Mybatis 结果映射

本文最后更新于:2024年9月8日 晚上

Mybatis 结果映射

resultMap

  • ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句需要描述它们的关系。

实例

  1. 返回值类型为resultMap
1
2
3
<select id="selectUserById" resultMap="UserMap">
select id , name , pwd from user where id = #{id}
</select>
  1. 编写resultMap,实现手动映射。
1
2
3
4
5
6
7
<resultMap id="UserMap" type="User">
<!-- id为主键 -->
<id column="id" property="id"/>
<!-- column是数据库表的列名, property是对应实体类的属性名 -->
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>

association

  • 关联属性,指定属性为实体类。
    • property:属性名。
    • javaType:属性类型。
    • column:指定传递参数的字段。
      • column="{key=value,key=value}"其实就是键值对的形式, key是传给下个sql的取值名称, value是片段一中sql查询的字段名。
      • 当只有一个key时,可以省略value

实例

  • 获取所有学生及对应老师的信息。
  • 思路:获取所有学生的信息根据获取的学生信息的tid获取该老师的信息。
    • 做一个结果集映射:StudentTeacher
    • StudentTeacher结果集的类型为 Student
    • 学生中老师的属性为teacher,对应数据库中为tid,多个学生关联一个老师。

实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
@Data //GET,SET,ToString,有参,无参构造。
public class Teacher {
private int id;
private String name;
}

@Data
public class Student {
private int id;
private String name;
// 多个学生可以是同一个老师,即多对一。
private Teacher teacher;
}

按查询嵌套处理

  • 编写对应的Mapper文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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="com.example.mapper.StudentMapper">

<select id="getStudents" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="teacher">
select * from teacher where id = #{tid}
</select>

</mapper>
  • 测试。
1
2
3
4
5
6
7
8
9
10
11
@Test
public void testGetStudents(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);

List<Student> students = mapper.getStudents();

for (Student student : students){
System.out.println("学生名:"+ student.getName() +"\t老师:"+student.getTeacher().getName());
}
}

按结果嵌套处理

  • 直接查询出结果,进行结果集的映射。
  • 编写对应的Mapper文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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="Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--关联对象property 关联对象在Student实体类中的属性-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
  • 测试。
1
2
3
4
5
6
7
8
9
10
11
@Test
public void testGetStudents2(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);

List<Student> students = mapper.getStudents2();

for (Student student : students){
System.out.println("学生名:"+ student.getName() +"\t老师:"+student.getTeacher().getName());
}
}

小结

  • 按照查询进行嵌套处理就像SQL中的子查询。
  • 按照结果进行嵌套处理就像SQL中的联表查询。

collection

  • 集合属性,指定属性为集合。
  • JavaType和ofType都是用来指定对象类型。
    • JavaType是用来指定entity中属性的类型。
    • ofType指定的是映射到list集合属性中entity的类型。
  • column:指定传递参数的字段。
    • column="{key=value,key=value}"其实就是键值对的形式, key是传给下个sql的取值名称, value是片段一中sql查询的字段名。
    • 当只有一个key时,可以省略value

实例

  • 获取所有学生及对应老师的信息。
  • 一个老师拥有多个学生。
  • 如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)

实体类编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Data
public class Student {
private int id;
private String name;
private int tid;
}

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

按查询嵌套处理

  • 编写接口对应的Mapper配置文件。
1
2
3
4
5
6
7
8
9
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from student where tid = #{id}
</select>
  • 测试。
1
2
3
4
5
6
7
8
@Test
public void testGetTeacher2(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}

按结果嵌套处理

  • 从学生表和老师表中查出学生id,学生姓名,老师姓名,对查询出来的操作做结果集映射。
  • 编写对应的Mapper文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<mapper namespace="com.example.mapper.TeacherMapper">
<select id="getTeacher" 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=#{id}
</select>

<resultMap id="TeacherStudent" type="Teacher">
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
</collection>
</resultMap>
</mapper>
  • 测试。
1
2
3
4
5
6
7
8
@Test
public void testGetTeacher(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!