Redis之二级缓存(基于Maven Web项目java实现)

1.spring+redis集成配置

        1.1、导入依赖

<properties>
    <spring-data-redis.version>1.7.1.RELEASE</spring-data-redis.version>
    <jedis.version>2.9.0</jedis.version>
    <jackson.version>2.9.3</jackson.version>
    ...
</properties>

<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>${jedis.version}</version>
        <exclusions>
            <exclusion>
                <artifactId>commons-pool2</artifactId>
                <groupId>org.apache.commons</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>${spring-data-redis.version}</version>
    </dependency>
    <!-- jackson -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
        <exclusions>
            <exclusion>
                <artifactId>jackson-annotations</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson.version}</version>
    </dependency>
	...
</dependencies>

        1.2、在src/main/resources下面创建spring-redis.xml文件

        1.3、在相同目录下创建redis.properties文件(文件内容如下:)

       

#ip地址
redis.hostName=127.0.0.1
#端口号
redis.port=6379
#如果有密码
redis.password=
#客户端超时时间单位是毫秒 默认是2000
redis.timeout=10000

#redis缓存数据过期时间单位秒
redis.expiration=3600

##################### redis连接池配置 ###########################################
#最大空闲数
redis.maxIdle=300
#连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
#redis.maxActive=600
#控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
redis.maxTotal=1000
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWaitMillis=1000
#连接的最小空闲时间 默认1800000毫秒(30分钟)
redis.minEvictableIdleTimeMillis=300000
#每次释放连接的最大数目,默认3
redis.numTestsPerEvictionRun=1024
#逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
redis.timeBetweenEvictionRunsMillis=30000
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
redis.testOnBorrow=true
#在空闲时检查有效性, 默认false
redis.testWhileIdle=true

#redis集群配置
#redis.sentinel.host1=172.20.1.230
#redis.sentinel.port1=26379

#redis.sentinel.host2=172.20.1.231
#redis.sentinel.port2=26379

#redis.sentinel.host3=172.20.1.232
#redis.sentinel.port3=26379

        1.4、编写相关内容如下(注:文中第一步,不需要配置,需要在spring.xml文件中配置多配置文件.properties文件引入方式: 代码在1.4.1中

<?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:contet="http://www.springframework.org/schema/context"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
    <!-- 1.导入redis配置文件 -->
<!--    <contet:property-placeholder location="redis.properties"/>-->
    <!-- 2.创建redis数据库连接池 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!--最大空闲数-->
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <!--连接池的最大数据库连接数  -->
        <property name="maxTotal" value="${redis.maxTotal}"/>
        <!--最大建立连接等待时间-->
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
        <!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->
        <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/>
        <!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->
        <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/>
        <!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->
        <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/>
        <!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        <!--在空闲时检查有效性, 默认false  -->
        <property name="testWhileIdle" value="${redis.testWhileIdle}"/>
    </bean>
    <!-- 3.创建redis连接工厂类 -->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          destroy-method="destroy">
        <property name="poolConfig" ref="poolConfig"/>
        <!--IP地址 -->
        <property name="hostName" value="${redis.hostName}"/>
        <!--端口号  -->
        <property name="port" value="${redis.port}"/>
        <!--如果Redis设置有密码  -->
        <property name="password" value="${redis.password}"/>
        <!--客户端超时时间单位是毫秒  -->
        <property name="timeout" value="${redis.timeout}"/>
    </bean>
    <!-- 4.创建redistemplate模板类 -->
    <!-- redis操作模板,使用该对象可以操作redis  -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <!--redis是key-value-->
        <property name="connectionFactory" ref="connectionFactory"/>
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <!--开启事务  -->
        <property name="enableTransactionSupport" value="false"/>
    </bean>


    <!--  5.配置Redis缓存管理器 -->
  <!--  <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate" />
        <!--redis缓存数据过期时间单位秒-->
       <!-- <property name="defaultExpiration" value="${redis.expiration}" />
        <!--是否使用缓存前缀-->
     <!--   <property name="usePrefix" value="true"/>
        <!--设置缓存前缀-->
      <!--  <property name="cachePrefix">
            <bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix">
                <constructor-arg index="0" value="-cache-"/>
            </bean>
        </property>
    </bean>  -->

    <!-- 6.配置自定义Key生成器CacheKeyGenerator -->
    <!--  <bean id="cacheKeyGenerator" class="com.zking.ssm.util.CacheKeyGenerator"/> -->

    <!--7.启用注解式缓存-->
   <!-- <cache:annotation-driven cache-manager="redisCacheManager" key-generator="cacheKeyGenerator"/>  -->
</beans>

        1.4.1、引入外部多文件方式

<!--1. 引入外部多文件方式 -->
<bean id="propertyConfigurer"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="ignoreResourceNotFound" value="true" />
    <property name="locations">
    <list>
        <value>classpath:jdbc.properties</value>
        <value>classpath:redis.properties</value>
    </list>
    </property>
</bean>

       1.5、前言:在spring-mvc中配置对应json对象转换器

    <!--配置JSON对象接收-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
                <!-- json转换器 -->
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

        1.5、案例操作(注:能直接加入对象的原因是在Spring-mvc.xml文件中配置json转换器,而且操作在测试类中进行

    //导入dao层接口类
    @Autowired
    private IBookMapper bookMapper;

    @Autowired
    private RedisTemplate<String,Object> template;


     @Test
    public void test2(){
        //mybati相关操作
         Book book = bookMapper.queryBook(1);
        //添加到redis缓存中
        template.opsForValue().set("book",book); //templae的配置中还有opsForSet、opsForHash、opsForZset、opsForList相关操作
        //获取redis中的book
        Book book = (Book) template.opsForValue().get("book");
    }

2、启用spring注解式声明

        2.1、解注1.4中5、6、7步的代码

        2.2、在util下创建CacheKeyGenerator类(这是在spring-redis.xml中的第六步引入的全局key生成类

2.3、编写如下代码

package com.zking.ssm.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.util.ClassUtils;

import java.lang.reflect.Array;
import java.lang.reflect.Method;

@Slf4j
public class CacheKeyGenerator implements KeyGenerator {
    // custom cache key
    public static final int NO_PARAM_KEY = 0;
    public static final int NULL_PARAM_KEY = 53;

    @Override
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder key = new StringBuilder();
        key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
        if (params.length == 0) {
            key.append(NO_PARAM_KEY);
        } else {
            int count = 0;
            for (Object param : params) {
                if (0 != count) {//参数之间用,进行分隔
                    key.append(',');
                }
                if (param == null) {
                    key.append(NULL_PARAM_KEY);
                } else if (ClassUtils.isPrimitiveArray(param.getClass())) {
                    int length = Array.getLength(param);
                    for (int i = 0; i < length; i++) {
                        key.append(Array.get(param, i));
                        key.append(',');
                    }
                } else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) {
                    key.append(param);
                } else {//Java一定要重写hashCode和eqauls
                    key.append(param.hashCode());
                }
                count++;
            }
        }

        String finalKey = key.toString();
        log.debug("using cache key={}", finalKey);
        return finalKey;
    }
}

3、缓存注解

注:各注解作用区域都又说明,请按照文档要求明确注解位置

        3.1.@CacheConfig

@CacheConfig是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager和CacheResolver。

参数说明
value缓存位置的一段名称,不能为空
key缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL

        3.2.@Cacheable

@Cacheable配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果,本次方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找。

参数说明
value缓存位置的一段名称,不能为空
key缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
keyGenerator指定key的生成策略
condition触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL

示例:

@Cacheable(value="selectByPrimaryKey",key="'selectOne-'+#bookId",condition="#bookId>90")
@Override
public Book selectByPrimaryKey(Integer bookId) {
    Book book = bookMapper.selectByPrimaryKey(bookId);
    return book;
}

        3.3.@CachePut

@CachePut类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果。

参数说明
value缓存的名称,在 spring 配置文件中定义,必须指定至少一个
key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
condition缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

示例:

@CachePut(value="selectByPrimaryKey",key="'selectOne-'+#bookId",condition="#bookId>90")
@Override
public Book selectByPrimaryKey(Integer bookId) {
    Book book = bookMapper.selectByPrimaryKey(bookId);
    return book;
}

        3.4.@CacheEvict

@CacheEvict用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)。

参数说明
value缓存位置的一段名称,不能为空
key缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
condition触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL
allEntriestrue表示清除value中的全部缓存,默认为false

示例一:清空指定缓存

@CacheEvict(value="selectByPrimaryKey")
@Override
public void delete(Integer bookId) {
   System.out.println("被删除了...");
}

示例二:清空所有缓存

@CacheEvict(value="selectByPrimaryKey",allEntries = true)
@Override
public void delete(Integer bookId) {
   System.out.println("被删除了...");
}

  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值