MyBatis中自定义二级缓存(使用Redis做缓存)

在MyBatis中,默认的二级缓存Cache实现是PerpetualCache,而通常,这种方式满足不了分布式集群的项目,这时候,我们可以借助一些第三方服务来做缓存,比如Redis,下面,来尝试下用Redis做MyBatis的二级缓存

开启二级缓存

MyBatis中自定义二级缓存(使用Redis做缓存)_第1张图片

实现自己的cache

package top.yuyufeng.learn.mybatis.cache;

import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

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

/**
 * @author yuyufeng
 * @date 2018/6/25.
 */
public class RedisCache implements Cache {

    private final String id;

    private static ValueOperations valueOs;

    private static RedisTemplate template;


    public static void setValueOs(ValueOperations valueOs) {
        RedisCache.valueOs = valueOs;
    }

    public static void setTemplate(RedisTemplate template) {
        RedisCache.template = template;
    }

    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();


    public RedisCache(String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
    }

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

    @Override
    public void putObject(Object key, Object value) {
        valueOs.set(key.toString(), value, 10, TimeUnit.MINUTES);
    }

    @Override
    public Object getObject(Object key) {
        return valueOs.get(key.toString());
    }

    @Override
    public Object removeObject(Object key) {
        valueOs.set(key.toString(), "", 0, TimeUnit.MINUTES);
        return key;
    }

    @Override
    public void clear() {
        template.getConnectionFactory().getConnection().flushDb();
    }

    @Override
    public int getSize() {
        return template.getConnectionFactory().getConnection().dbSize().intValue();
    }

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

这里使用到了Spring-data-redis

mapper文件中使用自定义的cache

        

调试

package top.yuyufeng.learn.mybatis.service;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import top.yuyufeng.learn.mybatis.cache.RedisCache;
import top.yuyufeng.learn.mybatis.entity.Blog;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author yuyufeng
 * @date 2018/6/13.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-redis.xml","classpath:spring/spring-service.xml"})
public class CacheTest {


    @Resource(name="redisTemplate")
    private ValueOperations valueOs;

    @Autowired
    private RedisTemplate template;

    @Autowired
    private BlogService blogService;

    @Before
    public void testBefore(){
        RedisCache.setTemplate(this.template);
        RedisCache.setValueOs(this.valueOs);
    }

    @Test
    public void selectAll() throws Exception {
        List list =  blogService.selectAll();
        for (Blog blog : list) {
            System.out.println(blog);
        }

        List list2 =  blogService.selectAll();
        for (Blog blog : list2) {
            System.out.println(blog);
        }
    }

}


Cache Hit Ratio [top.yuyufeng.learn.mybatis.mapper.BlogMapper]: 0.5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16073fa8]
Blog{blogId=1, blogTitle=‘什么是mybatis’, blogContent='MyBatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。
', createTime=Fri May 25 14:28:35 CST 2018}

可以看到,我查询了两次,命中率为0.5,缓存已经生效了

你可能感兴趣的:(Java,MyBatis源码阅读)