(十一)延迟加载
目录
延迟加载的含义
比如现在我们有一个网页,在网页上显示 订单信息
,然后鼠标某一个 订单信息
,则会显示产生这个订单的 用户信息
;
我们可以看出,当用户不点击具体的 订单信息
的时候,我们是不需要去显示具体的 用户信息
的 ;也就是说,开始我们只需要查询 订单表
,即可完成需求,等到需要显示用户信息了,再去查询 用户表
,这种 按需加载
,也就是 延迟加载
;
延迟加载的意义
我们都知道数据库在进行 关联查询
的时候,关联的表越多,查询速度越慢 ;
比如上面的情况,不使用延迟加载,则开始就是有关联查询,查询出所有信息;
而我们使用延迟加载,就会 按需加载
,首先只会去查询需要的表,比 关联查询
,将要快许多。
并且有些时候,并不是每个定单用户都会点击查看的,因此实质,也不需要查询所有的信息出来,按需查询
是个极好的选择 ;
因此,延迟加载
,会大大的提高数据库的性能 ;
mybatis支持延迟加载
使用 resultMap
的 association
、collection
标签都支持实现延迟加载 ;
使用方法
需求:查询订单及其关联的用户信息 ;
由于我们使用 懒惰加载
,因此,我们需要配置 2 个 statement
对象,一个用于 直接查询
,一个 用于 按需查询
;
-
配置
直接查询
的sql
查询订单表
<select id="findOrdersAndUserLazyLoading" resultMap="findOrdersAndUserLazyLoadingMap" > SELECT * FROM `order` </select>
-
配置
懒加载
使用的sql
查询用户表
<select id="findUserById" parameterType="int" resultType="xin.ijava.pojo.User"> select * from User where id = #{id} </select>
-
创建
resultMap
实现懒加载使用
select
、column
实现懒加载 ;<!--懒加载--> <resultMap id="findOrdersAndUserLazyLoadingMap" type="xin.ijava.pojo.OrdersUsers"> <id column="order_id" property="order_id"/> <result column="user_id" property="user_id"/> <result column="create_time" property="createTime"/> <!--懒加载用户信息--> <!--select : 指定懒加载执行的 sql --> <!--column :指定懒加载,关联查询的列 --> <association property="user" javaType="xin.ijava.pojo.User" select="xin.ijava.dao.UserMapper.findUserById" column="user_id"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> </resultMap>
-
编写接口
public List<OrdersUsers> findOrdersAndUserLazyLoading() throws Exception ;
-
测试代码
@Test public void test3() throws Exception { SqlSession sqlSession = factory.openSession(); // 获取代理对象,参数写上类的全路径名 UserCustomerMapper userMapper = sqlSession.getMapper(xin.ijava.dao.UserCustomerMapper.class); // 利用代理对象,操作 List<OrdersUsers> users = userMapper.findOrdersAndUserLazyLoading(); for (OrdersUsers ordersUsers : users) { System.out.println(ordersUsers); } // System.out.println(users); }
-
观察
log
[service] 2018-09-11 15:35:37,895 - xin.ijava.dao.UserCustomerMapper.findOrdersAndUserLazyLoading -8274 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrdersAndUserLazyLoading - ==> Preparing: SELECT * FROM `order` [service] 2018-09-11 15:35:38,797 - xin.ijava.dao.UserCustomerMapper.findOrdersAndUserLazyLoading -9176 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrdersAndUserLazyLoading - ==> Parameters: [service] 2018-09-11 15:35:39,917 - xin.ijava.dao.UserCustomerMapper.findOrdersAndUserLazyLoading -10296 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrdersAndUserLazyLoading - <== Total: 4 [service] 2018-09-11 15:36:06,088 - xin.ijava.dao.UserMapper.findUserById -36467 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Preparing: select * from User where id = ? [service] 2018-09-11 15:36:06,089 - xin.ijava.dao.UserMapper.findUserById -36468 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Parameters: 5(Integer) [service] 2018-09-11 15:36:06,098 - xin.ijava.dao.UserMapper.findUserById -36477 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - <== Total: 1 xin.ijava.pojo.OrdersUsers_$$_jvstbd2_0@692ec5f8 [service] 2018-09-11 15:36:15,714 - xin.ijava.dao.UserMapper.findUserById -46093 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Preparing: select * from User where id = ? [service] 2018-09-11 15:36:15,716 - xin.ijava.dao.UserMapper.findUserById -46095 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Parameters: 1(Integer) [service] 2018-09-11 15:36:15,719 - xin.ijava.dao.UserMapper.findUserById -46098 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - <== Total: 1 xin.ijava.pojo.OrdersUsers_$$_jvstbd2_0@63c1edd9 [service] 2018-09-11 15:36:20,415 - xin.ijava.dao.UserMapper.findUserById -50794 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Preparing: select * from User where id = ? [service] 2018-09-11 15:36:20,416 - xin.ijava.dao.UserMapper.findUserById -50795 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Parameters: 4(Integer) [service] 2018-09-11 15:36:20,419 - xin.ijava.dao.UserMapper.findUserById -50798 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - <== Total: 1 xin.ijava.pojo.OrdersUsers_$$_jvstbd2_0@7608443a xin.ijava.pojo.OrdersUsers_$$_jvstbd2_0@29efafae
我在遍历的时候,下了断点 ;可以看见,在我们访问用户信息之前,是没有执行查询
user
表的;在遍历的时候,才开始需要谁,就去查找谁 ;并且我们发现
4
个订单,只执行了3
次sql
,这是因为其中一级缓存
的原因 ;
假如 mybatis
不支持延迟加载
假如mybatis
不支持 延迟加载
,我们也不要慌(问题很大,慌也没有用),它不支持,离开它,我们还不能做事了啊。想一下,我们还有许多其他持久层的框架使用啊 ;
说正事,假如 mybatis
不支持 延迟加载
,我们也是可以手动实现的;
我们定义 2
个方法,分别用于 直接查询
、按需查询
;在页面上先使用 直接查询 查询我们需要的订单信息,然后如果需要继续查询关联的用户信息,则在 services
层 拦截一下,传入产生订单的用户 id
,然后调用 按需查询
方法 ;
一样可以完成 延迟加载
;
上一篇: 对象关系行为模式之延迟加载
下一篇: 114. 二叉树展开为链表