[置顶] 【Mybatis】深入浅出Mybatis(十四)——延迟加载
2018-03-08 16:38
302 查看
一、前言
在前面的博客中,小编向大家介绍了级联查询,针对不同的类型(一对一,一对多)进行了不同的选择:一对一的时候,我们可以选择resultType或resultMap,resultType要有一个和查询出来的字段对应的Model,而resultMap需要我们写一个resultMap,使用association连接两个表。
一对多的时候,我们使用resultMap比较方便,使用collection来连接两个表。
当然,这里就有了一个问题,我们可不可以在用到的时候,再去查呢,做一个延迟加载?
二、延迟加载
延迟加载(Lazy load)是Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓的延迟加载就是当在真正需要的时候,才真正执行数据加载。可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。
三、Mybatis延迟加载实现
resultMap的两种方式级联查询方式,association和collection具有延迟加载的功能,他们的实现反射是一样的,这里小编就以association举例实践一下。3.1 步骤
1 配置开启延迟加载2 查询主干sql,主要是单表的,也可以是关联查询的。
3 按照需要加载关联查询的信息
3.2 实现
需求:一个订单对应一个用户,查询订单的时候顺便把用户信息查出来配置开启延迟加载:在mybatis的配置文件SqlMapConfig.xml中setting配置
<settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
参数说明:
lazyLoadingEnable :全局设置是否开启懒加载,默认为false。
aggressiveLazyLoading:侵略性 lazy loading 开关, 默认为true。这个属性比较搞笑,如果为true则当你访问任何一个属性都会加载所有的其他lazy load属性,即使你根本没有调用哪个lazy load属性,说白了就是aggressiveLazyLoading=true,则lazy load等于没用,所以要使用lazy load还是将其设为false
在上一篇博客中,小编用resultType和resultMap同上实现了这个功能,下面小编就对resultMap进行修改 ,实现延迟加载。
OrdersMapper.xml:
变化说明:这里订单和用户是一对一的,所以使用了assocation。这里面的一些属性,在前面介绍过了。这里重点介绍一下,懒加载的属性。
<!-- 延迟加载的resultMap --> <resultMap id="OrderMap" type="com.dmsd.pojo.Orders"> <!--对订单信息进行映射配置 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 实现对用户信息进行延迟加载 --> <!-- 实现对用户信息进行延迟加载 select:指定延迟加载需要执行的statement的id(是根据User的主键查询用户信息的statement) 要使用userMapper.xml中selectByPrimaryKey完成根据用户id(user_id)用户信息的查询,如果findUserById不在本mapper中需要前边加namespace column:订单信息中关联用户信息查询的列,是user_id --> <association property="user" javaType="com.dmsd.pojo.User" select="com.dmsd.dao.UserMapper.selectByPrimaryKey" column="user_id"> </association> </resultMap> <select id="queryOrderMap" resultMap="OrderMap"> SELECT * FROM orders </select>
运行测试:
@Test public void testqueryOrderMap(){ List<Orders> ordersList = orderService.queryOrderMap(); System.out.println("------------------------------------------------------"); System.out.println(ordersList); }
以debug方式运行:
当运行到
System.out.println("------------------------------------------------------");的时候,在控制台输出的sql语句只有
SELECT * FROM orders;这个时候,我们只是做了查询,没有真正用到其中的数据。
继续运行后,
System.out.println(ordersList);会真正的使用其中的数据,所以就进行了查询:
这就是延迟加载,在用的时候,才会去查。
四、使用懒加载可能遇到的问题
4.1 Cannot enable lazy loading because CGLIB is nott available .
原因:少cglib.jar,添加就可以了。
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>
五、resultType、resultMap、延迟加载使用场景总结
延迟加载:延迟加载实现的方法多种多样,在只查询单表就可以满足需求,为了提高数据库查询性能使用延迟加载,再查询关联信息。注意:mybatis提供的延迟加载的功能用于Service。
resultType:
作用:将查询结果按照sql列名和pojo属性名的一致性映射到pojo中。
场合:常见一些明细记录的展示,将关联信息全部展示到页面上时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo即可)
resultMap:使用association和collection完成一对一和一对多高级映射。
association:
作用:将关联查询信息映射到一个pojo类中。
场合:为了方便获取关联信息可以使用association将关联订单映射为pojo,比如:查询订单关联查询用户信息。
collection:
作用:将关联查询信息映射到一个list集合中。
场合:为了方便获取关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块和功能,可以使用collection将模块和功能列表映射到list中。
相关文章推荐
- Mybatis学习笔记(十四)【延迟加载】
- 深入浅出Mybatis(九)延迟加载和缓存
- MyBatis 延迟加载,一级缓存(sqlsession级别)、二级缓存(mapper级别)设置
- mybatis入门基础(七)----延迟加载
- mybatis延迟加载
- Mybatis学习记录(七)----Mybatis延迟加载
- Mybatis深入了解(七)----延迟加载
- Mybatis深入了解(七)----延迟加载
- Mybatis的延迟加载
- Mybatis学习总结(八)——延迟加载
- MyBatis 延迟加载,一级缓存,二级缓存设置
- MyBatis 延迟加载,一级缓存,二级缓存设置
- 配置mybatis的缓存,延迟加载等等一系列属性
- [置顶] 【Mybatis】深入浅出Mybatis(七)——别名使用
- [置顶] 【Mybatis】深入浅出Mybatis(十一)——Mybatis和Spring整合
- MyBatis 延迟加载,一级缓存,二级缓存设置
- MyBatis入门【十一】resultMap小结及延迟加载
- mybatis的延迟加载与代码生成工具
- 有趣的MyBatis——延迟加载