Mybatis的二級快取

是橙子呐發表於2024-11-30

以根據使用者id查詢使用者為例。
二級快取開啟:1. 先配置全域性二級快取,2. UserMapper.xml檔案中的sql語句上開啟二級快取。兩者缺一不可。

首先,我們假設已經有一個MyBatis的全域性配置檔案mybatis-config.xml,它啟用了二級快取:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <!-- 啟用二級快取的全域性開關 -->
    <settings>
        <setting name="cacheEnabled" value="true"/>
        <!-- 其他設定 -->
    </settings>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
        <!-- 其他Mapper -->
    </mappers>
</configuration>

接下來,我們有一個Mapper XML檔案UserMapper.xml,它定義了一個查詢,並啟用了二級快取

<?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.example.mapper.UserMapper">
   <!-- 啟用當前 Mapper 的二級快取 -->
    <cache/>
    <!-- 查詢使用者 -->
    <select id="selectUserById" resultType="com.example.domain.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

然後,我們有一個對應的Java介面UserMapper.java:

package com.example.mapper;

import com.example.domain.User;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {
    // 這裡通常會有@Select註解或其他Mapper註解,但在這個例子中我們已經在XML中定義了SQL
    User selectUserById(int id);
}

以及一個User類User.java,它表示資料庫中的使用者表:

package com.example.domain;

public class User {
    private int id;
    private String name;
    private String email;

    // Getters and Setters
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

最後,我們有一個簡單的Java應用程式,它使用MyBatis來查詢使用者,並演示二級快取的工作:

package com.example;

import com.example.domain.User;
import com.example.mapper.UserMapper;
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 java.io.IOException;
import java.io.Reader;

public class MyBatisExample {
    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        Reader reader;
        SqlSession session = null;

        try {
            reader = Resources.getResourceAsReader(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

            // 開啟第一個SqlSession
            session = sqlSessionFactory.openSession();
            try (SqlSession session1 = session) {
                UserMapper mapper = session1.getMapper(UserMapper.class);
                User user1 = mapper.selectUserById(1);
                System.out.println("User 1: " + user1.getName());
            }

            // 開啟第二個SqlSession(注意這裡不是同一個SqlSession物件)
            session = sqlSessionFactory.openSession();
            try (SqlSession session2 = session) {
                UserMapper mapper = session2.getMapper(UserMapper.class);
                User user2 = mapper.selectUserById(1);
                System.out.println("User 2: " + user2.getName());
            }

            // 注意到這裡沒有提交或關閉SqlSession,但在實際應用中應該適當管理SqlSession的生命週期
            // 在這個例子中,由於我們啟用了二級快取,並且兩次查詢是相同的,所以第二次查詢應該會從快取中獲取結果

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

在這個例子中,我們有兩個不同的SqlSession物件,但它們都對映到同一個UserMapper介面。由於我們在UserMapper.xml中啟用了二級快取,並且兩次查詢都是相同的(即查詢ID為1的使用者),因此第二次查詢應該會從快取中獲取結果,而不是再次執行SQL查詢。這可以透過觀察控制檯輸出來驗證,如果兩次查詢的輸出是相同的,並且沒有看到SQL查詢日誌(這取決於你的MyBatis配置和日誌級別),那麼這就表明二級快取正在工作。

相關文章