MyBatis -- 结果集映射

结果集映射,顾名思义跟结果集有关。无非就是把SQL的查询结果映射到JavaBean的字段上。

一。字段映射
比如有张数据表结构如下:
MyBatis -- 结果集映射_第1张图片
在后台的JavaBean中,如果遵守规范的话,属性名和列名一致,那么我们就不需要手动做字段映射,MyBatis会自动帮我们把值填充到Bean中。但现在情况不一样,Bean的属性名和数据库列名对应不上。
import java.util.ArrayList;

import java.util.List;

public class Grade {

    private String gradeId;        // 班级ID
    private String gName;        // 班级名
    private List stuList = new ArrayList(); // 班级中的学生

    public String getGradeId() {
            return gradeId;
    }


    public void setGradeId(String gradeId) {
            this.gradeId = gradeId;
    }


    public String getgName() {
            return gName;
    }


    public void setgName(String gName) {
            this.gName = gName;
    }


    public List getStuList() {
            return stuList;
    }


    public void setStuList(List stuList) {
            this.stuList = stuList;
    }

    @Override
    public String toString() {
            return "Grade [gradeId=" + gradeId + ", gName=" + gName + ", stuList="
                            + stuList + "]";
    }
}
gradeId和GID明显对应不上,但是修改列或者属性名是不可取的,原因不多说。我们可以通过MyBatis的字段映射在不修改代码的情况下完成这个需求,给它俩建立一种映射关系:
字段映射,当数据库的列名和类的属性名不一致时,需要通过建立映射关系使得它俩对应上。

返回的结果都是grade(自己取的typeAliases),只是多了一层映射关系。


        
        
 grade。多个学生对应一个grade,一个学生只能有一个grade。 
   

在设计Bean的时候,应该是这样的:
public class Student {


    private String sId;
    private String sName;
    private Grade grade;


    public String getsId() {
            return sId;
    }


    public void setsId(String sId) {
            this.sId = sId;
    }


    public String getsName() {
            return sName;
    }


    public void setsName(String sName) {
            this.sName = sName;
    }

    public Grade getGrade() {
            return grade;
    }


    public void setGrade(Grade grade) {

            this.grade = grade;

    }


    @Override
    public String toString() {
            return "Student [sId=" + sId + ", sName=" + sName + ", grade=" + grade
                            + "]";
    }

}
包含一个grade属性,在查询到学生信息的同时把对应的班级查出来并填充进去。当然用Java代码编写逻辑也是完全能够实现的,但是有了MyBatis的结果集映射,我们并不需要编写这样的逻辑。确定好是一对多关系后,在映射文件中声明映射关系。下面就把这个例子的代码都贴上来吧:
MyBatis -- 结果集映射_第3张图片
Student映射接口:
import java.util.List;
import cn.et.lesson03.entity.Student;
public interface StudentMapper {
    

    

            

    

/* 根据ID查询学生 */ public Student queryStuById(String sId); /*根据班级ID查询学生*/ public List queryStusByGId(String gId);}
现在要调用 queryStuById ,返回一个student的同时,把这个student的grade属性填充进去,也就是说还需要一个 select * from grade where gid = x 这么一条SQL语句,定义在grade类对应的映射文件中:

    
然后在Student类的映射文件中建立映射关系:
    

    

            

    
 type = 查询返回结果
 id = 映射命名
association = 声明是多对一映射。
property = "grade" 需要填充的属性
column = "gid" 外键列
select 获取对应的grade数据行的 SQL语句,上上边那个,语法格式:命名空间.声明。

 映射接口中方法的SQL语句:
    
 测试方法:
@Test

    public void mappingGrade() throws IOException{

            SqlSession session = getSession();
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            Student student = mapper.queryStuById("1");
            System.out.println(student.getGrade());
}
结果:
MyBatis -- 结果集映射_第4张图片
流程:
    调用方法 --> 执行接口映射方法之前先执行resultMap --> 
    通过association中的column外键,执行 association 对应的SQL语句获取结果集,填充到
    property --> resultMap结束 --> 执行方法对应的SQL语句返回最终结果。

三。一对多映射(one to  many )

一对多映射很简单,一个班级对应多个学生,查询一个班级的同时获取班级中的所有学生,填充到stuList属性中:
MyBatis -- 结果集映射_第5张图片
把上面的例子反过来想就OK了。班级和学生在数据库中的关系是主外键关联,通过grade表的主键到student表查询,需要一个这个的语句:select * from student where GID = #{gid}。

这个语句在Student的映射文件中定义:
    

然后在Grade的映射文件中,定义结果集映射:
    

            

    
一对多关系用collection表示。
property = 要填充的属性
javaType = 该属性的数据类型
column = 主键,studen表的外键
select = student映射文件中的语句:  select * from student where GID = #{gid}


测试方法:
    @Testpublic void queryStu() throws IOException {

            SqlSession session = getSession();

            GradeMapper mapper = session.getMapper(GradeMapper.class);

            Grade grade = mapper.queryGradeById("1");

            

            List list = grade.getStuList();

            for (Student student : list) {

                    System.out.println(student.getsId() + "---" + student.getsName());

            }

    }

运行结果:
MyBatis -- 结果集映射_第6张图片



四。基于注解实现的结果集映射

字段映射:
    @Results({

    @Result(column="SID" , property = "stuId" , id = true)})

    @Select("select * from student where sid = #{sId}")

    public Student queryStuById(String sId);
多对一映射:
    @Results({

                    @Result(column = "SID", property = "stuId", id = true),

                    @Result(property = "grade", column = "GID", 

                    one = @One(select = "cn.et.lesson03.anno.GradeMapper.queryGradeById")) })

    @Select("select * from student where sid = #{sId}")

    public Student queryStuById(@Param("sId") String sId);
one表示多对一映射,多个学生属于一个grade,指向的方法也是一个grade:
 @Select("select * from grade where GID = #{0}")

    public Grade queryGradeById(String gId);
一对多映射:
指向的方法返回值是个list,所以还要在映射声明中指定一下javaType。
   
@Results({ 
    @Result(column = "GID", property = "stuList", javaType = ArrayList.class, 
     many = @Many(select = "cn.et.lesson03.anno.StudentMapper.queryStusByGId")) })

    @Select("select * from grade where GID = #{0}")

    public Grade queryGradeById(String gId);
一对多用many表示,因为查询结果是多条,指向方法:
    @Results({

    @Result(column = "SID" , property = "stuId")})

    @Select("select * from student where GID = #{param1}")

    public List queryStusByGId(String gId);






你可能感兴趣的:(MyBatis)