1.如果之前项目中已经使用了第三方缓存(例如:ehcache)
(1)首先应该摒弃或者屏蔽掉,防止ehcache缓存的存在对这里的redis缓存的判断
(2)缓存的整合不在spring部分,而在mybatis部分
(3)整合也是整合redis+mybatis或者ehcache+mybatis,先意识到这点
(4)但是一般实际开发过程中,mybatis的相关配置已经整合到spring的配置文件中了
(5)因此缓存相关的配置也和mybatis一样,整合在spring的配置文件,方便利用spring的事务进行统一管理
2.整合过程如下:
(1)配置pom.xml:引入redis依赖
<!--支持Redis的语言——Jedis包-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!--依赖包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
<!-- mybatis与redis整合包-->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-redis</artifactId>
<version>1.0.0-beta2</version>
</dependency>
<!-- spring与redis整合包 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.1.RELEASE</version>
</dependency>
(2)创建配置Redis属性文件redis.properties
<1>property文件夹下的jdbc.properties和redis.properties.分别是数据源连接配置和redis服务端连接配置
<2>redis.properties配置内容
#ip和端口值为服务器默认设置,能找到redis服务并连接上
redis.host=127.0.0.1
redis.port=6379
#没有密码这里密码对应的值为空(没有最好就不要写,即使为空经测试运行起来也有问题)
redis.password=root
#redis.pool….是对连接redis服务器的jedispool的设置
redis.maxWaitMillis=1000
redis.maxTotal=600
redis.maxIdle=300
#在获取连接的时候检查有效性
redis.testOnBorrow=true
redis.testOnReturn=true
redis.timeout=100000
# 默认缓存失效时间
defaultCacheExpireTime=3600
(4)spring与redis整合的配置文件,如下:或者单独配置redis.xml
<!--扫描redis配置文件:集成在spring中,这里省略-->
//<context:property-placeholder ignore-unresolvable="true" location="classpath:redis.properties"/>
<!-- Redis连接池的设置:把jedisPool交给spring管理 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--高版本:maxWaitMillis,低版本:maxWait-->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 连接池中最大连接数。高版本:maxTotal,低版本:maxActive -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- 连接池中最大空闲的连接数. -->
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- 配置Redis连接工厂 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="poolConfig" ref="jedisPoolConfig"/>
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}"/>
<property name="timeout" value="${redis.timeout}"/>
</bean>
<!-- 配置redistempLate模板 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!-- 如果不配置Serializer,那么存储的时候只能使用String,如果用对象类型存储,那么会提示错误 -->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<!-- 开启事务,可以通过transcational注解控制 -->
<property name="enableTransactionSupport" value="true"></property>
</bean>
<!--当自定义的Redis缓存类通过注解方式注入spring后,就不要在此配置:静态注入了-->
<!-- <bean id="redisCacheTransfer" class="com.user.util.RedisCacheTransfer">
<property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
</bean> -->
</beans>
<2>单独配置时:在spring的配置文件applicationContext.xml导入spring-redis.xml即可
<import resource="spring-redis.xml"/>
3.mybatis整合redis缓存(使用Spring封装类RedisTemplate后,可省略)
(1)mybatis自己已经做了一个兼容redis的第三方缓存的jar包
(2)在pom.xml中引入mybatis-redis 的jar包,前面已经引入了
<1>可以查看RedisCache的源码
<2>public final class RedisCache implements Cache
(3)在mybatis的Mapper中引入:
<1>也可以使用自定义的接口
<2>使用自定义接口,需要在Mapper中引入具体的接口实现类路径
<mapper namespace="com.user.dao.UserDao">
<!--不自定义缓存接口,使用官方实现的默认接口用的是hash来缓存Mapper中的查询有缺陷
1.经测试如果使用默认接口,不需要配置,否则报错-->
<!--<cache type="org.mybatis.caches.redis.RedisCache" />-->
<!--mybatis集成在spring,缓存类使用注解后就不需要在此配置-->
<!-- <cache type="com.user.caches.redis.RedisCache" /> -->
...
</mapper>
(4)配置完毕之后,需要开启mybatis的全局缓存:
<configuration>
<settings>
<setting name="logImpl" value="LOG4J2" />
<!-- 全局映射器启用缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
(5)经过上面操作,就可以使用官方提供的Redis缓存了
(6)操作缓存时只需要引入RedisTemplate或者JedisPool
<1>JedisPool是Redis官方推荐的面向Java的操作Redis的客户端
<2>RedisTemplate是SpringDataRedis中对JedisApi的高度封装
<3>RedisTemplate相对于JedisPool来说可以方便地更换Redis的Java客户端
<4>比JedisPool多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用
@Resource
private RedisTemplate redisTemplate;
@Resource
private JedisPool jedisPool;
3.至此Redis已经引入到了SSM框架中
(1)引入过程中注意事项如下:
<1>redis作为缓存服务器的配置和数据库服务器配置一样,需要一些基本信息用来连接redis服务器
<2>redis的配置文件可以单独配置,然后引入spring中还可以直接与spring集成
<3>redis事务管理和spring事务管理不同,需要配置
(2)在使用mybatis官方提供的redis作为mybatis缓存,如果不做一些额外处理,会存在一些不足
<1>默认情况下,mybatis会为每一个mapper创建一个RedisCache,而JedisPool是在RedisCache的构造方法中创建
的,这就意味着会为每一个mapper创建一个JedisPool,使用意图和开销上面都会有问题;
<2>应用中也会独立使用到redis,这样无法让RedisCache直接使用项目中可能已经存在的JedisPool,并且会造成两个
配置文件(除非应用也使用redis.properties);
<3>RedisCache是使用hash来缓存一个Mapper中的查询,所以只能通过mybatis的cache配置来控制对象的生存时间,
空闲时间等属性;而无法独立的去配置每一个缓存区域(即每一个hash)
(3)针对上面的三个不足之处进行了进一步的改进:
<1>需要用到mybatis-redis中SerializeUtil类
<2>官方提供的redis-cache用的是hash来缓存Mapper中的查询,这里采用string数据结构来缓存
***<3>重要:可以自定义一个RedisCache,使用注解形式注入spring***
4.自定义缓存类接口:RedisCacheService
public interface RedisCacheService {
//读取缓存
Object getCache(String key);
//写入缓存
boolean setCache(String key, Object value);
boolean setCacheToRedis(String key, Object value, long expireTime);
// 批量删除对应的value
void remove(String... keys);
// 批量删除key
void removePattern(String pattern);
// 删除对应的value
void remove(String key);
// 删除符合要求的key by ivan
void deleteKeys(String key);
// 判断缓存中是否有对应的value
boolean exists(String key);
}
5.实现自定义缓存类接口,使用注解方式注入spring:RedisCacheServiceImpl
(1)使用自定义缓存类,注入spring优点如下:
<1>不需要在spring静态引入Redis配置类
<2>不需要在Mapping.xml中引入缓存支持,因为Mybatis已经集成在spring中统一管理
<3>Spring框架已经对Redis底层进行了封装:RedisTemplate<String, Object>,提供了丰富的Redis操作
(2)实现自定义缓存类接口:RedisCacheServiceImpl
/**
* RedisTemplate类:将同一类型操作封装为operation接口
* ValueOperations:简单K-V操作
* SetOperations:set类型数据操作
* ZSetOperations:zset类型数据操作
* HashOperations:针对map类型的数据操作
* ListOperations:针对list类型的数据操作
*/
@Service
public class RedisCacheServiceImpl implements RedisCacheService {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
public Object getCache(String key) {
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
return valueOperations.get(key);
}
@Override
public boolean setCache(String key, Object value) {
boolean result = false;
try {
value = JSON.toJSONString(value);
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
valueOperations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public boolean setCacheToRedis(String key, Object value, long expireTime) {
boolean result = false;
try {
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
valueOperations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public void remove(String... keys) {
for (String key : keys)
remove(key);
}
@Override
public void removePattern(String pattern) {
Set<String> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
@Override
public void remove(String key) {
if (exists(key))
redisTemplate.delete(key);
}
@Override
public void deleteKeys(String key) {
redisTemplate.delete(redisTemplate.keys(key));
}
@Override
public boolean exists(String key) {
return redisTemplate.hasKey(key);
}
public void setRedisTemplate(
RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
6.调用Redis缓存接口操作,应用实例
public class UserController {
@Resource
private UserService userService;
@Resource
private RedisCacheService redisCacheService;
@RequestMapping(value = "/user", method = RequestMethod.GET)
@ResponseBody
public Object FindInfo(@RequestParam("username") String username) {
//尝试从缓存中取数据
String name = (String) redisCacheService.getCache("username");
if(name==null){
//缓存中没有从数据库读取数据
List<User> list = userService.findByName(username);
System.out.println(list);
//将获取到的数据放入缓存,设置生存时间为1小时
redisCacheService.setCacheToRedis( "username", username, 3600);
System.out.println("数据存入缓存成功");
}else{
return name;
}
return username;
}
7.至此,SSM+Maven+Redis搭建单机版完毕
(1)注意事项如下:
<1>mybatis整合redis缓存(使用Spring封装类RedisTemplate后,可省略)
<2>使用自定义封装类,注解注入spring后,不需要在spring再静态注入
<3>实际开发中使用Spring封装的Redis:RedisTemplate