redis 依赖的jar包:
commons-pool2-2.5.0.jar
jedis-2.9.0.jar
spring-data-redis-1.6.2.RELEASE.jar
我是配合spring4.2实现的缓存操作:我这里实现redis唯一缓存注解实现,redis的配置加载spring里进行配置;配置内容:
spring配置:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!-- 配置自动识别注解 -->
<context:component-scan base-package="com.dome" >
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- <task:annotation-driven/> -->
<task:annotation-driven executor="asyncExecutor" scheduler="scheduler"/>
<task:executor id="asyncExecutor" pool-size="100-1000" queue-capacity="10000" rejection-policy="CALLER_RUNS"/>
<task:scheduler id="scheduler" pool-size="100" />
<!--加载数据库配置文件-->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- 加载数据库连接设置 -->
<value>classpath:config/database.properties</value>
<!-- <value>classpath:config/database.properties</value> -->
<!-- 加载redis连接设置 -->
<value>classpath:config/redis.properties</value>
</list>
</property>
</bean>
<!-- 数据中心连接 就是数据库连接设置 我是封装在一个文件里的 暂不提供-->
<import resource="datasource-sqlserver.xml" />
<!-- redis 缓存设置 redis 连接设置 封装在一个文件里 -->
<import resource="redisConfig.xml" />
<!-- 解决使用@ResponseBody 的中文乱码。 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<!-- JSON解析对象 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" >
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
<!-- 日期格式转换 -->
<property name="webBindingInitializer">
<bean class="com.dome.filter.DateConverterFilter" />
</property>
</bean>
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<!-- 验证码 kaptcha-->
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg>
<props>
<prop key="kaptcha.border">yes</prop>
<prop key="kaptcha.border.color">105,179,90</prop>
<prop key="kaptcha.textproducer.font.color">blue</prop>
<prop key="kaptcha.image.width">125</prop>
<prop key="kaptcha.image.height">45</prop>
<prop key="kaptcha.textproducer.font.size">45</prop>
<prop key="kaptcha.session.key">kaptchaRemote</prop>
<prop key="kaptcha.textproducer.char.length">4</prop>
<prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!-- * 优势:简单直观,效率高
* 劣势:系统中只能用Redis一种缓存了
使用redis内置CacheManager-->
<!-- jedis 配置 连接池配置-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- #最大空闲数 -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- #控制一个pool可分配多少个jedis实例 -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- redis服务器中心 连接redis基本信息-->
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="poolConfig" ref="poolConfig" />
<property name="port" value="${redis.port}" />
<property name="hostName" value="${redis.host}" />
<property name="password" value="${redis.password}" />
<!-- #客户端超时时间单位是毫秒 默认是2000 -->
<property name="timeout" value="${redis.timeout}"></property>
<!-- #选择redis第几个库 -->
<property name="database" value="${redis.database}" />
</bean>
<!-- redis template,被后面的RedisCacheManager或RedisCache引用 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"/>
<!--value,key值 的序列化 Redis缓存对象乱码处理-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="stringSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
</bean>
<!-- 配置缓存 -->
<!-- 允许基于注解的使用,proxy-target-class默认为false,即使用JDK Proxy机制,如设置为true则基于CGLIB动态生成代理类 -->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<property name="usePrefix" value="true" />
<property name="defaultExpiration" value="3600"/>
<constructor-arg ref="redisTemplate" />
<!-- 下面列表每一项对应一个Cache对象的名字,也就是@Cacheable的value指向的值-->
<constructor-arg>
<list>
<value>default</value><!-- 缓存名,在注解中用value引用 -->
<value>user</value><!-- 可以配置多个缓存,以实现不同的超时策略 -->
<value>test</value>
</list>
</constructor-arg>
<!-- 用expires属性分别配置其超时时间,缺省则使用defaultExpiration,单位均为秒 -->
<property name="expires">
<map>
<entry key="user" value="600"/><!-- value="0"此缓存永不超时,即使Redis重启也不会丢失哟 -->
<entry key="test" value="600"/><!-- value="0"此缓存永不超时,即使Redis重启也不会丢失哟 -->
</map>
</property>
</bean>
</beans>
伪代码验证 按自己需求添加代码 (谨做参考):
伪代码:
package com.dome.service.user.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.dome.bean.user.User;
import com.dome.dao.source2.user.UserMapper;
import com.dome.service.user.UserService;
@Service
public class UserServiceImpl implements UserService {
/**
* userService
*
* 缓存机制说明:所有的查询结果都放进了缓存,也就是把MySQL查询的结果放到了redis中去,
* 然后第二次发起该条查询时就可以从redis中去读取查询的结果,从而不与MySQL交互,从而达到优化的效果,
* redis的查询速度之于MySQL的查询速度相当于 内存读写速度/硬盘读写速度
* @Cacheable("a")注解的意义就是把该方法的查询结果放到redis中去,
* 下一次再发起查询就去redis中去取,存在redis中的数据的key就是a;
* @CacheEvict(value={"a","b"},allEntries=true)
* 的意思就是执行该方法后要清除redis中key名称为a,b的数据;
* key 命名规范
* 当前被调用的方法使用的Cache:#root.caches[0].name
* 当前方法名#root.methodName 当前方法#root.method.name 当前被调用的对象#root.target 当前被调用的对象的 * class#root.targetClass
* 当前方法参数组成的数组#root.args[0] 当前被调用的方法使用的Cache#root.caches[0].name */
@Autowired
private UserMapper userMapper;
@Cacheable(value="user",key="'test'")
@Override
public User selectOne(String id) {
return userMapper.selectOne(id);
}
//allEntries=true redis自带缓存 不能生效 要报错 我这里没有添加
//去除缓存
@CacheEvict(value="user",key="'test'")
@Override
public Boolean updateOne(String id) {
try {
User u = userMapper.selectOne(id);
u.setId("1");
u.setUsername("qwer1234");
userMapper.updateByPrimaryKeySelective(u);
return true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
缺点:
缓存的value,key都在service层的注解里 不便于后期维护
redis缓存容易出现更新和查询缓存同步执行 出现脏数据的问题
项目中不建议这样使用 怎么写后面会有介绍---------我们先了解 在优化
这样的独占redis 的缓存 本人觉得难用 项目中 不建议这样实现 只用redis缓存配置 其他缓存需要关闭 如mybatis自带的缓存 且需添加<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
commons-pool2-2.5.0.jar
jedis-2.9.0.jar
spring-data-redis-1.6.2.RELEASE.jar
我是配合spring4.2实现的缓存操作:我这里实现redis唯一缓存注解实现,redis的配置加载spring里进行配置;配置内容:
spring配置:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!-- 配置自动识别注解 -->
<context:component-scan base-package="com.dome" >
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- <task:annotation-driven/> -->
<task:annotation-driven executor="asyncExecutor" scheduler="scheduler"/>
<task:executor id="asyncExecutor" pool-size="100-1000" queue-capacity="10000" rejection-policy="CALLER_RUNS"/>
<task:scheduler id="scheduler" pool-size="100" />
<!--加载数据库配置文件-->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- 加载数据库连接设置 -->
<value>classpath:config/database.properties</value>
<!-- <value>classpath:config/database.properties</value> -->
<!-- 加载redis连接设置 -->
<value>classpath:config/redis.properties</value>
</list>
</property>
</bean>
<!-- 数据中心连接 就是数据库连接设置 我是封装在一个文件里的 暂不提供-->
<import resource="datasource-sqlserver.xml" />
<!-- redis 缓存设置 redis 连接设置 封装在一个文件里 -->
<import resource="redisConfig.xml" />
<!-- 解决使用@ResponseBody 的中文乱码。 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<!-- JSON解析对象 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" >
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
<!-- 日期格式转换 -->
<property name="webBindingInitializer">
<bean class="com.dome.filter.DateConverterFilter" />
</property>
</bean>
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<!-- 验证码 kaptcha-->
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg>
<props>
<prop key="kaptcha.border">yes</prop>
<prop key="kaptcha.border.color">105,179,90</prop>
<prop key="kaptcha.textproducer.font.color">blue</prop>
<prop key="kaptcha.image.width">125</prop>
<prop key="kaptcha.image.height">45</prop>
<prop key="kaptcha.textproducer.font.size">45</prop>
<prop key="kaptcha.session.key">kaptchaRemote</prop>
<prop key="kaptcha.textproducer.char.length">4</prop>
<prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>
</beans>
mybatisConfig.xml:redis 缓存配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!-- * 优势:简单直观,效率高
* 劣势:系统中只能用Redis一种缓存了
使用redis内置CacheManager-->
<!-- jedis 配置 连接池配置-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- #最大空闲数 -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- #控制一个pool可分配多少个jedis实例 -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- redis服务器中心 连接redis基本信息-->
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="poolConfig" ref="poolConfig" />
<property name="port" value="${redis.port}" />
<property name="hostName" value="${redis.host}" />
<property name="password" value="${redis.password}" />
<!-- #客户端超时时间单位是毫秒 默认是2000 -->
<property name="timeout" value="${redis.timeout}"></property>
<!-- #选择redis第几个库 -->
<property name="database" value="${redis.database}" />
</bean>
<!-- redis template,被后面的RedisCacheManager或RedisCache引用 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"/>
<!--value,key值 的序列化 Redis缓存对象乱码处理-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="stringSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
</bean>
<!-- 配置缓存 -->
<!-- 允许基于注解的使用,proxy-target-class默认为false,即使用JDK Proxy机制,如设置为true则基于CGLIB动态生成代理类 -->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<property name="usePrefix" value="true" />
<property name="defaultExpiration" value="3600"/>
<constructor-arg ref="redisTemplate" />
<!-- 下面列表每一项对应一个Cache对象的名字,也就是@Cacheable的value指向的值-->
<constructor-arg>
<list>
<value>default</value><!-- 缓存名,在注解中用value引用 -->
<value>user</value><!-- 可以配置多个缓存,以实现不同的超时策略 -->
<value>test</value>
</list>
</constructor-arg>
<!-- 用expires属性分别配置其超时时间,缺省则使用defaultExpiration,单位均为秒 -->
<property name="expires">
<map>
<entry key="user" value="600"/><!-- value="0"此缓存永不超时,即使Redis重启也不会丢失哟 -->
<entry key="test" value="600"/><!-- value="0"此缓存永不超时,即使Redis重启也不会丢失哟 -->
</map>
</property>
</bean>
</beans>
伪代码验证 按自己需求添加代码 (谨做参考):
伪代码:
package com.dome.service.user.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.dome.bean.user.User;
import com.dome.dao.source2.user.UserMapper;
import com.dome.service.user.UserService;
@Service
public class UserServiceImpl implements UserService {
/**
* userService
*
* 缓存机制说明:所有的查询结果都放进了缓存,也就是把MySQL查询的结果放到了redis中去,
* 然后第二次发起该条查询时就可以从redis中去读取查询的结果,从而不与MySQL交互,从而达到优化的效果,
* redis的查询速度之于MySQL的查询速度相当于 内存读写速度/硬盘读写速度
* @Cacheable("a")注解的意义就是把该方法的查询结果放到redis中去,
* 下一次再发起查询就去redis中去取,存在redis中的数据的key就是a;
* @CacheEvict(value={"a","b"},allEntries=true)
* 的意思就是执行该方法后要清除redis中key名称为a,b的数据;
* key 命名规范
* 当前被调用的方法使用的Cache:#root.caches[0].name
* 当前方法名#root.methodName 当前方法#root.method.name 当前被调用的对象#root.target 当前被调用的对象的 * class#root.targetClass
* 当前方法参数组成的数组#root.args[0] 当前被调用的方法使用的Cache#root.caches[0].name */
@Autowired
private UserMapper userMapper;
@Cacheable(value="user",key="'test'")
@Override
public User selectOne(String id) {
return userMapper.selectOne(id);
}
//allEntries=true redis自带缓存 不能生效 要报错 我这里没有添加
//去除缓存
@CacheEvict(value="user",key="'test'")
@Override
public Boolean updateOne(String id) {
try {
User u = userMapper.selectOne(id);
u.setId("1");
u.setUsername("qwer1234");
userMapper.updateByPrimaryKeySelective(u);
return true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
缺点:
缓存的value,key都在service层的注解里 不便于后期维护
redis缓存容易出现更新和查询缓存同步执行 出现脏数据的问题
项目中不建议这样使用 怎么写后面会有介绍---------我们先了解 在优化
这样的独占redis 的缓存 本人觉得难用 项目中 不建议这样实现 只用redis缓存配置 其他缓存需要关闭 如mybatis自带的缓存 且需添加<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>