本文主要介绍了MyBatis二级缓存的工作原理、应用场景以及如何配置和使用二级缓存,帮助读者快速掌握MyBatis二级缓存的使用方法。文章详细解释了二级缓存的优点、配置方法和常见的缓存策略,并通过示例代码展示了二级缓存的实际应用。通过学习本文,读者可以深入了解MyBatis二级缓存,提升系统性能和响应速度。mybatis二级缓存学习入门涵盖了从基础概念到实践应用的全过程,适合对MyBatis有基本了解的开发者。
MyBatis 是一个优秀的持久层框架,它支持定制化 SQL 映射和存储过程调用。MyBatis 可以将 Java 对象与数据库中的记录进行映射,使得 Java 对象与数据库中的数据进行交互。MyBatis 提供了强大的动态 SQL 生成能力,可以实现复杂的数据查询和更新操作。MyBatis 的核心是一个 SqlSession
对象,它负责执行 SQL 语句,并返回相应的结果集。
MyBatis 的配置主要包括 mybatis-config.xml
文件和映射文件(Mapper XML 文件)。mybatis-config.xml
文件用于全局配置,而 Mapper XML 文件用于定义 SQL 映射语句。
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapping/UserMapper.xml"/> </mappers> </configuration>
<?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.mapping.UserMapper"> <select id="selectUserById" resultType="com.example.model.User"> SELECT * FROM users WHERE id = #{id} </select> </mapper>
MyBatis 的一级缓存是 SqlSession 级别的缓存。每个 SqlSession 实例都有一个本地缓存。当 SqlSession 执行查询时,结果会先存入本地缓存中,如果后续的查询语句命中了本地缓存,则直接从缓存中获取结果,而不会去数据库查询。当 SqlSession 关闭时,本地缓存会被清空。
一级缓存适用于同一个 SqlSession 实例中的多次查询操作。在 Web 应用中,通常每个请求会创建一个新的 SqlSession 实例,因此一级缓存的作用范围通常局限于单个请求。在某些情况下,可以利用一级缓存,减少连续查询相同数据的数据库访问次数,提高性能。
二级缓存是全局缓存,它可以在不同的 SqlSession 实例之间共享。二级缓存是 MyBatis 默认不开启的,需要手动配置。二级缓存可以显著提高查询性能,因为它减少了数据库的访问次数。
要开启二级缓存,需要在 mybatis-config.xml
中配置全局缓存,同时在每个 Mapper XML 文件中开启二级缓存。
<settings> <setting name="cacheEnabled" value="true"/> </settings>
<mapper namespace="com.example.mapping.UserMapper"> <cache/> <select id="selectUserById" resultType="com.example.model.User"> SELECT * FROM users WHERE id = #{id} </select> </mapper>
二级缓存的配置可以包括缓存的存储策略、缓存的清理策略等。以下是一些常用的二级缓存配置选项:
type
属性指定缓存的实现类,默认为 JdkDefaultCache
。type
属性指定自定义缓存实现类。<cache eviction="FIFO" flushInterval="60000" size="1024" readOnly="true"/>
eviction
:缓存的清除策略,FIFO
表示先进先出策略。flushInterval
:缓存刷新间隔,单位为毫秒。size
:缓存的大小。readOnly
:是否只读,如果设为 true
,则缓存只读,不会更新。<cache type="com.example.cache.CustomCache"/>
二级缓存的缓存区域包括查询缓存区和更新缓存区。查询缓存用于存储查询结果,更新缓存用于存储更新操作的结果。
查询缓存区存储查询语句的执行结果。当查询语句命中缓存时,直接从缓存中读取结果,避免了数据库查询。
更新缓存区存储更新操作的结果。当更新操作成功后,更新缓存区中的数据,确保缓存中的数据与数据库中的数据一致。
二级缓存的缓存策略包括缓存的刷新策略和清除策略。
缓存刷新策略主要包括 FIFO
(先进先出)、LRU
(最近最少使用)、LFU
(最不经常使用)等。
缓存清除策略包括手动清除和定时清除。手动清除可以在需要的时候手动清除缓存,定时清除则可以通过设置缓存刷新间隔来定时清除缓存。
以下是一个简单的示例,演示如何在 MyBatis 中使用二级缓存。
假设有一个 users
表,包含 id
和 username
两个字段。
CREATE TABLE users ( id INT PRIMARY KEY, username VARCHAR(100) );
public class User { private int id; private String username; // 构造函数、getter 和 setter 方法 }
<mapper namespace="com.example.mapping.UserMapper"> <cache/> <select id="selectUserById" resultType="com.example.model.User"> SELECT * FROM users WHERE id = #{id} </select> </mapper>
public interface UserMapper { User selectUserById(int id); }
public class UserMapperTest { public static void main(String[] args) { SqlSessionFactory sqlSessionFactory = null; SqlSession sqlSession = null; try { // 创建 SqlSessionFactory SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsReader("mybatis-config.xml")); // 打开两个 SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 第一次查询 User user = userMapper.selectUserById(1); System.out.println("First query result: " + user); // 关闭 SqlSession sqlSession.close(); // 打开另一个 SqlSession sqlSession = sqlSessionFactory.openSession(); userMapper = sqlSession.getMapper(UserMapper.class); // 第二次查询,命中二级缓存 user = userMapper.selectUserById(1); System.out.println("Second query result: " + user); } catch (IOException e) { e.printStackTrace(); } finally { if (sqlSession != null) { sqlSession.close(); } } } }
First query result: User(id=1, username=John) Second query result: User(id=1, username=John)
mybatis-config.xml
文件中是否开启了全局缓存,并且在 Mapper XML 文件中开启了二级缓存。SqlSession
的 clearCache()
方法来清除当前 SqlSession 的缓存,或者调用 Mapper
类的 clearCache()
方法来清除整个 Mapper 的缓存。// 清除当前 SqlSession 的缓存 sqlSession.clearCache(); // 清除整个 Mapper 的缓存 userMapper.clearCache();
flushInterval
属性来设置缓存刷新间隔,或者通过设置 eviction
属性来指定清除策略。<cache eviction="FIFO" flushInterval="60000" <!-- 每 60 秒刷新缓存 --> size="1024" readOnly="true"/>
type
属性来指定自定义的缓存实现类,并实现 org.apache.ibatis.cache.Cache
接口。public class CustomCache implements Cache { private Map<String, Object> cacheMap = new HashMap<>(); @Override public String getId() { return this.getClass().getName(); } @Override public void putObject(Object key, Object value) { cacheMap.put(key.toString(), value); } @Override public Object getObject(Object key) { return cacheMap.get(key.toString()); } @Override public Object removeObject(Object key) { return cacheMap.remove(key.toString()); } @Override public void clearCache() { cacheMap.clear(); } @Override public int getSize() { return cacheMap.size(); } @Override public Collection<Object> getAllObjects() { return cacheMap.values(); } @Override public void putObjects(Map<String, Object> map) { cacheMap.putAll(map); } } `` 通过以上示例和说明,可以更好地理解和使用 MyBatis 的二级缓存功能,从而提高系统的性能和响应速度。