zoukankan      html  css  js  c++  java
  • (十一)延迟加载

    目录


    延迟加载的含义

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

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


    延迟加载的意义

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

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

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

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

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


    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,然后调用 按需查询 方法 ;

    一样可以完成 延迟加载

  • 相关阅读:
    iis 站点部署后 Microsof .Net Framework异常
    数据库中GUID的生成
    影响世界的100个经典管理定律
    帕金森定律(Parkinson's Law)
    eclipse 弹出智能提示、代码自动换行
    eclipse 快捷键
    extjs grid 分页
    extjs gride 显示序号
    SharePoint 2013 Deploy Master Page And Page Layout
    正则表达式匹配并替换字符串
  • 原文地址:https://www.cnblogs.com/young-youth/p/11665669.html
Copyright © 2011-2022 走看看