search
HomeJavajavaTutorialWhat are Java Mybatis first-level cache and second-level cache?

1. What is cache

The cache is an area in the memory where data is stored. The purpose is to improve query efficiency. MyBatis will store the query results in the cache. When executes the same SQL next time, it will not access the database, but directly obtain the results from the cache, thus reducing the pressure on the server.

What is cache?

A piece of data that exists in memory.

What is the role of cache?

Reduce the interaction between the program and the database, improve query efficiency, and reduce the pressure on the server and database.

What kind of data is cached?

Data that is frequently queried but not frequently changed, and has little impact on the results after changes.

What are the categories of MyBatis cache?

Level 1 Cache and Level 2 Cache

How to determine whether two SQLs are the same?

The Sql statement of the query is the same, the parameter values ​​passed are the same, the requirements for the result set are the same, the precompiled template ID is the same

2. Mabtis first-level cache

MyBatis The first-level cache is also called local cache. The SqlSession object contains an Executor object, and the Executor object contains a PerpetualCache object, which stores first-level cache data.

Since the first-level cache is in the SqlSession object, the first-level cache can only be shared when using the same SqlSession object to operate the database.

MyBatis's first-level cache is enabled by default and does not require any configuration.

As shown below:

What are Java Mybatis first-level cache and second-level cache?

(1) Test the first-level cache

In fact, the test method is very simple, that is, by using the same and different SqlSession objects to perform SQL queries, you can know whether the hash values ​​of the returned objects are the same. If the hash values ​​returned are the same, it means that the SQL query is not performed, but directly Get the object from the cache to return

The following is using the same Session object to execute the query. If the hash values ​​of user1 and user2 are the same, it means that the first level cache is indeed enabled, and There is no query, but the data is taken directly from the cache.

import com.mybatisstudy.mapper.UserMapper;
import com.mybatisstudy.pojo.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.Test;
 
import java.io.InputStream;
 
public class TestUserMapper3 {
    // 测试使用同一个SqlSession查询
    @Test
    public void testCache1() throws Exception{
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session = factory.openSession();
 
        // 使用同一个SqlSession查询
        UserMapper mapper1 = session.getMapper(UserMapper.class);
        UserMapper mapper2 = session.getMapper(UserMapper.class);
 
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
        System.out.println("------------------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
 
        session.close();
    }
}

Execution result

What are Java Mybatis first-level cache and second-level cache?

## OK, indeed the returned hash values ​​are the same, and We can show through the console output that it does not query but directly gets the object from the cache and returns it, so this is the first-level cache, which improves query efficiency.

Under different sqlsessions for testing, whether the returned hash value is consistent

// 测试使用不同SqlSession查询
    @Test
    public void testCache2() throws Exception{
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session1 = factory.openSession();
        SqlSession session2 = factory.openSession();
 
        // 测试使用不同SqlSession查询
        UserMapper mapper1 = session1.getMapper(UserMapper.class);
        UserMapper mapper2 = session2.getMapper(UserMapper.class);
 
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
        System.out.println("---------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
 
        session1.close();
        session2.close();
    }

What are Java Mybatis first-level cache and second-level cache?

OK, you can see that the returned hash value is different, and the output display of the console can also be seen that it is also a query here. The first-level cache is indeed based on the SqlSession object

(2) Clear the first-level cache

But, if there is too much cache, it will also affect us Query efficiency, so you need to clear the cache at this time, just like we have to clear the mobile phone cache from time to time otherwise it will be very stuck. It is the same reason. So how to clear the first-level cache?

Perform the following operations to clear the MyBatis first-level cache:

    SqlSession calls close(): The SqlSession object is unavailable after the operation, and the object's Cached data is also unavailable.
  • SqlSession calls clearCache() / commit(): The operation will clear the first-level cache data.
  • SqlSession calls the addition, deletion and modification method: the operation will clear the first-level cache data, because the database changes after addition, deletion and modification, the cached data will be inaccurate
  • // 清空Mybatis一级缓存
        @Test
        public void testCache3() throws Exception{
            InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = builder.build(is);
            SqlSession session = factory.openSession();
     
            UserMapper mapper1 = session.getMapper(UserMapper.class);
            UserMapper mapper2 = session.getMapper(UserMapper.class);
     
            User user1 = mapper1.findById(1);
            System.out.println(user1.hashCode());
     
            // 清空Mybatis一级缓存
            session.clearCache();
     
            System.out.println("-------------------------------");
            User user2 = mapper2.findById(1);
            System.out.println(user2.hashCode());
     
            session.close();
        }
Execution effect

What are Java Mybatis first-level cache and second-level cache?

OK, the returned hash value is indeed different, but have we observed this? When using different SqlSession objects to execute queries above, the console input display is a bit different, that is, there is no need to establish a JDBC connection here, which also effectively improves query efficiency, so we still have to clear the cache occasionally

三、Mybatis二级缓存

MyBatis二级缓存也叫全局缓存。数据存放在SqlSessionFactory中,只要是同一个工厂对象创建的SqlSession,在进行查询时都能共享数据。一般在项目中只有一个SqlSessionFactory对象,所以二级缓存的数据是全项目共享的。
MyBatis一级缓存存放的是对象,二级缓存存放的是对象的数据。所以要求二级缓存存放的POJO必须是可序列化的,也就是要实现Serializable接口。
MyBatis二级缓存默认不开启,手动开启后数据先存放在一级缓存中,只有一级缓存数据清空后,数据才会存到二级缓存中。           
SqlSession 调用 clearCache() 无法将数据存到二级缓存中。

(1)开启二级缓存

1. POJO类实现Serializable接口

import java.io.Serializable;
 
public class User implements Serializable {
    private int id;
    private String username;
    private String sex;
    private String address;
}

2. 在Mybatis配置文件添加如下设置

<!-- 二级缓存打开 -->
<settings>   
 <setting></setting>
</settings>

这里有个额外知识,就是Mybatis配置文件的标签还得按照顺序来放的,否则就会以下编译错误;

The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,

objectWrapperFactory?,reflectorFactory?,plugins?,environments?,

databaseIdProvider?,mappers?)". 

  同时也说明了放置顺序就得按照match里面的顺序来放

3. 添加 标签

 如果查询到的集合中对象过多,二级缓存只能缓存1024个对象引用。可以通过

标签的size属性修改该数量。

比如:

(2)测试二级缓存

        那怎么测试呢,从上面我们可以知道二级缓存存放的是对象的数据,并且是基于SqlSessionFactory的,因此我们可以用SqlSessionFactory获取两个SqlSession对象,然后让他们分别获取各自的mapper,然后进行查询,返回到同一个实例化的USer对象中,如果返回的数据是一致的,但是对象的哈希值是不一样的话,则说明二级缓存里存放的确实对象的数据而不是对象。

// 测试二级缓存
@Test
public void testCache4() throws Exception {
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(is);
    SqlSession session = factory.openSession();

    UserMapper mapper1 = session.getMapper(UserMapper.class);
    UserMapper mapper2 = session.getMapper(UserMapper.class);

    User user1 = mapper1.findById(1);
    System.out.println(user1);
    System.out.println(user1.hashCode());

    // 让一级缓存失效
    session.commit();
    System.out.println("----------------------------");

    user1 = mapper2.findById(1);
    System.out.println(user1);
    System.out.println(user1.hashCode());
}

运行结果 

What are Java Mybatis first-level cache and second-level cache?

        OK,从运行结果上我们可以知道结果集返回到同一个对象中,而他们的哈希值反而不一样,说明执行第二次查询的时候新建了一个对象并且该对象指向那个对象并且将SqlSessionFactory中的数据赋值到新建的那个对象。其实从控制台打印的日志我们也可以得出,并没有执行查询方法,因为没有打印SQL语句,而且缓存也是从0.0改成了0.5,因此我们可以断定二级缓存存放的是数据而不是对象。

The above is the detailed content of What are Java Mybatis first-level cache and second-level cache?. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:亿速云. If there is any infringement, please contact admin@php.cn delete
How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log?How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log?Apr 19, 2025 pm 11:45 PM

Start Spring using IntelliJIDEAUltimate version...

How to elegantly obtain entity class variable names to build database query conditions?How to elegantly obtain entity class variable names to build database query conditions?Apr 19, 2025 pm 11:42 PM

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

How to use the Redis cache solution to efficiently realize the requirements of product ranking list?How to use the Redis cache solution to efficiently realize the requirements of product ranking list?Apr 19, 2025 pm 11:36 PM

How does the Redis caching solution realize the requirements of product ranking list? During the development process, we often need to deal with the requirements of rankings, such as displaying a...

How to safely convert Java objects to arrays?How to safely convert Java objects to arrays?Apr 19, 2025 pm 11:33 PM

Conversion of Java Objects and Arrays: In-depth discussion of the risks and correct methods of cast type conversion Many Java beginners will encounter the conversion of an object into an array...

How do I convert names to numbers to implement sorting and maintain consistency in groups?How do I convert names to numbers to implement sorting and maintain consistency in groups?Apr 19, 2025 pm 11:30 PM

Solutions to convert names to numbers to implement sorting In many application scenarios, users may need to sort in groups, especially in one...

E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products?E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products?Apr 19, 2025 pm 11:27 PM

Detailed explanation of the design of SKU and SPU tables on e-commerce platforms This article will discuss the database design issues of SKU and SPU in e-commerce platforms, especially how to deal with user-defined sales...

How to set the default run configuration list of SpringBoot projects in Idea for team members to share?How to set the default run configuration list of SpringBoot projects in Idea for team members to share?Apr 19, 2025 pm 11:24 PM

How to set the SpringBoot project default run configuration list in Idea using IntelliJ...

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)