MyBatis(八):高级结果映射
环境准备
-
两个很简单的表,学生表记录了老师的pk

-
以下两个实体类,学生表记录了老师的pk---->Teacher的id是Student的tid。
//省略了无参、有参构造、get、set、重写toString public class Student { private int id; private String name; private int tid; } public class Teacher { private int id; private String name; }
1.假如需求是查出每个学生的信息和对应老师的名字,那么sql语句应该是
select s.*,t,name from student s,teacher t where s.tid = t.id
2.直接把结果放在map里面就可以了
-
Mapper.xml
<mapper namespace="com.rzp.dao.StudentMapper">
<select id="getByTeacher" resultType="map">
select s.*,t.name as tname from student s,teacher t where t.id = s.tid
</select>
</mapper>
- Mapper接口
public interface StudentMapper { List<HashMap> getByTeacher(); }
-
测试
@Test public void getByTeacher(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<HashMap> studentList = mapper.getByTeacher(); for (Map student : studentList) { //通过get方法可以直接取出来 System.out.print(student.get("id")+" "); System.out.print(student.get("name")+" "); System.out.print(student.get("tid")+" "); System.out.print(student.get("tname")+" "); System.out.println(); } sqlSession.close(); }

3.这个方式如果只是做一些统计应该会比较好用,但是如果像这种情况还不如直接在Student里加一个temp属性,这样还能直接把List的泛型设置为Student,操作Student时还更方便。
4.但是以下两种情况就不好用了:
-
如果实体类里的属性是另一个实体类对象时,比如Student里有一个Teacher对象的属性。
![]()
-
又或者是实体类里的属性是另一个实体类的容器,比如Teacher里有一个Student的List。

-
这时候就要使用结果集映射的对象(associtation )和集合(collection)属性。
-
我的理解其实就是把普通结果集映射的properties替换成associtation而已,感觉就像是在xml文件里也定义了一个实体类,其中对象要用associtation来定义。
associtation
一、按照查询嵌套处理
-
Student里给了Teacher对象
//省略了无参、有参构造、get、set、重写toString public class Student { private int id; private String name; private int tid; private Teacher teacher; } public class Teacher { private int id; private String name; }
-
Mapper接口
public interface StudentMapper { //获取所有学生的信息 List<Student> getAllStudent(); }
-
Mapper.xml
<mapper namespace="com.rzp.dao.StudentMapper">
<!--查询所有学生和对应的老师,思路:
1.查询所有的学生信息
2.根据查询出来的学生tid寻找对应的老师
-->
<select id="getAllStudent" resultMap="StudentMap">
select * from student
</select>
<resultMap id="StudentMap" type="Student">
<!--复杂的属性,需要单独处理 对象:associtation 集合:collection-->
<!--结果集映射中定义一个“对象”(associtation)属性
property---student中这个对象的名称
javaType---student中这个对象的类
select---获取这个对象的查询语句(方法)
column---使用这个语句要输入的参数,多个是column="{prop1=col1,prop2=col2}"
-->
<association property="teacher" column="tid" javaType="Teacher" select="getAllStudendTest"/>
</resultMap>
<select id="getAllStudendTest" resultType="Teacher">
select * from teacher where id = #{id}
</select>
</mapper>
-
测试方法
//查询所有学生 @Test public void getAllTeacher(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Student> studentList = mapper.getAllStudent(); for (Student student : studentList) { System.out.println(student); } sqlSession.close(); }
-
这个方式个人感觉不太符合一般联表查询的思维,更加像嵌套子查询。
二、按照结果嵌套处理
-
Mapper接口
//按照结果嵌套处理 List<Student> getAllStudent2();
-
Mapper.xml
<select id="getAllStudent2" resultMap="StudentMap2"> select s.id,s.name,s.tid,t.name tname from student s,teacher t where s.tid = t.id </select> <resultMap id="StudentMap2" type="Student"> <result property="id" column="id"/> <result property="name" column="name"/> <result property="tid" column="tid"/> <association property="teacher" javaType="Teacher"> <result property="name" column="tname"/> </association> </resultMap>
-
测试
//查询所有学生2 @Test public void getAllTeacher2(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Student> studentList = mapper.getAllStudent2(); for (Student student : studentList) { System.out.println(student); } sqlSession.close(); }

-
备注:测试结果之中,teacher对象的id是0,个人觉得这个很像一个有参构造器。

collection
三、按照结果嵌套处理
-
实体类
public class Student { private int id; private String name; private int tid; } public class Teacher { private int id; private String name; private List<Student> studentsList; }
-
Mapper.xml
<!--按结果嵌套查询-->
<select id="getTeacherById" resultMap="TeacherMap">
select s.*,t.name tname from student s,teacher t
where s.tid = t.id and t.id = #{tid}
</select>
<resultMap id="TeacherMap" type="Teacher">
<result property="name" column="tname"/>
<collection property="studentsList" ofType="Student" >
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
-
Mapper接口
Teacher getTeacherById(@Param("tid") int id);
-
测试
@Test public void test1(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = mapper.getTeacherById(1); System.out.println(teacher); sqlSession.close(); }

四、按查询嵌套处理
-
Mapper.xml
<!--按查询嵌套处理-->
<select id="getTeacherById2" resultMap="TeacherMap1">
select t.* from teacher t where t.id = #{id}
</select>
<resultMap id="TeacherMap1" type="Teacher">
<result property="id" column="id"/>
<!--ofType--泛型-->
<collection property="studentsList" javaType="ArrayList" ofType="Student" column="id" select="getStudent"/>
</resultMap>
<select id="getStudent" resultType="Student">
select * from student where tid = #{id}
</select>
-
Mapper接口
Teacher getTeacherById2(int id);
-
测试
@Test public void test2(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = mapper.getTeacherById2(1); System.out.println(teacher); sqlSession.close(); }

对比
-
按结果查询,sql复杂,查询次数少,xml结构简单。
-
按查询嵌套处理,sql简单,查询了多次,xml结构复杂。

浙公网安备 33010602011771号