天天看点

mybatis入门(四)| ResultMap(结果集映射)ResultMap(结果集映射)

目录

  • ResultMap(结果集映射)
    • 1 解决数据库与实体类属性名不一致问题
    • 2 解决多对一结果集映射(association关联属性)
      • 2.1 按查询嵌套处理
      • 2.2 按结果嵌套处理。
    • 3解决一对多结果集映射(collection集合)
      • 3.1 按查询嵌套处理。
      • 3.2 按结果嵌套处理

ResultMap(结果集映射)

  • 为了解决数据映射问题而生

1 解决数据库与实体类属性名不一致问题

解决的问题:属性名和字段名不一致

因为各种原因,数据库的属性字段无法和实体类的属性字段一一对应。

举例:

现在数据库表属性为:

mybatis入门(四)| ResultMap(结果集映射)ResultMap(结果集映射)

实体类属性值为:

mybatis入门(四)| ResultMap(结果集映射)ResultMap(结果集映射)

查询语句:

<select id="selectUserById" parameterType="int" resultType="com.lyj.entity.UserInf">
	select id,name,pwd from user where id = #{id}
</select>
           

这样查询,因为pwd在实体类中并不存在,在注入值时无法注入。出现password属性为空的情况。

解决方案

  1. 使用别名(可简写 pwd password)
    <select id="selectUserById" parameterType="int" resultType="com.lyj.entity.UserInf">
    	select id,name,pwd as password from user where id = #{id}
    </select>
               
  2. 使用结果集映射->ResultMap 【推荐】
<resultMap id="UserMap" type="User">
        <!-- id为主键 -->
        <id column="id" property="id"/>
        <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
</resultMap>
<select id="selectUserById" parameterType="int" resultMap="UserMap">
    select id,name,pwd from user where id = #{id}
</select>
           

2 解决多对一结果集映射(association关联属性)

多对一理解:

  • 多个学生对应一个老师。
  • 数据库概念理解:学生拥有一个tid与教师id对应。
  • 实体类概念理解:学生拥有一个教师对象。

2.1 按查询嵌套处理

  1. 实体类student和teacher
    public class Student {
        private int id;
        private String name;
        private Teacher teacher;
    }
               
    public class Teacher {
        private int id;
        private String name;
    }
               
  2. StudentMapper增加接口
    //查询所有学生
    public List<Student> queryAllStudents();
               
  3. StudentMapper.xml增加对应方法(对于对象属性teacher采用关联属性)
    <mapper namespace="com.lyj.mapper.StudentMapper">
        <select id="queryAllStudents" resultMap="StudentTeacher">
            select id, name, tid from student
        </select>
        <resultMap id="StudentTeacher" type="com.lyj.entity.Student">
            <!--association关联属性 property属性名 javaType属性类型 column是将查询到的tid赋值给id并传递下去 select是对应的id-->
            <association property="teacher" column="{id=tid}" javaType="com.lyj.entity.Teacher" select="getTeacher"/>
        </resultMap>
        <!-- 这里传递过来的id,只有一个属性的时候,下面可以写任何值 association中column多参数配置: column="{key=value,key=value}" 其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的 字段名。-->
        <select id="getTeacher" resultType="com.lyj.entity.Teacher">
            select id, name from teacher where id = #{id}
        </select>
    </mapper>
               
  4. 测试(对于对象属性teacher的属性采用关联属性)
    @Test
        public void testGetStudents(){
            SqlSession session = SqlSessionUtil.getSession();
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            List<Student> students = mapper.queryAllStudents();
            for (Student student : students){
                System.out.println( "学生名:"+ student.getName() +"\t老师:"+student.getTeacher().getName());
            }
        }
               

2.2 按结果嵌套处理。

<!-- 按查询结果嵌套处理 思路:1. 直接查询出结果,进行结果集的映射 -->
<select id="getStudents2" resultMap="StudentTeacher2" >
select s.id sid, s.name sname , t.name tname from student s,teacher t where s.tid = t.id
</select>
<resultMap id="StudentTeacher2" type="com.lyj.entity.Student">
    <id property="id" column="sid"/>
    <result property="name" column="sname"/>
    <!--关联对象property 关联对象在Student实体类中的属性-->
    <association property="teacher" javaType="com.lyj.entity.Teacher">
        <id property="id" column="sid"/>
        <result property="name" column="tname"/>
    </association>
</resultMap>
           

3解决一对多结果集映射(collection集合)

一对多理解:

  • 一个老师有多个学生
  • 数据库概念理解:教师拥有一个id与学生tid对应。
  • 实体类概念理解:教师拥有一个学生对象List集合。

3.1 按查询嵌套处理。

  1. 实体类Student和Teacher
    public class Student {
        private int id;
        private String name;
    }
               
    public class Teacher {
        private int id;
        private String name;
        private List<Student> students;
    }
               
  2. TeacherMapper增加方法
  3. TeacherMapper.xml增加实现
    <select id="getTeacher" resultMap="TeacherStudent">
        select id, name from teacher where id = #{id}
    </select>
    <resultMap id="TeacherStudent" type="com.lyj.entity.Teacher">
        <!--column是一对多的外键 , 写的是一的主键的列名-->
        <collection property="students" javaType="ArrayList" ofType="Student" column="{id=id}" select="getStudentByTeacherId"/>
    </resultMap>
    <select id="getStudentByTeacherId" resultType="com.lyj.entity.Student">
        select id, name, tid from student where tid = #{id}
    </select>
               
  4. 测试
    @Test
        public void testGetTeacher(){
            SqlSession session = SqlSessionUtil.getSession();
            TeacherMapper mapper = session.getMapper(TeacherMapper.class);
            Teacher teacher = mapper.getTeacher(1);
            System.out.println(teacher.getName());
            System.out.println(teacher.getStudents());
        }
               

3.2 按结果嵌套处理

<select id="getTeacher2" resultMap="TeacherStudent2">
    select s.id sid, s.name sname , t.name tname, t.id tid from student s,teacher t where s.tid = t.id and t.id=#{id}
</select>
<resultMap id="TeacherStudent2" type="com.lyj.entity.Teacher">
    <id property="id" column="tid"/>
    <result property="name" column="tname"/>
    <collection property="students" ofType="com.lyj.entity.Student">
        <result property="id" column="sid" />
        <result property="name" column="sname" />
        <result property="tid" column="tid" />
    </collection>
</resultMap>