mybatis整合redis作为二级缓存

1、实现 mybatis 的二级缓存,一般来说有如下两种方式:

1) 采用 mybatis 内置的 cache 机制。
2) 采用三方 cache 框架, 比如ehcache, oscache 等等.

2、导入依赖:

   
    2.9.0
    1.7.1.RELEASE
    
    
      redis.clients
      jedis
      ${redis.version}
    
    
      org.springframework.data
      spring-data-redis
      ${redis.spring.version}
    

3、 log4j2配置:Log4j2 + Slf4j

上一篇博客有:https://mp.csdn.net/mdeditor/85159453#

4、jackson依赖:


    2.9.3 


    
      com.fasterxml.jackson.core
      jackson-databind
      ${jackson.version}
    
    
      com.fasterxml.jackson.core
      jackson-core
      ${jackson.version}
    
    
      com.fasterxml.jackson.core
      jackson-annotations
      ${jackson.version}
    

5、spring + redis 集成实现缓存功能(与mybatis无关)

5-1: 添加两个redis的配置文件,并将redis.properties和applicationContext-redis.xmll配置到applicationContext.xml文件中

redis.properties文件放到Resources目录下

redis.hostName=192.xxx.xxx.xx  //ip地址
redis.port=6379  //redsi端口号
redis.password=xxxxx  //密码
redis.timeout=10000
redis.maxIdle=300
redis.maxTotal=1000
redis.maxWaitMillis=1000
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=1024
redis.timeBetweenEvictionRunsMillis=30000
redis.testOnBorrow=true
redis.testWhileIdle=true

applicationContext-redis.xml文件



    
    

    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
            
        
        
            
        
        
            
        
        
            
        
        
        
    

    
    
        
    

注:

spring中引入第二个属性文件会出现“找不到某个配置项”错误,这是因为spring只允许有一个    

        
  

  
  

注2:通过import标签将spring-redis.xml导入到applicationContext.xml文件中

       
       
applicationContext.xml文件中:

mybatis整合redis作为二级缓存_第1张图片

6、 将redis缓存引入到mybatis中

6-1: 创建mybatis的自定义缓存类“RedisCache”,必须实现org.apache.ibatis.cache.Cache接口

RedisCache.java:

package com.zking.ssm.redis;


import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class RedisCache implements Cache //实现类
{
    private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);

    private static RedisTemplate redisTemplate;

    private final String id;

    /**
     * The {@code ReadWriteLock}.
     */
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    @Override
    public ReadWriteLock getReadWriteLock()
    {
        return this.readWriteLock;
    }

    public static void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisCache.redisTemplate = redisTemplate;
    }

    public RedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        logger.debug("MybatisRedisCache:id=" + id);
        this.id = id;
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
        try{
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>putObject: key="+key+",value="+value);
            if(null!=value)
                redisTemplate.opsForValue().set(key.toString(),value,2, TimeUnit.DAYS);
        }catch (Exception e){
            e.printStackTrace();
            logger.error("redis保存数据异常!");
        }
    }

    @Override
    public Object getObject(Object key) {
        try{
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>getObject: key="+key);
            if(null!=key)
                return redisTemplate.opsForValue().get(key.toString());
        }catch (Exception e){
            e.printStackTrace();
            logger.error("redis获取数据异常!");
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        try{
            if(null!=key)
                return redisTemplate.expire(key.toString(),1,TimeUnit.DAYS);
        }catch (Exception e){
            e.printStackTrace();
            logger.error("redis获取数据异常!");
        }
        return null;
    }

    @Override
    public void clear() {
        Long size=redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {
                Long size = redisConnection.dbSize();
                //连接清除数据
                redisConnection.flushDb();
                redisConnection.flushAll();
                return size;
            }
        });
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>clear: 清除了" + size + "个对象");
    }

    @Override
    public int getSize() {
        Long size = redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                return connection.dbSize();
            }
        });
        return size.intValue();
    }
}

6-2:静态注入中间类“RedisCacheTransfer”,解决RedisCache中RedisTemplate的静态注入,从而使MyBatis实现第三方缓存 RedisCacheTransfer.java:
package com.zking.ssm.book.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

public class RedisCacheTransfer {
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisCache.setRedisTemplate(redisTemplate);
    }
}

6-3:spring与mybatis整合文件中开发二级缓存
6-4: 在XxxMapper.xml中添加自定义cache功能,示例:
  

注:

type:指定redis的二级缓存类的全路径名
eviction:二级缓存算法(FIFO/LRU/SOFT/WEAK)
flushInterval:刷新间隔,间隔多长时间清空缓存,被动触发非定时器轮询
size:缓存大小。每个缓存可以存储 1024 个列表或对象的引用
readOnly:缓存将作为“读/写”缓存,意味着获取的对象不是共享的且对调用者是安全的。不会有其它的调用者或线程潜在修改。
 

注意: pom对properties文件的加载!!!

mybatis整合redis作为二级缓存_第2张图片

注意点:

spring上下文,不允许两处及以上的文件注册,需要使用多文件注册的方法
pom.xml中记得将redis.properties文件给包含进去
spring-context.xml

附加:

MyBatis内置的二级缓存算法
Mybatis的所有Cache算法都是基于装饰器模式对PerpetualCache扩展增加功能。
1)

FIFO:先入先出,基于LinkedList实现;

2)LRU:最近最少使用,基于LinkedHashMap实现,在put的时候,自动移除最少使用缓存对象;
3)

SOFT:对Cache的value进行SoftReference包装;当缓存对象是Soft reference可达时,gc会向系统申请更多内存,而不是直接回收它,当内存不足的时候才回收它;

4)WEAK:对Cache的value进行WeakReference包装;WeakReference不会强制对象保存在内存中。它拥有比较短暂的生命周期,允许你使用垃圾回收器的能力去权衡一个对象的可达性。在垃圾回收器扫描它所管辖的内存区域过程中,一旦gc发现对象是weakReference可达,就会把它放到ReferenceQueue中,等下次gc时回收它。

你可能感兴趣的:(Redis)