前言
复杂查询需要用的内容:
- 结果集映射(特重要)
下面都需要用到结果集 - 联表查询方式
- 延迟加载
结果集(resultMap)
来看看官网的说法:
- resultMap 元素是 MyBatis 中最重要最强大的元素
- 它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。
- 实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。
- ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了
小结:
- 其他mybatis标签好不可以的说简单,几分钟就能过一遍,看过就会,但是resultMap却是一定要去学习的
- result涉及到结果映射
- 特别是在,多表(复杂)查询(一对多,多对一)是,它具有很强大的功能,能帮我们减少很多代码量
属性
还是从官网截图吧
注:
- id 一般用来标识主键
复杂查询
环境:
一个科目老师有多个学生,一个学生只能有一个相同科目老师
pojo
还是薄pojo贴出来好理解
public class Student {
private String name;
private Integer id;
//private Integer tid;
private Teacher teacher;
}
public class Teacher {
private String name;
private Integer tid;
private List<Student> students;
}
学生查询(多对一)
查询方式一(直接使用SQL语句)
<resultMap id="resultStudent" type="com.zzs.pojo.Student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
<result property="tid" column="tid"/>
</association>
</resultMap>
<select id="getAll" resultMap="resultStudent">
select s.sid sid,t.tid tid,s.name sname,t.name tname
from student s,teacher t
where s.sid = t.tid
</select>
查询方式二(使用association 的select)
<resultMap id="resultStudent2" type="Student">
<result property="id" column="sid"/>
<!-- select 可以在调用一个查询方法-->
<!--<association property="teacher" column="tid" select="TeacherGetAll" javaType="Teacher"/>-->
<!--上面方式是不好的,将有关于teacher的查询放入student中,造成混乱,我们可以直接使用teacherDao中的方法-->
<association property="teacher" column="tid" select="com.zzs.dao.TeacherDao.selectById" javaType="Teacher"/>
</resultMap>
<select id="getAll2" resultMap="resultStudent2">
select * from student;
</select>
<!--<select id="TeacherGetAll" resultType="Teacher">-->
<!--select * from teacher where tid = #{tid};-->
<!--</select>-->
老师查询(一对多)
<resultMap id="teacherResult" type="Teacher">
<result property="tid" column="tid"/>
<result property="name" column="tname"/>
<!--
ofType 是指集合中的泛型
collection 集合链表
-->
<collection property="students" javaType="List" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
</collection>
</resultMap>
<select id="getAll" resultMap="teacherResult">
select s.sid sid,t.tid tid,s.name sname,t.name tname
from student s,teacher t
where s.tid = t.tid
</select>
第二种略过
遗留问题
- 当是一对一,甚至是多对一查询的时候,使用第一种方式做好,sql也不复杂,查询效率也高
- 但是如果是一对多,甚至多对多查询的话,不sql语句会变得很复杂,一复杂阅读难度高了,发生的问题也多了
- 那么如果是一对多,甚至多对多查询的话,就使用第二种方法,但是使用第二种的话:
- 假设一个老师有100个学生,那么每次查询这个老师时都要加载100个学生的信息吗?这样会不会很浪费性能
- 解决方式:mybatis提出了延迟加载的概念
延迟加载
- 延迟加载:在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加载又叫按需查询(懒加载)
- 立即加载:不管用不用,只要一调用方法,马上发起查询
注意:
- 在上述第一种方式是没有延迟加载的概念,因为使用sql语句查询时将结果
一起查出来的 - 只有使用第二种方式:select时,才会有延迟加载
开启延迟加载:
- 需要在mybatis配置文件中设置
<settings>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
测试:
- 当没有开启延迟加载时
- 开启延迟加载时:
对比上面两幅图:
- 延迟架子只有在查询相关数据的时候才会执行sql语句