【Mybatis】04 - Mybatis延迟加载与缓存

1. Mybatis中的延迟加载

1.1 问题

  1. 在一对多中,当一个用户有一百个账户,在查询用户的时候,要不要把关联的账户查询出来?在查询账户的时候,要不要将关联的用户查询出来?

1.2 解决

1 在查询用户时,用户下的账户信息应该是什么时候使用,什么时候查询的。(延迟加载)

  1. 在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。(立即加载)

1.3 概念

  1. 延迟加载 :在真正使用数据时才发起查询, 不用的时候不查询。也叫按需加载或懒加载。

  2. 立即加载:不管用不用,只要一旦调用方法,马上发起查询。

1.4 对应的四种表关系

  1. 一对多 ||多对多 :通常使用的是延迟加载;

  2. 多对一 || 一对一:通常使用的是立即加载;

2. 一对一实现延迟加载

2.1 创建一个新Demo

  1. 这里的Demo不使用骨架的方式创建,之后复制之前一对多Demo的代码。进行测试。

  2. 在查询账户的时查询用户信息,修改AccountDao.xml


        
        
        
        
        
        
        
    
  
    
  1. 在全局配置文件中配置懒加载:参考网址
配置延迟加载
使用settings标签机进行配置
 
    
        
        
        
        
    
注意事项这里的配置标签是有顺序的一定需要按照规定的顺序进行配置,否则将报错。
配置的标签顺序
  1. 配置延迟加载之前 控制台日志信息:
配置懒加载之前的查询
配置懒加载之后的查询

3. 一对多实现延迟加载

  1. 在AccountDao.java持久层接口中添加根据用户id查询账户信息的方法。并在AccountDao.xml配置文件中进行配置:
    /**
     * 根据用户id查询账户信息
     * @param uid
     * @return
     */
    List findAccountByUid(Integer uid);
 
    
  1. 在UserDao.xml中修改,用户和账户的关联映射:
 
        
        
        
        
        
        
        
        
    
需要注意这里的column属性
  1. 使用延迟加载前后的区别:
使用延迟加载前
使用延迟加载之后

3.1 Demo地址

  1. Demo地址 : 一对一 一对多 实现懒加载

4. Mybatis 缓存

4.1 什么是缓存?

  1. 缓存是存在内存中的临时数据。

4.2 为什么使用缓存?

  1. 减少和数据库交互次数,提高执行效率。

4.3 什么样的数据适用于缓存?

  1. 经常查询并且不经常改变的。

  2. 数据的正确与否对最终结果影响不大的。

4.4 不适用于使用缓存的?

  1. 经常改变的数据;
  2. 数据的正确性对最终结果影响很大的;

4.5 Mybatis的一级缓存

4.5.1 Mybatis的一级缓存简介

  1. Mybatis的一级缓存指的是Mybatis中SqlSession对象的缓存。当我们执行查询之后,查询结果会同时存入到SqlSession为我们提供的一块区域中。该区域的结构是一个Map。当我们再次查询同样的数据,Mbatis会先去SqlSession中查询是否有?有的话直接拿出来。

4.5.2 Mybatis中一级缓存Demo

  1. 创建一个普通的Maven工程,实现简单的查询所有User。

  2. 在findById方法中测试 :

  • 未关闭SqlSession
 /**
     * 根据 id 查询用户信息
     */
    @Test
    public void findById() {

        /*使用Mybatis SqlSession中的一级缓存进行测试*/
        User user1 = userDao.findById(50);
        System.out.println(user1);

        User user2 = userDao.findById(50);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }
未关闭SqlSession的情况
  • 关闭SqlSession之后
 /**
     * 根据 id 查询用户信息
     */
    @Test
    public void findById() {

        /*使用Mybatis SqlSession中的一级缓存进行测试*/
        User user1 = userDao.findById(50);
        System.out.println(user1);

        // 在此处关闭SqlSession
        session.close();
        // 重新获取一个SqlSession
        session = factory.openSession();

        userDao = session.getMapper(UserDao.class);

        User user2 = userDao.findById(50);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }
关闭SqlSession之后释放缓存
  • 除了使用关闭SqlSession释放缓存的方式之外,还可以使用SqlSession的clearCache()方法释放缓存
/**
     * 根据 id 查询用户信息
     */
    @Test
    public void findById() {

        /*使用Mybatis SqlSession中的一级缓存进行测试*/
        User user1 = userDao.findById(50);
        System.out.println(user1);

       /* // 在此处关闭SqlSession
        session.close();
        // 重新获取一个SqlSession
        session = factory.openSession();*/

       session.clearCache();

        userDao = session.getMapper(UserDao.class);

        User user2 = userDao.findById(50);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

4.5.3 Mybatis中一级缓存如何做到同步

  1. Mybatis的一级缓存,当调用SqlSession的修改、添加、删除、commit()、close()等方法就会清空一级缓存。

  2. 在UserDao持久层接口中添加一个更新用户信息的方法。进行测试。

 /**
     * 更新用户信息
     * @param user
     */
    void updateUser(User user);
    
        update user set username = #{username} , address = #{address}
        where id = #{id}
    
  1. 编写测试类进行测试:
    @Test
    public void testUpdateToCache() {
        User user1 = userDao.findById(41);
        user1.setUsername("update to first level cache");
        user1.setAddress("重庆市渝北区");
        userDao.updateUser(user1);
        System.out.println(user1);

        // 再次查询
        User user2 = userDao.findById(41);
        System.out.println(user2);
        System.out.println(user1 == user2);
    }

4.6 Mybatis中的二级缓存

  1. 二级缓存概念:指的是Mybatis中SqlSessionFactory对象的缓存由同一个SqlSessiondFactory对象创建SqlSession共享其缓存。


    同一个SqlSessionFactory创建的SqlSession对象共享缓存

4.6.1 二级缓存的使用步骤

  1. 让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)。可以不用设置因为默认值就是true。
在全局配置文件中开启对缓存的支持
  1. 在让当前的映射配置文件支持缓存(在UserDao.xml中配置)。


    在映射配置文件中开启对缓存的支持
  2. 让当前的操作支持二级缓存(在Select标签中配置)。

在Select标签中开启对缓存的支持

4.6.2 在测试类中编写测试类进行测试

/**
     * 测试Mybatis的二级缓存  同一个factory创建的SqlSession对象共享缓存 但是前提是需要让Mybatis支持二级缓存
     */
    @Test
    public void testMyabtisSecondLevelCache() {
        // 同一个factory创建的SqlSession对象共享缓存
        SqlSession session1 = factory.openSession();
        UserDao userDao1 = session1.getMapper(UserDao.class);
        User user1 = userDao1.findById(41);
        System.out.println(user1);
        session1.close();

        SqlSession session2 = factory.openSession();
        UserDao userDao2 = session2.getMapper(UserDao.class);
        User user2 = userDao2.findById(41);
        System.out.println(user2);
        session2.close();

        System.out.println(user1 == user2);
    }
未开启Mybatis对缓存的支持
报错:因为实体类未实现Serializable接口实现之后恢复正常
开启对缓存的支持之后

4.6.2 Demo地址

  1. Demo地址 : Mybatis实现一级缓存和二级缓存

你可能感兴趣的:(【Mybatis】04 - Mybatis延迟加载与缓存)