mybatis的延迟加载&缓存

mybatis的延迟加载&缓存

一、延迟加载:在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.

好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

  1. assocation 实现延迟加载

    1.  **账户的持久层 DAO 接口** :List<Account> findAll();
      	2. **账户的持久层映射文件**
    
    <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE mapper 
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
    <mapper namespace="com.ityouxin.dao.IAccountDao"> 
    <!-- 建立对应关系 --> 
    <resultMap type="account" id="accountMap"> 
    <id column="aid" property="id"/> 
    <result column="uid" property="uid"/> 
    <result column="money" property="money"/> 
    <!-- 它是用于指定从表方的引用实体属性的 --> 
    <association property="user" javaType="user" 
    select="com.ityouxin.dao.IUserDao.findById" 
    column="uid"> 
    </association> 
    </resultMap> 
    <select id="findAll" resultMap="accountMap"> 
    select * from account 
    </select> 
    </mapper> 
    
    
    select: 填写我们要调用的 select 映射的 id 
    column : 填写我们要传递给 select 映射的参数
    
    

    3. 用户的持久层接口和映射文件

    public interface IUserDao { 
    /** 
    * 根据 id 查询 
    * @param userId 
    * @return 
    */ 
    User findById(Integer userId); 
    } 
    
    
    <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE mapper 
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
    <mapper namespace="com.ityouxin.dao.IUserDao"> 
    <!-- 根据 id 查询 --> 
    <select id="findById" resultType="user" parameterType="int" > 
    select * from user where id = #{uid} 
    </select> 
    </mapper>
    
    
    1. 开启Mybatis的延迟加载
    <!-- 开启延迟加载的支持 -->
    <settings> 
    <setting name="lazyLoadingEnabled" value="true"/> 
    <setting name="aggressiveLazyLoading" value="false"/> 
    </settings> 
    
    
  2. 使用Collection实现延迟加载

    1. 在User实体类中加入List accounts 属性
    2. 编写用户和账户持久层接口的的方法:List findAll();
    3. 编写用户持久层的映射配置
    <resultMap type="user" id="userMap"> 
    <id column="id" property="id"></id> 
    <result column="username" property="username"/> 
    <result column="address" property="address"/> 
    <result column="sex" property="sex"/> 
    <result column="birthday" property="birthday"/> 
    <!-- collection 是用于建立一对多中集合属性的对应关系 
    ofType 用于指定集合元素的数据类型 
    select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称) 
    column 是用于指定使用哪个字段的值作为条件查询 
    --> 
    <collection property="accounts" ofType="account" 
    select="com.ityouxin.dao.IAccountDao.findByUid" 
    column="id"> 
    </collection> 
    </resultMap> 
    <!-- 配置查询所有操作 --> 
    <select id="findAll" resultMap="userMap"> 
    select * from user 
    </select>
    
    <collection>标签: 
    主要用于加载关联的集合对象 
    select 属性: 
    用于指定查询 account 列表的 sql 语句,所以填写的是该 sql 映射的 id 
    column 属性: 
    用于指定 select 属性的 sql 语句的参数来源,上面的参数来自于 user 的 id 列,所以就写成 id 这一个字段名了
    
    1. 编写账户持久层映射配置
    <!-- 根据用户 id 查询账户信息 --> 
    <select id="findByUid" resultType="account" parameterType="int"> 
    select * from account where uid = #{uid} 
    </select> 
    
    
二、Mybatis缓存:
  1. 证明一级缓存的存在:一般一级缓存是sqlsession级别的缓存,只要Sqlsession没有flush或者close,一级缓存就存在

    1. 一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit()close()等方法时,就会清空一级缓存。
      
      
      /** 
      * 测试一级缓存 
      */ 
      @Test 
      public void testFirstLevelCache(){ 
      User user1 = userDao.findById(41); 
      System.out.println(user1); 
      // sqlSession.close(); 
      //再次获取 SqlSession 对象 
      // sqlSession = factory.openSession(); 
      sqlSession.clearCache();//此方法也可以清空缓存 
      userDao = sqlSession.getMapper(IUserDao.class); 
      User user2 = userDao.findById(41); 
      System.out.println(user2); 
      System.out.println(user1 == user2); 
      } 
      /**
      * 测试缓存的同步 
      */ 
      @Test 
      public void testClearlCache(){ 
      //1.根据 id 查询用户 
      User user1 = userDao.findById(41); 
      System.out.println(user1); 
      //2.更新用户信息 
      user1.setUsername("update user clear cache"); 
      user1.setAddress("北京市海淀区"); 
      userDao.updateUser(user1); 
      //3.再次查询 id 为 41 的用户 
      User user2 = userDao.findById(41); 
      System.out.println(user2); 
      System.out.println(user1 == user2); 
      } 
      当执行sqlSession.close()后,再次获取sqlSession并查询id=41的User对象时,又重新执行了sql语句,从数据库进行了查询操作。
      
      
    2. Mybatis二级缓存:二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

      1. 二级缓存的开启和关闭
      第一步:在 SqlMapConfig.xml 文件开启二级缓存 
      <settings> 
      <!-- 开启二级缓存的支持 --> 
      <setting name="cacheEnabled" value="true"/> 
      </settings> 
      因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为false 代表不开启二级缓存。 
      2.2.2.2 第二步:配置相关的 Mapper 映射文件 
      <cache>标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值。 
      <?xml version="1.0" encoding="UTF-8"?> 
      <!DOCTYPE mapper 
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
      <mapper namespace="com.ityouxin.dao.IUserDao"> 
      <!-- 开启二级缓存的支持 --> 
      <cache></cache> 
      </mapper> 
      2.2.2.3 第三步:配置 statement 上面的 useCache 属性 
      <!-- 根据 id 查询 --> 
      <select id="findById" resultType="user" parameterType="int" useCache="true"> 
      select * from user where id = #{uid} 
      </select> 
      将 UserDao.xml 映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement 要使用 
      二级缓存,如果不使用二级缓存可以设置为 false。 
      注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
      
      
    3. 二级缓存的注意事项

    当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这样就可以使用序列化方式来保存对象。:public class User implements Serializable { }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值