Mybatis resultMap-结果集映射

柔光的暖阳◎ 2022-10-07 02:57 349阅读 0赞

在JDK1.8中,当实体类属性名与数据表中的字段不一致时,我们如何查询数据?

实体类字段如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNzc4MDAx_size_16_color_FFFFFF_t_70

数据库字段如下:

20210616070803506.png

查询结果:

20210616073553257.png

解决这种问题,也很简单,下边记录两种方式(也是官方提供的):

方式一、

sql查询语句,使用as别名

  1. <mapper namespace="com.lxc.dao.UserMapper">
  2. <select id="getUserList" resultType="com.lxc.domain.User">
  3. select id,
  4. name,
  5. password as psw
  6. from mybatis
  7. </select>
  8. </mapper>

方式二、

使用resultMap 结果映射

把之前的 resultType 更换为 resultMap,使用标签来创建一个结果集。通过id来关联。

type:结果集的类型;

标签;

property:实体类中的属性名;

column:数据表中的字段;

  1. <mapper namespace="com.lxc.dao.UserMapper">
  2. <resultMap id="UserMap" type="com.lxc.domain.User">
  3. <result property="psw" column="password" />
  4. </resultMap>
  5. <select id="getUserList" resultMap="UserMap">
  6. select * from mybatis
  7. </select>
  8. </mapper>

官方描述:

一、多对一

1、

resultMap 元素是 MyBatis 中最重要最强大的元素。

想下下边如何查询出Student 学生和老师的信息:

数据表 - 多个学生对应一个老师:
watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNzc4MDAx_size_16_color_FFFFFF_t_70 1

Teacher类

  1. package com.lxc.sprint_boot_01.domain;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class Teacher {
  9. private int id;
  10. private String name;
  11. }

Student类

  1. package com.lxc.sprint_boot_01.domain;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class Student {
  9. private String name;
  10. private int id;
  11. private Teacher teacher;
  12. }

Student实体类中有Teacher属性,这个属性对应就是教师对象,如果像之前一样查询,那么teacher属性查不出来,因为学生表中没有这样的字段,它是通过tid来关联 teacher表:

查询sql如下:

20210723125951335.png

结果:
20210723130021237.png

此时可以 resultMap 结果映射,下的 表签或 标签处理结果集,从而描述这种关系。

  1. <!--type结果集的类型-->
  2. <resultMap id="studentMap" type="com.lxc.sprint_boot_01.domain.Student">
  3. <id column="id" property="id" />
  4. <result column="name" property="name" />
  5. <!--
  6. (1)association描述一个对象,里边标签就是对象该有的字段;
  7. (2)property = "teacher" student种的teacher属性
  8. (3)javaType = "xx" 就是描述对象的类型
  9. -->
  10. <association property="teacher" javaType="com.lxc.sprint_boot_01.domain.Teacher">
  11. <id column="tids" property="id" />
  12. <result column="tname" property="name" />
  13. </association>
  14. </resultMap>
  15. <select id="getStudentMapper" resultMap="studentMap">
  16. select s.*, t.id as tids, t.name as tname from
  17. student s,
  18. teacher t
  19. where s.tid = t.id;
  20. </select>

此时查询出来的结果,符合预期:

20210723133904311.png

2、

  • association – 一个复杂类型的关联;许多结果将包装成这种类型

    • 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用。
  • collection – 一个复杂类型的集合

    • 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用。

如果关联的结果为一个对象,那么使用 association;如果关联的结果为一个列表则使用 collection。

二、一对多

实体类属性改下,教师类中增加学生,它是一个泛型集合,因为对应的是多个学生。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNzc4MDAx_size_16_color_FFFFFF_t_70 2

对应的mapper.xml文件:

对应的是结果集中的泛型列表;

property:为teacher类中的 studentList 字段;

ofType:这里与结果集是一个对象不同,当结果集其中的属性是一个泛型列表时,类型使用:ofType属性来表示。

  1. <resultMap id="teacherMap" type="com.lxc.sprint_boot_01.domain.Teacher">
  2. <id property="id" column="teachId" />
  3. <result property="name" column="tname" />
  4. <collection property="studentList" ofType="com.lxc.sprint_boot_01.domain.Student">
  5. <id column="sid" property="id" />
  6. <result column="sname" property="name" />
  7. </collection>
  8. </resultMap>
  9. <select id="getTeacherMapper" resultMap="teacherMap">
  10. select
  11. t.id teachId, t.`name` tname,
  12. s.id sid, s.name sname, s.tid stid
  13. from
  14. teacher t,
  15. student s
  16. where
  17. t.id = s.tid
  18. and
  19. #{id} = s.tid;
  20. </select>

查询结果为:

2021072314380583.png

例一:

有四个表,分别时教师表、学生表、课程表、学生与课程关联中间表

根据id查询教师及对应的学生和学生对应的课程信息。
最后结果如下:

一个教师对象,里边有studentList数组,对应多个学生,学生中有textClass对象,对应课程信息。
20210723155155591.png

这种看起来很复杂,如果明白了上边的多对一和一对多的使用,其实非常的简单,无非是使用resultMap 来描述一层层的关系。

下边是三个实体类:
Teacher

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class Teacher {
  5. private int id;
  6. private String name;
  7. private List<Student> studentList;
  8. }

Student

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class Student {
  5. private String name;
  6. private int id;
  7. private TextClass textClass;
  8. }

TextClass

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class TextClass {
  5. private int id;
  6. private String english;
  7. private String yuWen;
  8. private String mathMatic;
  9. }

对应的xml写法如下:
提示:有个技巧,如果多个表查询,关系比较乱的话,先在Navicat中,把sql语句写好,执行没问题了,在复制到xml中来;
其次,照着实体类来写他们之间的关系,比如下边:

查询的是教师,所以结果集是Teacher类型,字段就是Teacher中的字段,其中 studentList 字段是一个泛型集合,那么使用来描述,使用ofType来定义结果集类型,这里是Student类型,接着Student类中的字段,其中有textClass属性,这个属性对应的是TextClass类,是一个对象,那么使用来描述对象,类型一定是TextClass类型的,里边写对应的 TextClass类中的字段即可,整个下来,思路很清晰。

  1. <resultMap id="teacherMap" type="com.lxc.sprint_boot_01.domain.Teacher">
  2. <id property="id" column="id" />
  3. <result property="name" column="name" />
  4. <collection property="studentList" ofType="com.lxc.sprint_boot_01.domain.Student">
  5. <id column="sid" property="id" />
  6. <result column="sname" property="name" />
  7. <association property="textClass" javaType="com.lxc.sprint_boot_01.domain.TextClass">
  8. <id column="cid" property="id" />
  9. <result column="eng" property="english" javaType="String" />
  10. <result column="mathM" property="mathMatic" javaType="String" />
  11. <result column="yuWen" property="yuWen" javaType="String" />
  12. </association>
  13. </collection>
  14. </resultMap>
  15. <select id="getTeacherMapper" resultMap="teacherMap">
  16. select
  17. t.*,
  18. s.id sid, s.`name` sname,
  19. course.english eng, course.id cid, course.mathMatic mathM, course.yuWen yuWen
  20. from
  21. teacher t,
  22. student s,
  23. stuCourse sc,
  24. course
  25. where
  26. #{id} = s.tid
  27. and
  28. s.id = sc.stuId
  29. and
  30. sc.courseId = course.id;
  31. </select>

发表评论

表情:
评论列表 (有 0 条评论,349人围观)

还没有评论,来说两句吧...

相关阅读