很简单的配置了一些东西,方便新人可以入门,有那方面不对的或者不足的请指点一下,我也确实很多东西不是很了解。
记得注意的是,当你更新和查询的时候,返回的值对象都应该是相同的,很多新人更新直接就返回int值,然后又一直报错
安装redis
redis的下载步骤参考文章:https://blog.csdn.net/weixin_42423819/article/details/80634918
- 去网址:https://github.com/MSOpenTech/redis/releases下载对应的压缩包版本。
- 解压到自己创建的redis目录下
- 配置环境变量
- 打开cmd窗口,执行redis-server.exe启动。
- 在另外打开一个cmd窗口,执行redis-cli.exe -h 127.0.0.1 -p 6379,测试下列代码:
设置键值对 set redisdemo 12345
取出键值对 get redisdemo
参考文章
对缓存的讲解:https://blog.csdn.net/qq_38974634/article/details/80650810
泛讲:http://www.ityouknow.com/springboot/2016/03/06/spring-boot-redis.html
详细配置(强烈推荐):http://xiaogang.org.cn/articles/2019/03/25/1553495738340.html
redis的使用
一些知识点的讲解:
使用注解自动根据方法返回值生成key-value
首先是配置:
pom.xml
<!--redis的引入-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
java的配置文件,只配置了key的生成器和过期时间设置
@Configuration
@EnableCaching
public class RedisConfig {
@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();
}
};
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
//初始化一个RedisCacheWriter
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
//设置默认超过期时间是1天
defaultCacheConfig.entryTtl(Duration.ofDays(1));
//初始化RedisCacheManager
RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
return cacheManager;
}
}
接着就是在impl文件上加注解:
//注解来统一指定value的值,这时候你在方法注解中就不用指定value值,优先级小于方法中的value。
//@CacheConfig(cacheNames = {"user"})
@Override
@Cacheable(value = "user")
public User selectByPrimaryKey(String username) {
return this.userMapper.selectByPrimaryKey(username);
}
}
//由于是更新同一个键值对,注意返回的需要跟查询同样为User对象,不要像平时一样返回int对象,可以使用result,也可以直接使用参数,eg:record.username,记得序列化对象
@Override
@CachePut(value = "user", key="#result.username")
public User updateByPrimaryKeySelective(User record) {
this.userMapper.updateByPrimaryKeySelective(record);
return this.userMapper.selectByPrimaryKey(record.getUsername());
}
在controller类上
//beforeInvocation = false在方法执行后,如果方法顺利执行,才清空相应的缓存
@RequestMapping("logout")
@CacheEvict(value = "user",key = "#user.username", beforeInvocation = false)
public ModelAndView logout(User user){
User myUser=userService.selectByPrimaryKey(user.getUsername());
if(user.getPassword().equals(myUser.getPassword())){
userService.deleteByPrimaryKey(user.getUsername());
return new ModelAndView("success");
}
else {
return new ModelAndView("fail");
}
}
大概这样子的配置就可以使用了,登陆使用@Cacheable会自动检测在缓存有没有相应的key,有的话就不会执行相应的方法,更新的话使用@CachePut,有相同的key就覆盖掉value,接着就是@CacheEvict清空缓存。
然后就是手动创建redis的键(最基础的)
看完文章还有不明白的建议看这一篇文章:https://blog.csdn.net/Abysscarry/article/details/80557347
- 首先是生成这两个boot封装的工具类: StringRedisTemplate和RedisTemplate。
区别在于第一个的key和value只能是String,而第二个是支持所有类型。 - 两个工具类都定义了对5种数据结构操作:
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
@Autowired
protected StringRedisTemplate redisTemplate;
@Autowired
protected RedisTemplate redisTemplate;
//生成一个key-value
ValueOperations operations=redisTemplate.opsForValue();
//第一个参数为key,第二个为value
operations.set("1","2");
//这里是设置键的有效日期
redisTemplate.expire("1", 123L, TimeUnit.SECONDS);
//判断是否有这个key的缓存
Boolean result = redisTemplate.hasKey("1");
//根据key取出相应的value
System.out.println(operations.get("1"));
//删除掉key—value
redisTemplate.delete("1");
补充
参考文章
作者:混合动力火锅
来源:CSDN
原文:https://blog.csdn.net/m0_37224390/article/details/82051251
当键值对用对象作为值时,需要在RedisConfig中编写修改一下序列化和反序列化。
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
如何使用:
@Test
public void savereids() {
User u=new User(1,"王伟",21);
template.opsForValue().set(u.getId()+"",u);
User result = (User) template.opsForValue().get(u.getId()+"");
System.out.println(result.toString());
}
参考文章:https://www.cnblogs.com/superfj/p/9232482.html
RedisTemplate使用指南
- 操作接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作 - 工具类
package com.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Component
public class RedisService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* 默认过期时长,单位:秒
*/
public static final long DEFAULT_EXPIRE = 60 * 60 * 24;
/**
* 不设置过期时长
*/
public static final long NOT_EXPIRE = -1;
public boolean existsKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 重名名key,如果newKey已经存在,则newKey的原值被覆盖
*
* @param oldKey
* @param newKey
*/
public void renameKey(String oldKey, String newKey) {
redisTemplate.rename(oldKey, newKey);
}
/**
* newKey不存在时才重命名
*
* @param oldKey
* @param newKey
* @return 修改成功返回true
*/
public boolean renameKeyNotExist(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
/**
* 删除key
*
* @param key
*/
public void deleteKey(String key) {
redisTemplate.delete(key);
}
/**
* 删除多个key
*
* @param keys
*/
public void deleteKey(String... keys) {
Set<String> kSet = Stream.of(keys).map(k -> k).collect(Collectors.toSet());
redisTemplate.delete(kSet);
}
/**
* 删除Key的集合
*
* @param keys
*/
public void deleteKey(Collection<String> keys) {
Set<String> kSet = keys.stream().map(k -> k).collect(Collectors.toSet());
redisTemplate.delete(kSet);
}
/**
* 设置key的生命周期
*
* @param key
* @param time
* @param timeUnit
*/
public void expireKey(String key, long time, TimeUnit timeUnit) {
redisTemplate.expire(key, time, timeUnit);
}
/**
* 指定key在指定的日期过期
*
* @param key
* @param date
*/
public void expireKeyAt(String key, Date date) {
redisTemplate.expireAt(key, date);
}
/**
* 查询key的生命周期
*
* @param key
* @param timeUnit
* @return
*/
public long getKeyExpire(String key, TimeUnit timeUnit) {
return redisTemplate.getExpire(key, timeUnit);
}
/**
* 将key设置为永久有效
*
* @param key
*/
public void persistKey(String key) {
redisTemplate.persist(key);
}
}
有关于redis的一些方法:https://www.redis.net.cn/order/3538.html
可以在网页上直接测试,也可以测试后在cmd上输入下列命令测试
列出所有的键值:KEYS *
删除相应的键值对:DEL KEY_NAME
eg:DEL “user”
查看key-value所剩下的有效时间:PTTL KEY
删除所有的键:plushall
github源码:https://github.com/jiaojiaoyow/myredis.git