The principle and use of Mybatis's first and second level caches, the prohibition of specified methods of second level cache and refresh cache, Mybatis integrated Ehcache, the use scenarios and limitations of second level cache-day03

The first section Mybatis cache

1.1 Mybatis cache understanding

  • Mybatis's cache is similar to hibernate's cache, including the first level cache and the second level cache . The first level cache is used by default, and the second level cache needs to be turned on manually.
  • The first level cache refers to sqlsession. There is a data area in sqlsession, which is a map structure. This area is the first level cache area. The key in the first level cache is a unique value composed of information such as SQL statements, conditions, and statements. The value in the first level cache is the result object of the query.
  • The second-level cache refers to the mapper under the same namespace. In the second-level cache, there is also a map structure. This area is the first-level cache area.
    Insert picture description here

Get a piece of data in sqlSession1, and you can get the same data in sqlSession2 without using SQL. At this time, you need to use the secondary cache.
The secondary cache is shared by all sqlSessions

1.2 Level 1 cache

principle

  • For the first query, the user whose id is 1 will execute sql, and the first level cache will be performed by default, and the data will be stored in the first level cache map. When the modification, addition, and deletion of users are submitted, the first level cache will be cleared. , Query the user whose id is 1 again and need to execute sql again
    Insert picture description here

Use and test

  • Previous save and findUserById methods
    Insert picture description here
    Insert picture description here
  • Note that the class to be configured to implement the serialization interface (that is, a serializable flag), otherwise an error will be reported
    Insert picture description here

Insert picture description here

	@Test
    public void test1() throws IOException {
    
    
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        SqlSession sqlSession = sessionFactory.openSession();

        //默认情况下的一级缓存是开启的
        //4.通过会话获取dao接口
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user1 = userMapper.findUserById(1);
        System.out.println(user1);

        //第二次不会执行sql
        User user2 = userMapper.findUserById(1);
        System.out.println(user2);

        sqlSession.close();
    }
  • When it involves saving, updating, deleting, etc., the first level cache is automatically cleared
    Insert picture description here
	@Test
    public void test2() throws IOException {
    
    
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        SqlSession sqlSession = sessionFactory.openSession();

        //默认情况下的一级缓存是开启的
        //保存、删除、更新后,一级缓存会自动清空,下次查询会再次执行sql
        //4.通过会话获取dao接口
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user1 = userMapper.findUserById(1);
        System.out.println(user1);

        //保存一个新用户
        userMapper.save(new User("shu1","男",new Date(),"北京市"));
        //若要保存到数据库记得提交事务,否则不影响数据库,这里只做演示一级缓存可不提交
        sqlSession.commit();
        //此时第二次会执行sql
        User user2 = userMapper.findUserById(1);
        System.out.println(user2);

        sqlSession.close();
    }

Insert picture description here

1.3 Secondary cache

principle

Insert picture description here

Use and test

  1. Turn on the general switch of the secondary cache (configured in the global configuration file) (more settings are set in day01)
    Insert picture description here
  2. Configure the secondary cache in UserMapper.xml
    Insert picture description here
  3. test
  • Note that the class to be configured to implement the serialization interface (that is, a serializable flag), otherwise an error will be reported
    Insert picture description here
    Insert picture description here
	//二级缓存
    @Test
    public void test3() throws IOException {
    
    
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();

        //默认情况下的一级缓存是开启的
        //保存、删除、更新后,一级缓存会自动清空,下次查询会再次执行sql
        //4.通过会话获取dao接口
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);


        User user1 = userMapper1.findUserById(1);
        System.out.println(user1);
        //session关闭了,数据才会写入二级缓存
        sqlSession1.close();

        User user2 = userMapper2.findUserById(1);
        System.out.println(user2);
        sqlSession2.close();
    }
  1. If operations such as insert, update, delete, etc. are performed, the secondary cache will be cleared
	@Test
    public void test4() throws IOException {
    
    
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession();

        //默认情况下的一级缓存是开启的
        //保存、删除、更新后,一级缓存会自动清空,下次查询会再次执行sql
        //4.通过会话获取dao接口
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
        UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);

        User user1 = userMapper1.findUserById(1);
        System.out.println(user1);
        sqlSession1.close();

        //保存用户,二级缓存也会清空
        userMapper3.save(new User("shu2","男",new Date(),"上海市"));
        sqlSession3.commit();
        sqlSession3.close();

        User user2 = userMapper2.findUserById(1);
        System.out.println(user2);
        sqlSession2.close();

    }

Insert picture description here
Insert picture description here

Disable the second level cache of the specified method

Insert picture description here

  • The second level cache of the specified method is disabled, the second level cache of this method does not take effect, and other methods do not affect
    Insert picture description here

Refresh cache

  • The second-level cache of the specified method is disabled above. This method is used to reflect the second-level cache. Remember to remove the disablement, otherwise the cache will not be refreshed.
    Insert picture description here
    Insert picture description here

to sum up

The common point between the first-level cache and the second-level cache: when operations such as insert, update, and delete are performed, the cache will be cleared.

1.4 Integrate ehcache

  • Question: Why not use the cache that comes with Mybatis, but integrate the ehcache cache?
  • Answer: Mybatis itself is a persistence layer framework, it is not a dedicated caching framework, so its implementation of caching is not good enough to support distributed, while Ehcache is a distributed caching framework.

What is distributed

  • In order to improve performance, the system usually adopts distributed deployment (cluster deployment)
    Insert picture description here

Integrated thinking

  • The cache has a standardized interface Cache (who wants to use it, just implement it and write the corresponding method), and its default implementation is PerpetualCache of mybatis. If you want to integrate the secondary cache of mybatis, then implement the Cache interface.
    Insert picture description here
  • Mybatis comes with implementation cache
    Insert picture description here

Integration steps

Step 1: Import the jar package

Insert picture description here
Insert picture description here

  • You can see the cache implemented by ehcache
    Insert picture description here

Step 2: Configure the cache tag in the mapping file

Insert picture description here

	<!--配置缓存
    type不写,默认使用的就是mybatis自带的缓存技术,perpetualCache永久缓存
    -->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

Step 3: Add ehcache configuration file under src

Insert picture description here

  • Copy it to the src directory and rename it to ehcache.xml (after deleting the comment)
    Insert picture description here

  • maxElementsInMemory: Set the maximum number of objects that can be stored in the memory-based cache.

  • eternal: Set whether the object is permanent, true means never expire, if it is false, then it must be judged according to timeToIdleSeconds and timeToLiveSeconds.

  • timeToIdleSeconds: Set the maximum time for the object to be idle, in seconds. After this time, the object expires. When the object expires, EHCache will remove it from the cache. If this value is 0, it means that the object can be idle indefinitely. (The unit is seconds)

  • timeToLiveSeconds: Set the longest time for the object to live. After this time, the object expires. If this value is 0, it means that the object can exist in the cache indefinitely. The attribute value must be greater than or equal to the timeToIdleSeconds attribute value (in seconds)

  • overflowToDisk: Set whether to write overflow objects to the hard disk-based cache after the number of objects in the internal cache reaches the upper limit

  • diskPersistent: Whether to persist the object (stored to the hard disk) when the jvm ends, true or false is optional, the default is false

  • diskExpiryThreadIntervalSeconds: Specifies the polling time of the listening thread dedicated to clearing expired objects. (The unit is seconds)

  • memoryStoreEvictionPolicy: When the memory cache reaches the maximum and a new element is added, the policy when the element in the cache is removed to the disk. The default is LRU (least recently used), options are LFU (least frequently used, least used) and FIFO (first in first out)

  • LRU (Least Recently Used): The cached element has a timestamp. When the cache capacity is full and you need to make room to cache new elements, then the element in the existing cache element whose timestamp is the farthest from the current time Will be cleared from the cache.

  • LFU (Less Frequently Used): The cached element has a hit attribute, and the one with the smallest hit value will be cleared from the cache.

Step 4: Test

  • Use the previous test secondary cache
	//二级缓存
    @Test
    public void test3() throws IOException {
    
    
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();

        //默认情况下的一级缓存是开启的
        //保存、删除、更新后,一级缓存会自动清空,下次查询会再次执行sql
        //4.通过会话获取dao接口
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);

        User user1 = userMapper1.findUserById(1);
        System.out.println(user1);
        //session关闭了,数据才会写入二级缓存
        sqlSession1.close();

        User user2 = userMapper2.findUserById(1);
        System.out.println(user2);
        sqlSession2.close();
    }
  • Execute SQL once and fetch it from the second-level cache for the second time
    Insert picture description here

1.5 Usage scenarios of secondary cache

  • For queries that require high access response speed but low real-time performance, secondary cache technology can be used .
    Note: When using the second-level cache, you must set a refresh interval (there is a flashInterval attribute in the cache tag) to refresh the second-level cache regularly. This refresh interval is set according to specific needs, such as 30 minutes, 60 minutes, etc., unit Is milliseconds.
  • For example: set the cache refresh interval to 60 minutes (clear the cache every 60 minutes)
    Insert picture description here

1.6 Limitations of the second-level cache

  • Mybatis second-level cache is not well implemented for fine-grained data.

  • For example: Cache product information. Due to the large amount of product information query visits, users must query the latest product information every time. At this time, if the secondary cache is used, it is impossible to refresh only the cached information of the product when a product changes. It does not refresh other product cache information, because the secondary cache is at the mapper level. When the information of a product is updated, the information cache data of all products will be cleared.

  • To solve such problems, data needs to be cached in a targeted manner at the business layer as needed.

  • For example, operations on frequently changing data can be separately placed in the mapper of another namespace.

Guess you like

Origin blog.csdn.net/qq_43414199/article/details/108883820