MyBatis的一级缓存、二级缓存演示以及讲解,序列化异常的处理
mybatis的缓存机制
缓存就是内存中的一个空间,通常用来提高查询效率
mybatis支持两种缓存技术:一级缓存和二级缓存,其中一级缓存默认开启,二级缓存默认关闭
一级缓存
(1)一级缓存默认开启
(2)是一种基于sqlsession的缓存,同一个sqlsession有效,不同的sqlsession无效
(3)同一个id,可以走缓存;不同id,即使查询的内容相同,也不会走缓存
//加载核心配置文件
inputstream is = resources.getresourceasstream("mybatis-cfg.xml");
//基于构建者创建工厂对象
sqlsessionfactory factory = new sqlsessionfactorybuilder().build(is);
//通过工厂创建sqlsession对象:测试一级缓存
//第一次查询
sqlsession sqlsession1 = factory.opensession();
list<user> list1 = sqlsession1.selectlist("selall1");
system.out.println(list1);
system.out.println("*************************");
//第二次查询
list<user> list2 = sqlsession1.selectlist("selall1");
system.out.println(list2);
sqlsession1.close();
//加载核心配置文件
inputstream is = resources.getresourceasstream("mybatis-cfg.xml");
//基于构建者创建工厂对象
sqlsessionfactory factory = new sqlsessionfactorybuilder().build(is);
//通过工厂创建sqlsession对象:测试一级缓存
sqlsession sqlsession1 = factory.opensession();
list<user> list1 = sqlsession1.selectlist("selall1");
system.out.println(list1);
system.out.println("***********不同id,即使内容相同,也不走缓存**************");
list<user> list2 = sqlsession1.selectlist("selall2");
system.out.println(list2);
sqlsession1.close();
//加载核心配置文件
inputstream is = resources.getresourceasstream("mybatis-cfg.xml");
//基于构建者创建工厂对象
sqlsessionfactory factory = new sqlsessionfactorybuilder().build(is);
//通过工厂创建sqlsession对象:测试一级缓存
sqlsession sqlsession1 = factory.opensession();
list<user> list1 = sqlsession1.selectlist("selall1");
system.out.println(list1);
// sqlsession1.close();
system.out.println("***********不是同一个sqlsession,不会走缓存**************");
sqlsession sqlsession2 = factory.opensession();
list<user> list2 = sqlsession2.selectlist("selall1");
// system.out.println(list2);
二级缓存
(1)二级缓存默认关闭
(2)是一种基于sqlsessionfactory的缓存,同一个工厂创建的sqlsession有效,不同工厂则无效
(3)需要使用时,应在指定的namespace下进行开启
(4)<cache>标签的属性
eviction:缓存清除策略,常用的有lru、fifo、soft、weak
flushinterval:刷新间隔,需要给定一个毫秒数,表示指定时间间隔时,会自动刷新缓存
size:设置大小,默认是1024
readonly:是否只读(不写入文件),默认是false,需要实体类实现序列化接口
type:用于自定义缓存机制,提供一个自定义类的全限定路径,自定义类需要实现cache接口
//加载核心配置文件
inputstream is = resources.getresourceasstream("mybatis-cfg.xml");
//基于构建者创建工厂对象
sqlsessionfactory factory = new sqlsessionfactorybuilder().build(is);
//通过工厂创建sqlsession对象:测试二级缓存
sqlsession sqlsession1 = factory.opensession();
list<user> list1 = sqlsession1.selectlist("selall1");
system.out.println(list1);
sqlsession1.close();
system.out.println("***********同一个工厂的sqlsession,会走缓存**************");
sqlsession sqlsession2 = factory.opensession();
list<user> list2 = sqlsession2.selectlist("selall1");
system.out.println(list2);
“cache hit ratio”中文意思是“缓存命中率”。
这是一个计算机术语,终端用户访问加速节点时,如果该节点有缓存住了要被访问的数据时就叫做命中,如果没有的话需要回原服务器取,就是没有命中。
序列化问题:
//加载核心配置文件
inputstream is = resources.getresourceasstream("mybatis-cfg.xml");
//基于构建者创建工厂对象
sqlsessionfactory factory = new sqlsessionfactorybuilder().build(is);
//通过工厂创建sqlsession对象:测试二级缓存
sqlsession sqlsession1 = factory.opensession();
list<user> list1 = sqlsession1.selectlist("selall1");
system.out.println(list1);
sqlsession1.close();
原因分析:
user实现类未实现序列化
为什么要实现序列化:
(1)缓存机制:将查询结果保存到内存中
(2)内存饱满,需要移出时,mybatis就会自动将内存中的内容进行移除,但是文件很重要,不能,此时就需要进行序列化,以文件的形式将内容从内存保存到硬盘上,一个内容保存成文件的读写,必须实现序列化。
解决方案:
一:user实体类实现序列化
二:在<cache>标签中添加readonly属性
表示:要求mybatis对缓存内容只读不写,当需要移除的时候,直接删除,不需要进行转存。