事在人为,是一种积极的人生态度;随遇而安,是一种乐观的处世妙方;顺其自然,是一种豁达的生存之道;水到渠成,是一种高超的入世智慧。 不保留的,才叫青春;不解释的,才叫从容;不放手的,才叫真爱;不完美的,才叫人生。 对世界好奇,对事业尊重,对生命敬畏,对家人负责。心态平和,坚持幽默,做个好人! --排骨营养汤
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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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-4.3.xsd">
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxTotal}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="hostName" value="${redis.ip}" />
<property name="password" value="${redis.password}" />
<property name="port" value="${redis.port}" />
<property name="poolConfig" ref="jedisPoolConfig" />
<property name="timeout" value="${redis.timeout}" />
</bean>
<!-- JSON序列化,空间占用小,无需指明但对象类型 -->
<bean id="genericJackson2JsonRedisSerializer" class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="keySerializer" ref="genericJackson2JsonRedisSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> -->
</property>
<property name="hashKeySerializer" ref="genericJackson2JsonRedisSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> -->
</property>
<property name="valueSerializer" ref="genericJackson2JsonRedisSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer" /> -->
</property>
<property name="hashValueSerializer" ref="genericJackson2JsonRedisSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer" /> -->
</property>
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
<!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!-- 编码1 -->
<bean class="RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="code1"/>
<property name="timeout" value="${redis.timeout}"/>
</bean>
<!-- 编码2 -->
<bean class="RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="code2"/>
<property name="timeout" value="${redis.timeout}"/>
</bean>
</property>
</bean>
</beans>
以上配置文件实现了
- json格式的序列化
- code1和code2两个key值的管理
- redis的基本配置
2. 管理类
/**
* @author
* @version 创建时间:2017年12月12日 下午2:13:10
*
*/
import java.util.concurrent.Callable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
public class RedisCache implements Cache {
private RedisTemplate<String, Object> redisTemplate;
private String name;
@Autowired
private JedisDao jedisDao;
private long timeout;
@Autowired
private GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer;
public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
public long getTimeout() {
return timeout;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
@Override
public Object getNativeCache() {
return this.redisTemplate;
}
@Override
public ValueWrapper get(Object key) {
final String keyf = key.toString();
Object object = null;
object = redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
// byte[] key = keyf.getBytes();
byte[] value = connection.hGet(name.getBytes(), keyf.getBytes());
if (value == null) {
return null;
}
return toObject(value);
}
});
return (object != null ? new SimpleValueWrapper(object) : null);
}
@Override
public void put(Object key, Object value) {
final String keyf = key.toString();
final Object valuef = value;
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
connection.hSet(name.getBytes(), keyf.getBytes(), toByteArray(valuef));
if (timeout > 0) {
connection.expire(name.getBytes(), timeout);
}
return 1L;
}
});
}
private byte[] toByteArray(Object obj) {
return genericJackson2JsonRedisSerializer.serialize(obj);
}
private Object toObject(byte[] bytes) {
return genericJackson2JsonRedisSerializer.deserialize(bytes);
}
@Override
public void evict(Object key) {
final String keyf = key.toString();
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.del(keyf.getBytes());
}
});
}
@Override
public void clear() {
redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
connection.del(name.getBytes());
return "ok";
}
});
}
@Override
public <T> T get(Object key, Class<T> type) {
return null;
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
return null;
}
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
return null;
}
}
3.使用
1.code1缓存管理
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.dubbo.config.annotation.Service;
public class Code1{
@CacheEvict(value = "code1", allEntries = true)
public boolean saveOrUpdate() {
return true;
}
@Cacheable(value = "code1", key = "'queryById_' + #id")
public List<Long> queryById(String id) {
return ...;
}
@Cacheable(value = "code1", key = "'queryByName_' + #name")
public List<Long> queryByName(String name) {
return ...;
}
}
1.该类实现了对code1为code值的HashMap的管理
2.在redis中结果应该是
code1--->queryById_1-->List<Long>
queryById_2-->List<Long>
....
queryById_n-->List<Long>
...
queryByName_name1-->List<Long>
queryByName_name2-->List<Long>
...
queryByName_name3-->List<Long>
当调用saveOrUpdate方法时,会触发RedisCache 中的evict,这样就会清空掉以code1为key值的所有redis缓存的数据。
当触发queryById()时,会先触发RedisCache 中的get方法,如果查询到了数据则直接返回,不再进入到queryById()方法里,如果未查询到结果则会把查询出来的数据通过调用RedisCache 中的put方法,插入到redis中,建立缓存,以待下次查询时使用。
2.code2管理
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.dubbo.config.annotation.Service;
public class Code2{
@CacheEvict(value = "code2", allEntries = true)
public boolean saveOrUpdate() {
return true;
}
@Cacheable(value = "code2", key = "#root.target.getCacheMapJson(#map)")
public List<Long> query(Map<String, Object> map) {
return ...;
}
public String getCacheMapJson(Map<String, Object> map) {
return JSON.toJSONString(map);
}
}
code2类与code1的区别是,实现了getCacheMapJson方法,复杂的查询条件进行序列化,该方法必须为public。
网友评论