MyBatis 中如何使用缓存
MyBatis 是一个基于 Java 的持久层框架,它提供了多种方式来使用缓存,包括一级缓存和二级缓存。本文将介绍 MyBatis 中常见的缓存使用方式及其使用方法。
1. 一级缓存
MyBatis 中的一级缓存是指 SqlSession 的缓存,它默认是开启的。在同一个 SqlSession 中,如果执行了相同的 SQL 语句,那么 MyBatis 会从缓存中读取结果,而不是再次向数据库发起请求。下面是一个简单的示例:
public class MyBatisTest {public static void main(String[] args) {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();try {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 第一次查询,从数据库中获取数据User user1 = userMapper.getUserById(1);System.out.println(user1);// 第二次查询,从一级缓存中获取数据User user2 = userMapper.getUserById(1);System.out.println(user2);// 更新数据,清空一级缓存user1.setName("Tom");userMapper.updateUser(user1);sqlSession.commit();// 第三次查询,从数据库中获取数据User user3 = userMapper.getUserById(1);System.out.println(user3);// 第四次查询,从一级缓存中获取数据User user4 = userMapper.getUserById(1);System.out.println(user4);} finally {sqlSession.close();}}
}
在上面的示例代码中,首先读取了配置文件 mybatis-config.xml,然后通过 SqlSessionFactoryBuilder 将配置文件解析为 SqlSessionFactory 对象,最后通过 SqlSessionFactory 创建 SqlSession 对象。在 SqlSession 中,通过 getMapper 方法获取映射器接口的实例,然后就可以直接调用映射器接口中的方法执行 SQL 语句了。在第一次查询时,会从数据库中获取数据,并将结果存储在一级缓存中。在第二次查询时,会直接从一级缓存中获取数据。在更新数据后,需要清空一级缓存,否则会出现数据不一致的情况。
2. 二级缓存
除了一级缓存外,MyBatis 还提供了二级缓存,它是 SqlSessionFactory 的缓存。在多个 SqlSession 中共享同一个二级缓存,如果执行了相同的 SQL 语句,那么 MyBatis 会从缓存中读取结果,而不是再次向数据库发起请求。下面是一个简单的示例:
public class MyBatisTest {public static void main(String[] args) {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();try {UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);// 第一次查询,从数据库中获取数据,并存储到二级缓存中User user1 = userMapper1.getUserById(1);System.out.println(user1);// 第二次查询,从二级缓存中获取数据User user2 = userMapper2.getUserById(1);System.out.println(user2);// 更新数据,清空二级缓存user1.setName("Tom");userMapper1.updateUser(user1);sqlSession1.commit();// 第三次查询,从数据库中获取数据,并存储到二级缓存中User user3 = userMapper2.getUserById(1);System.out.println(user3);// 第四次查询,从二级缓存中获取数据User user4 = userMapper1.getUserById(1);System.out.println(user4);} finally {sqlSession1.close();sqlSession2.close();}}
}
在上面的示例代码中,首先读取了配置文件 mybatis-config.xml,然后通过 SqlSessionFactoryBuilder 将配置文件解析为 SqlSessionFactory 对象,最后通过 SqlSessionFactory 创建 SqlSession 对象。在 SqlSession 中,通过 getMapper 方法获取映射器接口的实例,在多个 SqlSession 中共享同一个二级缓存。在第一次查询时,会从数据库中获取数据,并将结果存储在二级缓存中。在第二次查询时,会直接从二级缓存中获取数据。在更新数据后,需要清空二级缓存,否则会出现数据不一致的情况。
要启用二级缓存,需要在配置文件 mybatis-config.xml 中进行配置。下面是一个简单的配置示例:
<configuration><settings><setting name="cacheEnabled" value="true"/></settings><typeAliases><typeAlias type="com.example.User" alias="User"/></typeAliases><mappers><mapper resource="com/example/UserMapper.xml"/></mappers><cache type="org.apache.ibatis.cache.impl.PerpetualCache"/>
</configuration>
在上面的配置文件中,首先开启了缓存功能,然后定义了一个类型别名 User,最后定义了一个缓存实现类 org.apache.ibatis.cache.impl.PerpetualCache。
3. 自定义缓存
除了使用 MyBatis 提供的缓存实现类以外,还可以自定义缓存实现类。下面是一个简单的自定义缓存实现类示例:
public class MyCache implements Cache {private final String id;private final Map<Object, Object> cache = new HashMap<>();public MyCache(String id) {this.id = id;}@Overridepublic String getId() {return id;}@Overridepublic void putObject(Object key, Object value) {cache.put(key, value);}@Overridepublic Object getObject(Object key) {return cache.get(key);}@Overridepublic Object removeObject(Object key) {return cache.remove(key);}@Overridepublic void clear() {cache.clear();}@Overridepublic int getSize() {return cache.size();}@Overridepublic ReadWriteLock getReadWriteLock() {return null;}
}
在上面的示例代码中,实现了 MyBatis 的 Cache 接口,使用了一个 HashMap 作为缓存实现。
要使用自定义缓存,需要在配置文件 mybatis-config.xml 中进行配置。下面是一个简单的配置示例:
<configuration><settings><setting name="cacheEnabled" value="true"/></settings><typeAliases><typeAlias type="com.example.User" alias="User"/></typeAliases><mappers><mapper resource="com/example/UserMapper.xml"/></mappers><cache type="com.example.MyCache"><property name="id" value="myCache"/></cache>
</configuration>
在上面的配置文件中,首先开启了缓存功能,然后定义了一个类型别名 User,最后定义了一个缓存实现类 com.example.MyCache,并指定了缓存实现类的 id。如果没有指定 id,则默认使用缓存实现类的类名作为 id。
结论
MyBatis 提供了多种方式来使用缓存,包括一级缓存和二级缓存。一级缓存是 SqlSession 的缓存,它默认是开启的。二级缓存是 SqlSessionFactory 的缓存,需要在配置文件中进行配置。除了使用 MyBatis 提供的缓存实现类以外,还可以自定义缓存实现类。在使用缓存时,需要注意清空缓存,否则会出现数据不一致的情况。