1. 为什么使用缓存?
用户减轻数据压力,提供数据库性能,提供了一级缓存和二级缓存;
一级缓存在操作数据库时需要构造SqlSession对象,在对象中有一个数据结构(HashMap)用户存储缓存数据;用户存储缓存数据,不同的SqlSession之间的缓存数据区域(HashMap)是互不影响的;
如果缓存中数据,就不用去数据库中请求数据,减轻数据库压力;
2. 一级缓存
mybaties默认支持一级缓存,不需要再配置文件中配置;
如果sqlSession去执行了commit操作(插入,更新,删除),情况SqlSession中的以及缓存,这样做的目的是为了让缓存中存储的是最新的信息,避免脏读;
比如:
@Test
public void testfindClientByName() throws Exception {
SqlSession os = sqlSessionFactory.openSession();
ClientMapper cp = os.getMapper(ClientMapper.class);
List<Client> clients = cp.findClientByName("ya");
System.out.println("第一次加载:"+clients);
Client c=new Client();
c.setBron_date(new Date());
c.setClient_certificate_no("客户信息");
c.setContact_mode("12121212");
c.setCreate_date(new Date());
c.setFamily_register_address("家庭住址");
c.setId(10009);
c.setNow_address("目前的家庭住址");
c.setUrgency_contact_mode("我去");
c.setUsername("萨达姆");
cp.insertIntoClient(c);
os.commit();
List<Client> clientss = cp.findClientByName("ya");
System.out.println("第二次加载:"+clientss);
os.close();
}
应用:
正式开放,将Mybatis和Spring进行整合开发,事务控制在service中,一个service方法中包括了很多mapper方法的调用。
开始执行service时,开启事务,创建SqlSession对象,方法结束SqlSession关闭,清空数据;
如果执行两个service调用查询相同的用户信息,不走一级缓存,因为session方法结束后,sqlsession就关闭了,缓存就清空了;
3. 二级缓存 (mybatis的二级缓存使用场景)
mybatis默认不开启二级缓存,所以首先开启二级缓存;
二级缓存与一级缓存的区别是:
二级缓存范围更大,多个sqlsession可以共享一个mapper的缓存区域。
二级缓存区域:
按namespace分,每一个mapper有一个缓存区域,两个mapper的namespace如果相同,这两个mapper执行的sql查询到的数据存在相同得二级缓存区域中;
实现步骤 :
(1) 开启二级缓存 : mybatis的二级缓存时mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还有在具体的mapper.xml中开启二级缓存;
SqlMapConfig.xml : <setting name="cacheEnabled" value="true" />
Mapper.xml : <cache />
参数 :flushInterval : 刷新间隔
size :缓存的大小,默认1024 ;
onlyRead :只读
(2) Pojo类实现序列化接口 :class User implements Serializable;
(3)测试
sqlSession.close();执行关闭操作,将sqlSession中的数据,写入缓存中;
sqlSession.commit(); 执行提交操作,将当前mapper下的缓存清空;(4) 参数:
在statement中 useCache="false" 禁用缓存;针对每次查询都需要最新的数据sql,要设置useCache=false;
<select id="findClientById" parameterType="int" resultType="cn.labelnet.pojo.Client" useCache="true">
select * from f_client where id=#{value}
</select>
在statement中 flushCacle="true" 刷新缓存,执行完commit操作,都需要刷新缓存,默认为true,不需要修改;
<select id="findClientById" parameterType="int" resultType="cn.labelnet.pojo.Client" flushCache="true">
select * from f_client where id=#{value}
</select>
与ehcache缓存整合 :
ehcache是一个分布式缓存框架;为了提高系统并发,性能,一般对系统进行分布式部署;不使用分布式缓存,缓存的数据在各个服务器单独存储;不方便系统开发,所以要使用分布式缓存对象缓存数据进行管理;
对缓存数据进行集中管理,使用分布式缓存框架,redis,memcached,ehcache;
方法 :
mybatis提供了一个cache接口,如果自己实现的缓存逻辑,实现Cache接口开发接口;mybatis和ehcache进行整合,只需要实现mybatis的接口即可;
mapper.xml中 开启二级缓存需要 <cache type="" /> , type制定的cache接口的实现类型,mybatis默认使用的是PerpetualCache,
要和ehcache整合,需要配置type为echcache实现的cache接口类型;
加入ehcache的配置文件;
应用场景:
对访问多的查询请求且用户查询结果实时性要求不高的,此时采用mybatis二级缓存技术降低数据库访问量,提供访问速度,业务场景:
耗时较高的统计分析 sql ,电话账单查询sql, 实现方法 通过设置刷新间隔时间,由mybatis每隔多长时间只需刷新缓存;
局限行:
二级缓存对细粒度的数据级别的缓存实现不好,比如:改商品价格,如果mapper.xml中有一个执行了commit操作,那么缓存就会被清空;