一、mybatis 查询缓存:


1.mybatis 提供查询一级缓存和二级缓存,减轻数据库的压力,提高性能。


 


 


2.一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。


一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

 


3.二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。


 


  二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。


如果缓存中有数据就不用从数据库中获取,大大提高系统性能。


 


4.二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。


pojo类实现序列化接口是为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定在内存有可能是硬盘或者远程服务器。


二、mybatis整合redis


mybatis只提供了一个cache的接口,如果要实现缓存的逻辑,自己实现cache接口即可。

1.导入jedis.jar
2.配置spring-context-redis.xml
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="300" /> <!-- 最大能够保持idel状态的对象数  -->
        <property name="maxTotal" value="60000" /> <!-- 最大分配的对象数 -->
        <property name="testOnBorrow" value="true" /> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
    </bean>
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1" value="${redis.host}" />
        <constructor-arg index="2" value="${redis.port}" type="int" />
        <!-- <constructor-arg index="3" value="${redis.timeout}" type="int" />
        <constructor-arg index="4" value="${redis.password}"/>
        <constructor-arg index="5" value="${redis.database}" type="int" />
        <constructor-arg index="6" value="${redis.clientName}"/> -->
    </bean>
mybatis-config.xml
        <!-- 使全局的映射器启用或禁用缓存。 -->
        <setting name="cacheEnabled" value="true"/>



 


三、代码实现:


 


1.把model序列化


public class UserModel implements Serializable{
 
 
    private static final long serialVersionUID = 4673186153813605228L;
 
 
}


2.对于mapper.xml开二级缓存


<!--  开启二级缓存--> 

 
    <cache eviction="LRU" type="com.lsqz.util.redis.RedisCache" />


总结: 在UserMapper.xml中开启二缓存,UserMapper.xml下的sql执行完成会存储到它的缓存区域(HashMap)。


3.在对应的statement 上开启缓存,默认是关闭的    


<select id="selectByLoginname" resultType="com.**.Model" useCache="true">


4. mybatis刷新缓存(就是清空缓存)


在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。

 设置statement配置中的flushCache='true' 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。


如下:


<insertid='insertUser' parameterType='com.**.User' 
 flushCache='true'>


总结:一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存默认情况下为true,我们不用去设置它,这样可以避免数据库脏读。