MyBatis缓存机制详解(一级缓存,二级缓存)
一,什么是缓存
缓存就是数据交换的缓存区(称作Cache),是存储数据(使用频繁的数据)的临时地方。当用程序查询数据时,首先会在缓存中寻找,如果找到了就直接返回。如果找不到,则会去数据库中查找。缓存的本质就是用空间换时间,牺牲数据的实时性,以服务器内存中的数据暂时代替从数据库中读取的最新数据,减少程序与数据库之间的IO,减轻服务器压力,减少网络延迟,加快页面打开速度。
二,MyBatis中的缓存
MyBatis支持声明式数据缓存( declarative data caching )。当一条SQL语句被标记为“可缓存”后,首次执行它时从数据库中获取的所有数据会被存储在一段高速缓存中,今后执行这条语句时就会从高速缓存中读取结果,而不是再次命中数据库。
MyBatis提供了默认下基于Java HashMap的缓存实现,以及用于与OSCache,Ehcache,Hazelcast和Mecached连接的默认连接器。MyBatis还提供API供其他缓存实现使用。
注意了!
上面内容的重点:MyBatis执行SQL语句之后,这条语句从数据库中获取的数据就会被缓存,后面再需要用到这些数据的时候,会直接从缓存中拿结果,而不是再次执行SQL。
MyBatis提供了两种缓存(一级缓存和二级缓存),接下来将对这两种缓存进行详细的介绍。
MyBatis一级缓存
默认情况下,MyBatis只启用了一级缓存(也称为本地缓存),一级缓存的作用域是SqlSession。它仅仅对一个会话中的数据进行缓存。
接下来我们分情况对一级缓存进行测试说明
①同个SqlSession进行两次相同查询
public class Test {
@org.junit.Test
public void test1() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session1 = sqlSessionFactory.openSession();
try {
User user1 = session1.selectOne("com.ljt.mybatis.dao.UserDao.getUserById", 3);
System.out.println(user1);
User user2 = session1.selectOne("com.ljt.mybatis.dao.UserDao.getUserById", 3);
System.out.println(user2);
System.out.println(user1 == user2);
} finally {
session1.commit();
session1.close();
}
}
}
日志打印结果:
第一次查询,执行了SQL语句,然后返回了查询结果,第二次查询并没有执行SQL语句,直接从缓存中获取到了结果;通过"=="运算符对user1和user2进行比较,返回true,发现user1和user2实际上指向的是同一个对象。
结论:同个SqlSession进行两次相同查询,MyBatis只进行一次数据库查询,第二次会直接从缓存中获取查询结果。
②同个SqlSession进行两次不同的查询。