Mybatis结果映射详细讲解

 

resultMap是mybatis中最复杂的元素之一,它描述如何从结果集中加载对象,主要作用是定义映射规则、级联的更新、定制类型转化器。

 

resultMap参数讲解

constructor:     用于配置构造器方法
id:                      将结果集标记为id,以方便全局调用
result:                配置POJO到数据库列名映射关系
association:      级联使用    代表多对一关系
collection:         级联使用    代表一对多关系
discriminator:   级联使用    鉴别器 根据实际选择实例,可以通过特定条件确定结果集

 

一、通过xml的方式实现结果映射

我们就以学生跟班级的关系来测试

学生表:

班级表:

1.创建一个学生实体类

package cn.et.demo03.xml.model;

public class Student {
    private String id;
    private String name;
    private Grade grade;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Grade getGrade() {
        return grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}

 2.创建一个班级类

package cn.et.demo03.xml.model;

import java.util.ArrayList;
import java.util.List;

public class Grade {
    private String id;
    private String name;
    private List<Student> list =new ArrayList<Student>();

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Student> getList() {
        return list;
    }

    public void setList(List<Student> list) {
        this.list = list;
    }
}

在后台的JavaBean中,如果遵守规范的话,属性名和列名一致,那么我们就不需要手动做字段映射,MyBatis会自动帮我们把值填充到Bean中。但现在情况不一样,Bean的属性名和数据库列名对应不上。所以我们需要自己去映射

 

用xml的方式实现多对一的例子

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.et.demo03.xml.mapper.StudentMapper">

    <!--
        结果集映射:
            数据库的列名和实体类的属性名 如果不一致  需要建立列名和属性名的映射关系
            结果集映射返回的结果是相同的 都是classes 只是多了一层关系
    -->
    <resultMap id="studentMap" type="cn.et.demo03.xml.model.Student">
        <id column="sid" property="name"></id>
        <result column="sname" property="name"></result>
        <association column="gid" property="grade" select="cn.et.demo03.xml.mapper.GradeMapper.gradeById"></association>
    </resultMap>
    <select id="ManyToOneById" resultMap="studentMap">
        select * from student where sid=#{id}
    </select>
</mapper>

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.et.demo03.xml.mapper.GradeMapper">
    <resultMap id="gradeMap" type="cn.et.demo03.xml.model.Grade">
        <id column="gid" property="id"></id>
        <result column="gname" property="name"></result>
    </resultMap>
    <select id="gradeById" resultMap="gradeMap">
        select * from grade where gid=#{id}
    </select>
</mapper>

id : 唯一标识,一般用来标识id

column:  用来标识数据库的字段名

property:  用来标识实体的字段名

association: 代表一对多的关系

selele: 用来标识sql语句所在的位置 

 

写一个测试类

package cn.et.demo03.xml.controller;

import cn.et.demo03.xml.mapper.GradeMapper;
import cn.et.demo03.xml.mapper.StudentMapper;
import cn.et.demo03.xml.model.Grade;
import cn.et.demo03.xml.model.Student;
import cn.et.tools.DBTools;

import java.io.IOException;

public class TestController {
    public static void main(String[] args) throws IOException {
//      一对多的例子
        Grade grade =OneToMany();
        System.out.println("班级名称:"+grade.getName());
        for (int i=0; i<grade.getList().size(); i++){
            System.out.println("学生姓名:"+grade.getList().get(i).getName());
        }

    }

    /**
     * 多对一的例子
     * @return
     * @throws IOException
     */
    public static Student ManyToOne() throws IOException {
        StudentMapper studentMapper = DBTools.getSession().getMapper(StudentMapper.class);
        Student student  =studentMapper.ManyToOneById("11");
        return student;
    }

}

结果:

 

用xml的方式实现一对多的例子

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.et.demo03.xml.mapper.GradeMapper">
    <!--一对多的实现例子-->
    <resultMap id="oneToManyMap" type="cn.et.demo03.xml.model.Grade">
        <id column="gid" property="id"></id>
        <result column="gname" property="name"></result>
        <collection property="list" column="gid" javaType="arraylist" select="cn.et.demo03.xml.mapper.StudentMapper.studentByGid"></collection>
    </resultMap>
    <select id="oneToMany" resultMap="oneToManyMap">
        select * from grade where gid=#{id}
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.et.demo03.xml.mapper.StudentMapper">
    <!--一对多的例子-->
    <resultMap id="studentByGidMap" type="cn.et.demo03.xml.model.Student">
        <id column="sid" property="name"></id>
        <result column="sname" property="name"></result>
    </resultMap>
    <select id="studentByGid" resultMap="studentByGidMap">
        select * from student where gid=#{id}
    </select>
</mapper>

collection:用来标识一对多的关系

javaType:用来指定返回的类型

select: 用来标识sql语句的路径

 

编写一个测试类

package cn.et.demo03.xml.controller;

import cn.et.demo03.xml.mapper.GradeMapper;
import cn.et.demo03.xml.mapper.StudentMapper;
import cn.et.demo03.xml.model.Grade;
import cn.et.demo03.xml.model.Student;
import cn.et.tools.DBTools;

import java.io.IOException;

public class TestController {
    public static void main(String[] args) throws IOException {
//      多对一的例子
        Student student = ManyToOne();
        System.out.println(student.getName()+"===="+student.getGrade().getName());
    }

    /**
     * 多对一的例子
     * @return
     * @throws IOException
     */
    public static Student ManyToOne() throws IOException {
        StudentMapper studentMapper = DBTools.getSession().getMapper(StudentMapper.class);
        Student student  =studentMapper.ManyToOneById("11");
        return student;
    }

}

效果:


鉴别器的讲解

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.et.demo03.xml.mapper.StudentMapper">
    <!--鉴别器 判断返回数据,如果sid等于11就使用test1的resultMap,如果sid等于22就使用test2的resultMap-->
    <resultMap id="test" type="cn.et.demo03.xml.model.Student">
        <discriminator column="sid" javaType="string">
            <case value="11" resultMap="test1"/>
            <case value="22" resultMap="test2"/>
        </discriminator>
    </resultMap>
    <resultMap id="test1" type="cn.et.demo03.xml.model.Student">
        <result property="id" column="sid"/>
    </resultMap>
    <resultMap id="test2" type="cn.et.demo03.xml.model.Student">
        <result property="name" column="sname"></result>
    </resultMap>
    <select id="test" resultMap="test">
        select * from student where sid= #{id}
    </select>

</mapper>

鉴别器就用来判断返回值的,如果判断返回值如果等于一就执行一的resultMap,等于二就执行二的resultMap

case:就相当于if里面的条件,如果返回的参数登录case里面的valse就执行满足的这个case的resultMap

 

 

二、通过注解的方式来实现结果集映射

首先还是一样创建班级、学生两个实体类

package cn.et.demo03.annotation.model;

import java.util.ArrayList;
import java.util.List;

public class Grade {
    private String id;
    private String name;
    private List<Student> list =new ArrayList<Student>();

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Student> getList() {
        return list;
    }

    public void setList(List<Student> list) {
        this.list = list;
    }
}
package cn.et.demo03.annotation.model;

public class Student {
    private String id;
    private String name;
    private Grade grade;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Grade getGrade() {
        return grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}

 

用注解的方式比用xml的方式要简洁,直接在接口文件里面写就可以了

演示一对多的关系

package cn.et.demo03.annotation.mapper;

import cn.et.demo03.annotation.model.Grade;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface GradeMapper {
    /**
     * 演示一对多的接口
     * @param id
     * @return
     */
    @Results({
        @Result(property = "id",column = "gid"),
        @Result(property = "name",column = "gname"),
        @Result(property = "list",column ="gid",javaType = List.class, many = @Many(select = "cn.et.demo03.annotation.mapper.StudentMapper.studentByGid"))
    })
    @Select("select * from grade where gid =#{id}")
    Grade oneToMany(@Param("id") String id);

}
package cn.et.demo03.annotation.mapper;

import cn.et.demo03.annotation.model.Student;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface StudentMapper {
    /**
     * 演示一对多
     * @param id
     * @return
     */
    @Results({
        @Result(property = "id",column = "sid"),
        @Result(property = "name",column = "sname")
    })
    @Select("select * from student where gid=#{id}")
    List<Student> studentByGid(@Param("id") String id);
}

参数跟刚刚xml的方式意思差不多,就是用法不一样而已,按照如上操作 然后自己写一个测试类就实现了一对多的结果映射了。

 

演示多对一

package cn.et.demo03.annotation.mapper;

import cn.et.demo03.annotation.model.Student;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface StudentMapper {

    /**
     * 演示多对一
     * @param id
     * @return
     */
    @Results({
        @Result(property = "id",column = "sid"),
        @Result(property = "name",column = "sname"),
        @Result(property = "grade",column = "gid",one = @One(select = "cn.et.demo03.annotation.mapper.GradeMapper.gradeById"))
    })
    @Select("select * from student where sid= #{id}")
    Student ManyToOneById(@Param("id") String id);
}
package cn.et.demo03.annotation.mapper;

import cn.et.demo03.annotation.model.Grade;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface GradeMapper {
    /**
     * 演示多对一的接口
     * 通过班级id查找班级详细信息
     * @param id
     * @return
     */
    @Results({
        @Result(property = "id",column = "gid"),
        @Result(property = "name",column = "gname")
    })
    @Select("select * from grade where gid= #{id}")
    Grade gradeById(@Param("id") String id);

}

参数跟刚刚xml的方式意思差不多,就是用法不一样而已,按照如上操作 然后自己写一个测试类就实现了一对多的结果映射了。

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值