(十一)延迟加载
目录
延迟加载的含义
比如现在我们有一个网页,在网页上显示 订单信息,然后鼠标某一个 订单信息 ,则会显示产生这个订单的 用户信息 ;
我们可以看出,当用户不点击具体的 订单信息 的时候,我们是不需要去显示具体的 用户信息 的 ;也就是说,开始我们只需要查询 订单表,即可完成需求,等到需要显示用户信息了,再去查询 用户表 ,这种 按需加载,也就是 延迟加载;
延迟加载的意义
我们都知道数据库在进行 关联查询 的时候,关联的表越多,查询速度越慢 ;
比如上面的情况,不使用延迟加载,则开始就是有关联查询,查询出所有信息;
而我们使用延迟加载,就会 按需加载,首先只会去查询需要的表,比 关联查询,将要快许多。
并且有些时候,并不是每个定单用户都会点击查看的,因此实质,也不需要查询所有的信息出来,按需查询 是个极好的选择 ;
因此,延迟加载,会大大的提高数据库的性能 ;
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,然后调用 按需查询 方法 ;
一样可以完成 延迟加载 ;

浙公网安备 33010602011771号