Mybatis- cache
1为什么使用cache 2mybatis cache 2.1一级缓存2.3二级缓存3一级缓存一级缓存出现故障的情况有四种。不同的SqlSessions对应不同的一级缓存。在两次查询中添加、删除和更改了相同的SqlSession。在两次查询期间,同一SQL会话已被手动清空。4二级缓存相关属性缓存相关设置
1为什么用缓存
缓存机制可以减轻数据库的压力,提高数据库的性能,具有高性能和高并发性。
2mybatis缓存
在MyBatis系统中默认定义了二级缓存、一级缓存和二级缓存。
2.1 一级缓存
默认情况下,仅打开一级缓存(SqlSession级缓存,也称为本地缓存),它只缓存一个会话中的数据。Mybatis一级缓存的执行过程:sql语句的第一次执行将从数据库中获取数据,数据存储在缓存中,该语句的第二次执行将从缓存中获取数据,无需添加、删除和修改操作,而无需查询数据库。
2.2 二级缓存
L2缓存基于命名空间级别,需要手动打开。当SqlSession关闭时,它存储的数据将被放入映射器命名空间的L2缓存中。
2.3 Cache
为了提高可扩展性。MyBatis定义了缓存接口缓存。您可以通过实现缓存接口来自定义L2缓存。
3 一级缓存
@测试
public void test2()引发IOException {
字符串资源=' my batis-config . XML ';
InputStream InputStream=resources . getresourceasstream(资源);
Sqlsessionfactory Sqlsessionfactory=new SqlsessionfactoryBuilder()。构建(InputStream);
尝试(SqL session SqL session=SqL sessionfactory . OpenSession()){ 0
教师映射器mapper1=sqlSession.getMapper(教师映射器. class);
教师教师1=mapper 1 . getternabyid(1);
system . out . println('=================');
教师教师2=mapper 1 . getternabyid(1);
System.out.println(教师1==教师2);
}
}
您可以看到MyBatis进行了一次数据库查询。
一级缓存失效的四种情况
不同的SqlSession对应不同的一级缓存
@测试
public void test2()引发IOException {
字符串资源=' my batis-config . XML ';
InputStream InputStream=resources . getresourceasstream(资源);
Sqlsessionfactory Sqlsessionfactory=new SqlsessionfactoryBuilder()。构建(InputStream);
尝试(SqL session SqL session=SqL sessionfactory . OpenSession()){ 0
教师映射器mapper1=sqlSession.getMapper(教师映射器. class);
教师教师1=mapper 1 . getternabyid(1);
system . out . println('=================');
sqlsesession sqlSession1=sqlsessionfactory . opensession();
教师映射器mapper2=sqlSession1.getMapper(教师映射器. class);
教师2
= mapper2.getTeacherById(1);
System.out.println(teacher1 == teacher2);
}
}
可以看到MyBatis进行了两次数据库查询
同一个SqlSession但是查询条件不同
@Test
public void test2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
TeacherMapper mapper1 = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher1 = mapper1.getTeacherById(1);
System.out.println("==============");
Teacher teacher2 = mapper1.getTeacherById(2);
System.out.println(teacher1 == teacher2);
}
}
可以看到MyBatis进行了两次数据库查询
同一个SqlSession两次查询期间执行了增删改操作
@Test
public void test2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
TeacherMapper mapper1 = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher1 = mapper1.getTeacherById(1);
System.out.println("==============");
Teacher teacher = new Teacher();
teacher.setId(1);
teacher.setTeaName("hhh");
mapper1.updateTeaSet(teacher);
Teacher teacher2 = mapper1.getTeacherById(1);
System.out.println(teacher1 == teacher2);
}
}
可以看到更新数据后缓存被清楚了。
同一个SqlSession两次查询期间手动清空了缓存
@Test
public void test2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
TeacherMapper mapper1 = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher1 = mapper1.getTeacherById(1);
System.out.println("==============");
sqlSession.clearCache();
Teacher teacher2 = mapper1.getTeacherById(1);
System.out.println(teacher1 == teacher2);
}
}
可以看到MyBatis进行了两次数据库查询
4 二级缓存
1)在MyBatis核心配置文件中开启二级缓存
!--mybatis-config.xml--
setting name="cacheEnabled" value="true"/
2)在映射文件上添加标签:,注意!!!实体类要可序列化,即实现Serializable接口
@Test
public void test2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
SqlSession sqlSession1 = sqlSessionFactory.openSession();
TeacherMapper mapper1 = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher1 = mapper1.getTeacherById(1);
System.out.println("teacher1 = " + teacher1);
System.out.println("==============");
sqlSession.close();
TeacherMapper mapper2 = sqlSession1.getMapper(TeacherMapper.class);
Teacher teacher2 = mapper2.getTeacherById(1);
System.out.println("teacher2 = " + teacher2);
}
}
缓存相关属性
1)缓存相关属性:缓存相关属性:
? LRU – 最近最少使用的:移除最长时间不被使用的对象。
? FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
? SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
? WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
? 默认的是 LRU。
2)flushInterval:刷新间隔,单位毫秒
? 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
3)size:引用数目,正整数
? 代表缓存最多可以存储多少个对象,太大容易导致内存溢出
4)readOnly:只读,true/false
? true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
? false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。
缓存有关设置
1)全局setting的cacheEnable:
配置二级缓存的开关。一级缓存一直是打开的。
2)select标签的useCache属性:
配置这个select是否使用二级缓存。一级缓存一直是使用的
3)sql标签的flushCache属性:
增删改默认flushCache=true。sql执行以后,会同时清空一级和二级缓存。查询默认flushCache=false。
4)sqlSession.clearCache():
只是用来清除一级缓存。
5)当在某一个作用域 (一级缓存Session/二级缓存Namespaces) 进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/107444.html