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;
}
@Override
public String getId() {
return id;
}
@Override
public void putObject(Object key, Object value) {
cache.put(key, value);
}
@Override
public Object getObject(Object key) {
return cache.get(key);
}
@Override
public Object removeObject(Object key) {
return cache.remove(key);
}
@Override
public void clear() {
cache.clear();
}
@Override
public int getSize() {
return cache.size();
}
@Override
public 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 提供的缓存实现类以外,还可以自定义缓存实现类。在使用缓存时,需要注意清空缓存,否则会出现数据不一致的情况。