Mybatis的缓存-2020.03.24

延迟加载和立即加载的概念

  • 问题 :在一对多中,我们需要一个用户,他有100个账户
    • 在查询用户的时候,要不要把关联的账户查出来?
      在查询用户时,用户下的账户信息应该是,什么时候用,什么时候查询的
    • 在查询账户的时候,要不要把关联的用户查出来?
      在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来
  • 什么是延迟加载
    在真正使用数据时才发起查询,不用的时候不查询,按需加载(懒加载)
  • 什么是立即加载
    不管用不用,只要一调用方法,马上发起查询
  • 在对应的四种表关系中:一对一,多对一,一对多,多对多
    一对多,多对多:通常情况下我们都是采用延迟加载
    多对一,一对一:通常情况下我们都是采用立即加载

mybatis一对一实现延迟加载

  
  
      
      
      
  
settings
  • IAccountDao.xml
      
      
      
    
      
      
          
          
          
          
          
      
    
      
      
    
      
      
    
      
    
延迟加载.png

mybaits一对多实现延迟加载

  • IUserDao.xml
    
    
    

  
  
      
      
      
      
      
      
      
  

  
  

  
  

  

缓存的概念

  • 什么是缓存
    存在于内存中的临时数据
  • 为什么使用缓存
    减少和数据库的交互次数,提高执行效率
  • 什么样的数据能使用缓存,什么样的数据不能使用
    • 适用于缓存:
      • 经常查询并且不经常改变的
      • 数据的正确与否对最终结果影响不大的
    • 不适用于缓存:
      • 经常改变的数据
      • 数据的正确与否对最终结果影响很大的
      • 例如:商品的库存,银行的汇率,股市的牌价

mybatis中的一级缓存

  • 一级缓存:

    它指的是Mybatis中SqlSession对象的缓存。
    当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
    该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。
    当SqlSession对象消失时,mybatis的一级缓存也就消失了。
    
  • 测试一级缓存:

      /**
         * 测试一级缓存
         */
        @Test
        public void testFirstLevelCache(){
            User user1 = userDao.findById(41);
            System.out.println(user1);
            User user2 = userDao.findById(41);
            System.out.println(user2);
    
            System.out.println(user1 == user2); //true
        }
    
  • 关闭SqlSession:

     /**
         * 测试一级缓存
         */
        @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); //false
        }
    

触发清空一级缓存的情况

  • 一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

  • 测试

       /**
         * 测试缓存的同步
         */
        @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); //true
        }
    
      /**
         * 测试缓存的同步
         */
        @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);   //false
        }
    

mybatis的二级缓存

  • 二级缓存:
    它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存


    二级缓存.png
  • 二级缓存的使用步骤:

    • 第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
    • 第二步:让当前的映射文件支持二级缓存(在IuseDao.xml中配置)
    • 第三步:让当前的操作支持二级缓存(在select标签中配置)
  • 代码

    • SqlMapConfig.xml
          
            
          
      
    • IuseDao.xml
        
        
        
      
      
      
      
      
      
      
      
      
      
      
          update user set username=#{username},address=#{address} where id=#{id}
      
      
      
    • SecondLevelCacheTest.java
        package com.itheima.test;
      
        import com.itheima.dao.IUserDao;
        import com.itheima.domain.User;
        import org.apache.ibatis.io.Resources;
        import org.apache.ibatis.session.SqlSession;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.apache.ibatis.session.SqlSessionFactoryBuilder;
        import org.junit.After;
        import org.junit.Before;
        import org.junit.Test;
      
        import java.io.InputStream;
      
          /**
         * @author 黑马程序员
         * @Company http://www.ithiema.com
         */
        public class SecondLevelCacheTest {
      
        private InputStream in;
        private  SqlSessionFactory factory;
      
        @Before//用于在测试方法执行之前执行
        public void init()throws Exception{
          //1.读取配置文件,生成字节输入流
          in = Resources.getResourceAsStream("SqlMapConfig.xml");
          //2.获取SqlSessionFactory
          factory = new SqlSessionFactoryBuilder().build(in);
      
      }
      
      @After//用于在测试方法执行之后执行
      public void destroy()throws Exception{
          in.close();
      }
      
      /**
       * 测试一级缓存
       */
      @Test
      public void testFirstLevelCache(){
          SqlSession sqlSession1 = factory.openSession();
          IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
          User user1 = dao1.findById(41);
          System.out.println(user1);
          sqlSession1.close();//一级缓存消失
      
          SqlSession sqlSession2 = factory.openSession();
          IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
          User user2 = dao2.findById(41);
          System.out.println(user2);
          sqlSession2.close();
      
          System.out.println(user1 == user2);
        }
      }
      
      

你可能感兴趣的:(Mybatis的缓存-2020.03.24)