前言:部分参考自https://www.bilibili.com/video/BV1NE411Q7Nx?p=20
文章目录
ResultMap结果集映射
一、解决属性名和字段名不一致的问题
1、问题背景
解决属性名和字段名不一致的问题
user表
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 无法对应,从而问题产生
password 结果为null
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>
以上两种方法,都可以实现不同名字段的一一对应
3、ResultMap结果集映射
- resultMap 元素是 MyBatis 中最重要最强大的元素。
- ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了
- ResultMap 的优秀之处——你完全可以不用显式地配置它们
resultMap 元素有很多子元素和一个值得深入探讨的结构,称为高级结果映射,具体可参考官方文档
二、解决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();
}
之所以Student对象的teacher属性为null,是因为只有查询出的s.id,s.name属性可以一一映射到Student对象中,而t.name属性无法找到其映射,且Student对象teacher属性未被赋值,因此为null
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>
便可成功查出
附加:表中数据如下图
方法二:按照结果嵌套处理(推荐)
更改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>
【一对多的情况】
例子:一位老师对应多位学生
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();
}