resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
结果映射(resultMap)--主要使用这两个标签
- association – 一个复杂类型的关联;许多结果将包装成这种类型
- 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
- collection – 一个复杂类型的集合
- 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
数据库:
对于一对一或多对一的关系,使用association 来表示一个复杂类型的关联,如:
多个学生对应一个老师
@Data
public class Student {
private int id;
private String name;
private Teacher teacher;
}
@Data
public class Teacher {
private int id;
private String name;
}
学生中有一个老师的对象(teacher)------ 一(一个学生)中有一(一个老师对象)
StudentMapper 接口中创建方法
public interface StudentMapper {
//多对一处理---子查询方式
List<Student> getStudentList1();
//多对一处理---结果集映射
List<Student> getStudentList2();
}
Mapper配置文件
两种实现方式:
1、子查询方式,sql语句简单,但是配置属性较多
<select id="getStudentList1" resultMap="studentInfo">
<!-- id为接口中实现的方法名,resultMap为返回值类型,由于返回值包含一个Teacher对象,所以不能用resultType-->
select * from student;
</select>
<select id="getTeacher" resultType="Teacher">
<!--id为接下来resultMap引用,resultType为返回值类型-->
select * from teacher where id = #{tid};
</select>
<resultMap id="studentInfo" type="Student">
<!--id就是第一个查询标签中的resultMap的引用,type是实体类的全类名,可以配置简化-->
<association property="teacher" javaType="Teacher" select="getTeacher" column="tid"/>
<!--property对应学生类中的属性名-->
<!--javaType说明property中的值为一个Teacher对象-->
<!--select指向第二个查询标签-->
<!--column为select标签传参-->
</resultMap>
最后的column标签是以键值对的形式传参的
column="{key=value,key=value}"
当 column中的值只有一个时,即column="tid",在引用处名字不那么重要,因为他直接就把值取走了,并需要对比key,
所以 select * from teacher where id = #{tid},这里的tid写成id或者123,都能取到值。
2、结果集嵌套,sql相对复杂,但是配置属性没那么多
<select id="getStudentList2" resultMap="studentInfo2">
<!-- id为接口中实现的方法名,resultMap为返回值类型,由于返回值包含一个Teacher对象,所以不能用resultType-->
select s.id sid,s.name sname,t.id tid,t.name tname
from student s,teacher t
where s.tid=t.id;
</select>
<resultMap id="studentInfo2" type="Student">
<!--id就是查询标签中的resultMap的引用,type是实体类的全类名,可以配置简化-->
<result property="id" column="sid"/>
<!--property是实体类中的字段属性,column对应数据库查出来的属性,这里使用了别名,所以就用别名-->
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<!--property是实体类中的字段属性,复杂的属性,使用了javaType描述的是属性的类型,它是一个Teacher对象-->
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
一对多的处理只能使用collection ---一个复杂类型的集合
同样是学生与老师,站在老师的角度,一个老师有很多学生,所以实体类变成了这样
@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;
}
TeacherMapper 接口变成了这样
public interface TeacherMapper {
//子查询方式
List<Teacher> getTeacher1(@Param("tid")int tid);
//结果集映射
List<Teacher> getTeacher2(@Param("tid")int tid);
}
Mapper配置文件
方式一:
<!-- 嵌套子查询-->
<select id="getTeacher1" resultMap="teacher1">
select * from teacher;
</select>
<select id="getStudent" resultType="Student">
select * from student where tid = #{id};
</select>
<resultMap id="teacher1" type="Teacher">
<result property="id" column="id"/>
<collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudent"/>
<!--collection 表示这个类型是一个集合-->
<!--property 依旧是对应的实体类中的属性-->
<!--javaType 属性的类型,可以写成List,或者不写这个属性-->
<!--ofType 映射到集合中的实体类的全类名,就是list集合中是Student-->
<!--column 传参-->
<!--select 引用第二个select标签-->
<!---->
</resultMap>
方式二:清爽
<!-- 结果集映射-->
<!--必须要指定别名,查出来的数据列名有重复的情况下,映射会乱掉-->
<select id="getTeacher2" resultMap="teacher2">
select s.id sid,s.name sname,t.id tid,t.name tname
from student s,teacher t
where s.tid=t.id and t.id=#{tid}
</select>
<resultMap id="teacher2" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" javaType="ArrayList" ofType="Student">
<!--javaType 属性的类型,可以写成List,或者不写这个属性-->
<!--ofType 映射到集合中的实体类的全类名,就是list集合中是Student-->
<result property="id" column="sid"/>
<result property="name" column="sname"/>
</collection>
</resultMap>
感谢狂神说java
https://mp.weixin.qq.com/s/Dpt0LHTgx0kL7RCk8PZ2aw