0
点赞
收藏
分享

微信扫一扫

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】


前言:部分参考自https://www.bilibili.com/video/BV1NE411Q7Nx?p=20

文章目录

  • ​​ResultMap结果集映射​​
  • ​​一、解决属性名和字段名不一致的问题​​
  • ​​1、问题背景​​
  • ​​2、解决方法​​
  • ​​方法1:AS指定别名​​
  • ​​方法2(推荐):ResultMap结果集映射​​
  • ​​3、ResultMap结果集映射​​
  • ​​二、解决JavaBean中的复杂属性​​
  • ​​【多对一的情况】​​
  • ​​1、问题背景​​
  • ​​2、解决方法​​
  • ​​方法一:按照查询嵌套处理​​
  • ​​方法二:按照结果嵌套处理(推荐)​​
  • ​​【一对多的情况】​​
  • ​​1、问题背景​​
  • ​​2、解决方法​​
  • ​​方法:按照结果嵌套处理​​

ResultMap结果集映射

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

1、问题背景

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

user表

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_mysql


User实体类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
// private String pwd;
//注:此处与数据库中字段pwd不同名,字段不一致
private String password;
}

将User实体类中的 pwd 改成 password,使其与数据库中字段 pwd 无法对应,从而问题产生

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_数据库_02


MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_java_03


password 结果为null

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_java_04

2、解决方法

方法1:AS指定别名

为列名指定别名 , 别名和java实体类的属性名一致

<select id="selectUserById" resultType="User">
SELECT id, name, pwd AS password FROM user WHERE id = #{id}
</select>

方法2(推荐):ResultMap结果集映射

ResultMap结果集映射

<!--结果集映射-->
<resultMap id="UserMap" type="com.zlc.pojo.User">
<!--column:数据库中的字段,property:实体类中的属性-->
<result column="pwd" property="password"/>
</resultMap>

<!--id:接口方法的名字-->
<select id="getUserById" parameterType="int" resultMap="UserMap">
SELECT * FROM user WHERE id = #{id};
</select>

以上两种方法,都可以实现不同名字段的一一对应

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_mysql_05

3、ResultMap结果集映射

  • resultMap 元素是 MyBatis 中最重要最强大的元素。
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了
  • ResultMap 的优秀之处——你完全可以不用显式地配置它们

resultMap 元素有很多子元素和一个值得深入探讨的结构,称为高级结果映射,具体可参考​​官方文档​​

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_sql_06

二、解决JavaBean中的复杂属性

【多对一的情况】

例子:多位学生对应一位老师

Student类中关键语句:private Teacher teacher;

1、问题背景

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
private int id;
private String name;
private Teacher teacher;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Teacher {
private int id;
private String name;
}

StudentMapper接口

public interface StudentMapper {
public List<Student> getAllStudents();
}

StudentMapper.xml

<select id="getAllStudents" resultType="student">
SELECT s.id, s.name, t.name
FROM student s, teacher t
WHERE s.tid = t.id
</select>

测试类

@Test
public void testGetAllStudents() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.getAllStudents();
for (Student student : students) {
System.out.println(student);
}
System.out.println();
sqlSession.close();
}

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_sql_07


之所以Student对象的teacher属性为null,是因为只有查询出的s.id,s.name属性可以一一映射到Student对象中,而t.name属性无法找到其映射,且Student对象teacher属性未被赋值,因此为null

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_mybatis_08

2、解决方法

方法一:按照查询嵌套处理

思路:

  • 1、查询所有学生的信息
  • 2、根据查询出的学生的tid,再查出对应老师

首先更改StudentMapper.xml,新建一个ResultMap结果集映射,实现Student对象中复杂属性teacher的绑定,并将此ResultMap写入查询学生表的select的属性中,以替代之前的resultType = student

<!--
1、查询所有学生的信息
2、根据查询出的学生的tid,再查出对应老师
-->
<resultMap id="StudentTeacher" type="student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性,单独处理
对象:association
集合:collection
-->
<association property="teacher" column="tid" javaType="teacher" select="getTeacherById"/>
</resultMap>

<select id="getAllStudents" resultMap="StudentTeacher">
SELECT * FROM student
</select>

<select id="getTeacherById" resultType="teacher">
SELECT * FROM teacher WHERE id = #{id}
</select>

便可成功查出

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_sql_09


附加:表中数据如下图

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_sql_10

方法二:按照结果嵌套处理(推荐)

更改StudentMapper.xml

<select id="getAllStudents2" resultMap="StudentTeacher2">
SELECT s.id sid, s.name sname, t.name tname, t.id tid
FROM student s, teacher t
WHERE s.tid = t.id
</select>

<resultMap id="StudentTeacher2" type="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_mybatis_11

【一对多的情况】

例子:一位老师对应多位学生

Teacher类中关键语句:private List<Student> students;

1、问题背景

和上述几个问题的情况一样,也是null问题,不再赘述,之间上所有关键代码

2、解决方法

方法:按照结果嵌套处理

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
private int id;
private String name;
private int tid;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Teacher {
private int id;
private String name;
//一个老师对应多个学生
private List<Student> students;
}

TeacherMapper.xml

<select id="getTeacherById" resultMap="TeacherStudent">
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 = #{tid}
</select>

<resultMap id="TeacherStudent" type="teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!--
javaType:指定属性类型
ofType:集合中的泛型信息
-->
<collection property="students" ofType="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
</collection>
</resultMap>

测试类

@Test
public void getTeacherById() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacherById(1);
System.out.println(teacher);
System.out.println();
sqlSession.close();
}

MyBatis知识汇总(第八篇)ResultMap结果集映射+复杂属性映射【多对一的情况】【一对多的情况】_mybatis_12


举报

相关推荐

0 条评论