SpringBoot+Mybatis+redis实现二级缓存

对于查询比较多的项目可以考虑配置二级缓存,mybatis本身的二级缓存是缓存到本地,但是对于多个节点的项目来说,可能会出现数据不一致的问题,所以采用redis缓存,这样二级缓存的数据就可以缓存到内存,可实现多个节点项目的数据同步。

1、配置redis的连接

#redis
gmall.redis.host=172.16.1.250
gmall.redis.port=6379
gmall.redis.pass=Gworld2017
gmall.redis.photo.database=6

#最大分配的对象数
gmall.redis.maxActive=12000

#最大能够保持idel状态的对象数
gmall.redis.maxIdle=600

#当池内没有返回对象时,最大等待时间
gmall.redis.maxWait=2000

gmall.redis.timeout=5000

#当调用borrow Object方法时,是否进行有效性检查
gmall.redis.testOnBorrow=true

#当调用return Object方法时,是否进行有效性检查
gmall.redis.testOnReturn=true

gmall.redis.minIdle=5
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"
    default-lazy-init="false">
    <bean id="jedisConnFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
        primary="true">
        <property name="hostName" value="${gmall.redis.host}" />
        <property name="port" value="${gmall.redis.port}" />
        <property name="password" value="${gmall.redis.pass}" />
        <property name="timeout" value="${gmall.redis.timeout}" />
        <property name="database" value="${gmall.redis.photo.database}" />
    </bean>
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
        primary="true">
        <property name="connectionFactory" ref="jedisConnFactory" />
        <property name="exposeConnection" value="true" />
        <property name="keySerializer">
            <bean
                class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean
                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
        <property name="hashKeySerializer">
            <bean
                class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="hashValueSerializer">
            <bean
                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
    </bean>
</beans>

2、配置mybatis-config.xml文件

  

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
           <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

3、编写RedisCache实现Cache类

package com.gcard.gwmedia.cache;

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

import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import com.gcard.gwmedia.utils.SpringBeanFactoryUtils;

public class RedisCache implements Cache {

    Logger logger = LoggerFactory.getLogger(getClass());

    private final String FREFIX = "CACHE_";
    private final String id;

    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

    @SuppressWarnings("rawtypes")
    private RedisTemplate redisTemplate;

    private long cleanInterval;

    private long lastClear;

    public RedisCache(String id){
        if(id == null){
            throw new IllegalArgumentException("Cache instance require an ID");
        }
        this.id = id;
        this.cleanInterval = 1 * 60 * 60 * 1000;//一个小时
        this.lastClear = System.currentTimeMillis();
    }

    @SuppressWarnings({ "unchecked" })
    @Override
    public void clear() {
        lastClear = System.currentTimeMillis();
        String strKey = FREFIX + id.toString();
        getRedisTemplate().delete(strKey);
        logger.debug("Clear all the cached query result from redis");
    }

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

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Object getObject(Object key) {
        if(key != null){
            String strKey = FREFIX + id.toString();
            if(clearWhenStale(strKey)){
                return null;
            }
            RedisTemplate redisTemplate = getRedisTemplate();
            Object obj = redisTemplate.opsForHash().get(strKey, key.toString());
            logger.debug("Get cached query result from redis");
            if(obj != null){
                return obj;
            }else{
                return null;
            }
        }else{
            return null;
        }
    }

    @SuppressWarnings("rawtypes")
    private RedisTemplate getRedisTemplate() {
        if(redisTemplate == null){
            redisTemplate = (RedisTemplate) SpringBeanFactoryUtils.getBean("redisTemplate");
        }
        return redisTemplate;
    }
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public void putObject(Object key, Object value) {
        if (key != null) {
            String strKey = FREFIX + id.toString();
            clearWhenStale(strKey);
            RedisTemplate redisTemplate = getRedisTemplate();
            redisTemplate.opsForHash().put(strKey,key.toString(),value);
            logger.debug("Put query result to redis");
        }
    }
    @Override
    public ReadWriteLock getReadWriteLock() {
        return readWriteLock;
    }

    @Override
    public int getSize() {
        return 0;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Object removeObject(Object key) {
        if (key != null) {
            String strKey = FREFIX + id.toString();
            RedisTemplate redisTemplate = getRedisTemplate();
            redisTemplate.opsForHash().delete(strKey, key.toString());
            logger.debug("Remove cached query result from redis");
        }
        return null;
    }
    public boolean clearWhenStale(Object key){
        if(System.currentTimeMillis()-lastClear > cleanInterval){
            logger.info("clearWhenStale key={}", key);
            clear();
            return true;
        }
        return false;

    }
}

4、配置mapper.xml文件

在mapper.xml文件加入<cache/>

<cache type="com.gcard.gwmedia.cache.RedisCache"/>

5、Application启动类添加注解@EnableCaching

package com.gcard.gwmedia;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ImportResource;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@ImportResource(locations = {"classpath:/config/applicationContext.xml"})
@EnableAsync
@EnableCaching
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

原文地址:https://www.cnblogs.com/ouyanxia/p/9361599.html

时间: 2024-11-01 15:52:42

SpringBoot+Mybatis+redis实现二级缓存的相关文章

mybatis+redis实现二级缓存

在网上看了很多资料,发现例子都是千篇一律的相互复制.而且,使用的都是jedis的客户端..我这里使用的是redistemplate类实现. 缓存的原理..实现cache类接口,当哪个类需要缓存的时候,就直接将cache标签引入,并且制定我们的缓存类就可以了. 上代码: 1.引入spring-data-redis 1 <!-- redis服务 start--> 2 <dependency> 3 <groupId>org.springframework.data</g

springboot+mybatis+redis实现分布式缓存

大家都知道springboot项目都是微服务部署,A服务和B服务分开部署,那么它们如何更新或者获取共有模块的缓存数据,或者给A服务做分布式集群负载,如何确保A服务的所有集群都能同步公共模块的缓存数据,这些都涉及到分布式系统缓存的实现. 前面其实我已经介绍了springboot+mybatis+ehcache实现缓存数据,但是ehcache的设计并不适合做分布式缓存,所以今天用redis来实现分布式缓存. 原理什么的,我就不多说了,直接上代码. pom依赖 <dependency> <gr

SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 整体思路 pomxml中加入Maven依赖 引入applicationContextxml中引入redis配置 创建缓存实现类RedisCache 创建中间类RedisCacheTransfer完成RedisCachejedisConnectionFactory的静态注入 配置文件redisproperties mapper中加入MyBatis二级缓存 Mybatis全局配置 打印Sql日志方便测试 测试代码 项目环境: 在

SpringMVC +Spring + MyBatis + Mysql + Redis(作为二级缓存) 配置

转载:http://blog.csdn.net/xiadi934/article/details/50786293 项目环境: 在SpringMVC +Spring + MyBatis + MySQL.Redis部署在Linux虚拟机. 1.整体思路 参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅) 使用Spring管理Redis连接池 模仿EhcacheCache,实现RedisCache 2.pom.xml中加入Maven依赖 1 <!-- spring-re

mybatis整合Redis实现二级缓存

Mybatis整合ehcache实现二级缓存 导入相关依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!--mybatis与ehcache整合--

redis实现二级缓存

缓存的作用就是降低数据库的使用率,来减轻数据库的负担.我们平常的操作一般都是查>改,所以数据库的有些查操作是重复的,如果一直使用数据库就会有负担.Mybatis也会做缓存,也会有一级缓存和二级缓存: 一级缓存:是SqlSession级别的缓存,使用HashMap数据结构来用于存储缓存数据的 二级缓存:是mapper级别的缓存,其作用域是mapper的同一个namespace,不同的SqlSession执行两次相同namespace下的sql语句,并且传递的参数相同,返回的结果也相同时,第一次执行

【MyBatis学习13】MyBatis中的二级缓存

1. 二级缓存的原理 前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的.为了更加清楚的描述二级缓存,先来看一个示意图: 从图中可以看出: sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到该UserMapper的二级缓存中. 如果SqlSession3去执行相同 mapper下sql,执行commit提交,则会清空该UserMapper下二级缓

Mybatis学习笔记-二级缓存

~ 缓存是提供应用系统性能的重要手段,前面已经介绍过Mybatis是一级缓存,与一级缓存不同的是,二级缓存的作用范围扩大到了应用级别,并且可以比一级缓存更细粒度的对二级缓存的应用进行配置.下面就详细叙述一下Mybatis的二级缓存实现. 二级缓存的工作流程 不多说,先上图,图解是攻城狮最好的朋友^_^- 前面在叙述一级缓存的时候已经说过,一级缓存是一块放在Executor中的map内存块.试想一下,如果二级缓存也是Executor中的内存块可以可以呢?-- 当然不可以!为啥?因为二级缓存要支持细

MySQL与Redis实现二级缓存

redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储 Redis支持数据的备份,即master-slave模式的数据备份 优势 性能极高 - Redis能读的速度是110