(十一)延迟加载

目录


延迟加载的含义

    比如现在我们有一个网页,在网页上显示 订单信息,然后鼠标某一个 订单信息 ,则会显示产生这个订单的 用户信息

     我们可以看出,当用户不点击具体的 订单信息 的时候,我们是不需要去显示具体的 用户信息 的 ;也就是说,开始我们只需要查询 订单表,即可完成需求,等到需要显示用户信息了,再去查询 用户表 ,这种 按需加载,也就是 延迟加载


延迟加载的意义

我们都知道数据库在进行 关联查询 的时候,关联的表越多,查询速度越慢 ;

比如上面的情况,不使用延迟加载,则开始就是有关联查询,查询出所有信息;

而我们使用延迟加载,就会 按需加载,首先只会去查询需要的表,比 关联查询,将要快许多。

并且有些时候,并不是每个定单用户都会点击查看的,因此实质,也不需要查询所有的信息出来,按需查询 是个极好的选择

因此,延迟加载,会大大的提高数据库的性能 ;


mybatis支持延迟加载

使用 resultMapassociationcollection 标签都支持实现延迟加载 ;


使用方法

需求:查询订单及其关联的用户信息 ;

由于我们使用 懒惰加载因此,我们需要配置 2 个 statement 对象,一个用于 直接查询,一个 用于 按需查询

  1. 配置 直接查询sql

    查询订单表

    <select id="findOrdersAndUserLazyLoading" resultMap="findOrdersAndUserLazyLoadingMap" >
        SELECT * FROM `order`
    </select>
  2. 配置 懒加载 使用的 sql

    查询用户表

    <select id="findUserById" parameterType="int" resultType="xin.ijava.pojo.User">
       select * from User where id = #{id}
    </select>
  3. 创建 resultMap 实现懒加载

    使用 selectcolumn 实现懒加载 ;

    <!--懒加载-->
    <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>
  4. 编写接口

    public List<OrdersUsers> findOrdersAndUserLazyLoading() throws Exception ;
  5. 测试代码

    @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);
    }
  6. 观察 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 个订单,只执行了 3sql,这是因为其中一级缓存的原因 ;


假如 mybatis 不支持延迟加载

假如mybatis 不支持 延迟加载 ,我们也不要慌(问题很大,慌也没有用),它不支持,离开它,我们还不能做事了啊。想一下,我们还有许多其他持久层的框架使用啊 ;

说正事,假如 mybatis 不支持 延迟加载 ,我们也是可以手动实现的;

我们定义 2 个方法,分别用于 直接查询按需查询 ;在页面上先使用 直接查询 查询我们需要的订单信息,然后如果需要继续查询关联的用户信息,则在 services 层 拦截一下,传入产生订单的用户 id,然后调用 按需查询 方法 ;

一样可以完成 延迟加载

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值