redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
1.导入jar包依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
2.相应的配置
# REDIS (RedisProperties)
#spring.redis.database=
spring.redis.host=
spring.redis.password=
spring.redis.port=6379
spring.redis.pool.max-idle=100
spring.redis.pool.min-idle=1
spring.redis.pool.max-active=1000
spring.redis.pool.max-wait=-1
server.port=8081
3.编写cache管理类
package com.example;
import java.lang.reflect.Method;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* 缓存管理(注解用)
* @author Administrator
*
*/
@Configuration
@EnableCaching
public class CacheService extends CachingConfigurerSupport {
/**
* 生成key的策略
*
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/**
* 管理缓存
*
* @param redisTemplate
* @return
*/
@SuppressWarnings("rawtypes")
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//设置缓存过期时间
// rcm.setDefaultExpiration(60);//秒
//设置value的过期时间
Map<String,Long> map=new HashMap();
map.put("test",60L);
rcm.setExpires(map);
return rcm;
}
/**
* RedisTemplate配置
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);//如果key是String 需要配置一下StringSerializer,不然key会乱码 /XX/XX
template.afterPropertiesSet();
return template;
}
}
4.常用的操作redis的方法
package com.example;
import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
/**
* redicache 工具类
*
*/
@SuppressWarnings("unchecked")
@Component
public class RedisUtil {
@SuppressWarnings("rawtypes")
@Autowired
private RedisTemplate redisTemplate;
/**
* 批量删除对应的value
*
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
*
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
/**
* 删除对应的value
*
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
*
* @param key
* @return
*/
public Object get(final String key) {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
* 写入缓存
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
5.在方法前面加上缓存
@RequestMapping("/")
@Cacheable(value="test")
public String getSessionId(HttpSession session){
redisUtil.set("123", "测试");
System.out.println("进入了方法");
String string= redisUtil.get("123").toString();
return string;
}
@Cacheable参数
value 指明缓存将被存到什么地方。
key Spring默认使用被@Cacheable注解的方法的签名来作为key
condition =
"#age < 25"
数将指明方法的返回结果是否被缓存。
本文地址(防爬虫不标注来源): http://www.wncode.cn
引用来自“王念博客”的评论
这不是缓存的问题 而是jackson的异常,你可以把PageImpl类拷贝出来手动加个构造方法 或者看看jackson有没有注解解决这个问题。引用来自“absurd717”的评论
结果报了Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.data.domain.PageImpl cannot be cast to com.absurd.core.model.PageImplBean] with root cause引用来自“Kevin_Zhan”的评论
配置文件都没引用到,spring怎么知道这个redis的配置在哪呢,对应的key是什么呢引用来自“王念博客”的评论
这是springBoot的配置,不是spring xml配置的方式。引用来自“Kevin_Zhan”的评论
你的意思是 他默认会去application.properties去寻找对应的redis的属性,比如host,timeout,然后注入到redis吗?引用来自“Kevin_Zhan”的评论
配置文件都没引用到,spring怎么知道这个redis的配置在哪呢,对应的key是什么呢引用来自“王念博客”的评论
这是springBoot的配置,不是spring xml配置的方式。引用来自“Kevin_Zhan”的评论
配置文件都没引用到,spring怎么知道这个redis的配置在哪呢,对应的key是什么呢引用来自“王念博客”的评论
这不是缓存的问题 而是jackson的异常,你可以把PageImpl类拷贝出来手动加个构造方法 或者看看jackson有没有注解解决这个问题。引用来自“王念博客”的评论
这不是缓存的问题 而是jackson的异常,你可以把PageImpl类拷贝出来手动加个构造方法 或者看看jackson有没有注解解决这个问题。private static final long serialVersionUID = 1L;
private int number;
private int size;
private int totalPages;
private int numberOfElements;
private long totalElements;
private boolean previousPage;
private boolean firstPage;
private boolean nextPage;
private boolean lastPage;
private List content;
private Sort sort;
public PageImplBean() {
super(new ArrayList());
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public int getNumberOfElements() {
return numberOfElements;
}
public void setNumberOfElements(int numberOfElements) {
this.numberOfElements = numberOfElements;
}
public long getTotalElements() {
return totalElements;
}
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
}
public boolean isPreviousPage() {
return previousPage;
}
public void setPreviousPage(boolean previousPage) {
this.previousPage = previousPage;
}
public boolean isFirstPage() {
return firstPage;
}
public void setFirstPage(boolean firstPage) {
this.firstPage = firstPage;
}
public boolean isNextPage() {
return nextPage;
}
public void setNextPage(boolean nextPage) {
this.nextPage = nextPage;
}
public boolean isLastPage() {
return lastPage;
}
public void setLastPage(boolean lastPage) {
this.lastPage = lastPage;
}
public List getContent() {
return content;
}
public void setContent(List content) {
this.content = content;
}
public Sort getSort() {
return sort;
}
public void setSort(Sort sort) {
this.sort = sort;
}
public PageImpl pageImpl() {
return new PageImpl(getContent(), new PageRequest(getNumber(),
getSize(), getSort()), getTotalElements());
}
}
at [Source: [B@206540; line: 1, column: 46]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:261) ~[jackson-databind-2.8.3.jar:2.8.3]
意思是PageImpl没有无参构造函数,怎么解决?