Springboot集成Redis
导入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
#redis配置
spring:
redis:
port: 6379
host: 43.139.142.79
password: credis66
database: 1
redis配置模板文件:
package com.yixin.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//为了自己开发方便,一般直接使用 <String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
// Json序列化配置
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);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
Springboot使用Redis的操作
以下是笔记内容:
1、装配
@Autowired
private RedisTemplate<String,Object> redisTemplate;
2、 String 类型操作
// 查询所有,模糊查找所有以jedis开头的key的值
Set<String> keys = redisTemplate.keys("jedis*");
// 设置、获取键值对
redisTemplate.opsForValue().set("jedis1", "1");
redisTemplate.opsForValue().get("jedis1");
// 设置有效期限的键,获取 ttl 值
redisTemplate.opsForValue().set("expire1", "ttl key");
redisTemplate.expire("expire1", 60, TimeUnit.SECONDS);//60s失效
redisTemplate.getExpire("expire1")//获取剩余存活时间
// 同时设置多个键值对,并获取
Map<String, String> stringStringMap = new LinkedHashMap<>();
stringStringMap.put("java-1", "6");
stringStringMap.put("java-2", "8");
stringStringMap.put("java-3", "10");
redisTemplate.opsForValue().multiSet(stringStringMap);
List<String> multiGet = redisTemplate.opsForValue().multiGet(stringStringMap.keySet());
// 对 数值型的 键值对进行增减操作
redisTemplate.opsForValue().increment("java-1", 3L);//3L表示整数3
redisTemplate.opsForValue().decrement("java-3", 5L);
multiGet = redisTemplate.opsForValue().multiGet(stringStringMap.keySet());
// 返回旧的数据,更新新的数据
String andSet = redisTemplate.opsForValue().getAndSet("java-2", "new-value");
// 对值进行字符串操作
redisTemplate.opsForValue().append("java-2", "-aaa");
// 删除元素
Set<String> keys1 = redisTemplate.keys("*");
redisTemplate.delete(keys1);
3、List 类型操作
// 从左侧和右侧 添加元素
List<String> nameList = new LinkedList<>();
nameList.add("Mike");
nameList.add("Peter");
nameList.add("Jack");
redisTemplate.opsForList().leftPushAll("list-java-1", nameList); // 左侧 push
nameList.clear();
nameList.add("aaa");
nameList.add("bbb");
nameList.add("ccc");
redisTemplate.opsForList().rightPushAll("list-java-1", nameList); // 右侧 push
// 根据索引获取元素
String index = redisTemplate.opsForList().index("list-java-1", 1);
// 获取所有元素
List<String> range = redisTemplate.opsForList().range("list-java-1", 0, -1);
// 删除指定数量的某元素
redisTemplate.opsForList().remove("list-java-1", 2, "Mike");//这里参数count=2>0,表示删除从左到右的第一个等于Mike的值,count<0表示删除从右到左的第一个等于Mike的值,count=0:删除等于Mike的所有元素。
// 删除全部元素
redisTemplate.opsForList().trim("list-java-1", 0, 0);
redisTemplate.opsForList().leftPop("list-java-1");
range = redisTemplate.opsForList().range("list-java-1", 0, -1);
//元素数量
redisTemplate.opsForList().size("list-java-1")
4、Set 集合类型方法
// 添加元素
redisTemplate.opsForSet().add("set-java-1", "Mike", "Peter", "Jack", "Mike", "Smith");
// 查询元素
Set<String> members = redisTemplate.opsForSet().members("set-java-1")
// 判断元素是否在 set 中
redisTemplate.opsForSet().isMember("set-java-1", "Mike")
// 交集,并集,差集的计算
Set<String> intersect = redisTemplate.opsForSet().intersect("set-java-1", "set-java-2");
Set<String> union = redisTemplate.opsForSet().union("set-java-1", "set-java-2");
Set<String> difference = redisTemplate.opsForSet().difference("set-java-1", "set-java-2");
// 删除元素
redisTemplate.opsForSet().remove("set-java-1", "Mike");
redisTemplate.opsForSet().move("set-java-1", "set-java-2", "Jack");
redisTemplate.opsForSet().pop("set-java-1", redisTemplate.opsForSet().size("set-java-1"));//指定删除集合和个数
redisTemplate.opsForSet().pop("set-java-2", redisTemplate.opsForSet().size("set-java-2"));
5、Sort Set 类型方法(有序集合)
有序集合每个key必须添加一个序号score
// 添加元素
redisTemplate.opsForZSet().add("sortset-java-1", "不及格", 59.0);
redisTemplate.opsForZSet().add("sortset-java-1", "及格", 69.0);
// 查询元素
redisTemplate.opsForZSet().size("sortset-java-1")
redisTemplate.opsForZSet().score("sortset-java-1", "优秀")//获取该键的序号,key不能通过序号获取。key只能用来查询。
redisTemplate.opsForZSet().count("sortset-java-1", 60, 100)
// 删除元素
redisTemplate.opsForZSet().remove("sortset-java-1", "不及格"); // 单独删除一个元素
redisTemplate.opsForZSet().removeRangeByScore("sortset-java-1", 60, 100); // 删除分数段的所有元素
6、Hash 类型方法
// 增加数据(进行序列化)
User user = new User(2022090101, "Mike", 21, "Beijing"));
Map<String, String> userMap = new LinkedHashMap<>();
userMap.put(String.valueOf(user.getId()), JSON.toJSONString(user));
redisTemplate.opsForHash().putAll("hash-java-1", userMap);//userMaper需要经过序列化,key和value都需要是String
// 获取所有的键,值
Set<Object> keys = redisTemplate.opsForHash().keys("hash-java-1");
List<Object> values = redisTemplate.opsForHash().values("hash-java-1");
// 判断某个键是否存在
Boolean aBoolean = redisTemplate.opsForHash().hasKey("hash-java-1", "2022090101");
// 获取并修改某个键对应的值
String userString = (String)redisTemplate.opsForHash().get("hash-java-1", "2022090101");
User user = JSON.parseObject(userString, User.class);
user.setAge(30);
user.setAddress("Guangzhou");
redisTemplate.opsForHash().put("hash-java-1", "2022090101", JSON.toJSONString(user));
// 获取所有键值对
Map<Object, Object> entries = redisTemplate.opsForHash().entries("hash-java-1");
for (Map.Entry<Object, Object> entry: entries.entrySet()){
System.out.println("键:" + entry.getKey() + ", 值:" + entry.getValue());//获取键对值集合后遍历
}
// 删除元素
redisTemplate.opsForHash().keys("hash-java-1").forEach(key -> redisTemplate.opsForHash().delete("hash-java-1", key));
7、 事务
/**
* 事务
*/
public void MultiMethod(){
// 模拟转账操作(模拟 Mike,Jack用户各有 100 元)
redisTemplate.opsForValue().set("Mike", "100");
redisTemplate.opsForValue().set("Jack", "100");
// 进行转账操作(转账 20 元)
int transfer = 20;
String mike = redisTemplate.opsForValue().get("Mike");
redisTemplate.setEnableTransactionSupport(true); // 开启事务支持
redisTemplate.watch(List.of("Mike", "Jack")); // 开启监听
redisTemplate.multi(); // 开启事务
try{
// 判断余额是否足够
if (Integer.parseInt(mike) >= transfer){
redisTemplate.opsForValue().decrement("Mike", (long) transfer); // 转出
redisTemplate.opsForValue().increment("Jack", (long) transfer); // 转入
redisTemplate.exec(); // 提交事务
System.out.println("双方转账成功");
}else {
System.out.println("Mike 账户余额不足,转账失败");
}
}catch (Exception e){
System.out.println("转账过程中出现异常:" + e.getMessage());
redisTemplate.discard(); // 回滚
} finally {
System.out.println("转账后双方余额:Mike:" + redisTemplate.opsForValue().get("Mike") + ", Jack: " + redisTemplate.opsForValue().get("Jack"));
// 删除测试数据
redisTemplate.delete(List.of("Mike", "Jack"));
}
}
主要语句:
redisTemplate.setEnableTransactionSupport(true); // 开启事务支持
redisTemplate.watch(List.of("Mike", "Jack")); // 开启监听
redisTemplate.multi(); // 开启事务
redisTemplate.opsForValue().decrement("Mike", (long) transfer); // 转出
redisTemplate.opsForValue().increment("Jack", (long) transfer); // 转入
redisTemplate.exec(); // 提交事务
redisTemplate.discard(); // 回滚
8、bound…Ops系列(最常用)
/**
* boundHashOps()则是直接将key和boundHashOperations对象进行了绑定,
* 后续直接通过boundHashOperations对象进行相关操作即可,写法简洁,不需要
* 每次都显式的将key写出来
*/
BoundHashOperations<String, String, Object> boundHashOperations = redisTemplate.boundHashOps("hash-key");
result = (Integer) boundHashOperations.get("a");
result = (Integer) boundHashOperations.get("b");
boundHashOperations.delete("c");
//即boundHashOps不用每次都带上数据库中的key进行查询,更快更方便。
//而opsForHash每次查询都带上数据库中的key进行查询,繁琐
/**获取a,然后获取b,然后删除c,对同一个key有多次操作,按照opsForHash()的写法
* 每次都是redisTemplate.opsForHash().xxx("key","value")写法很是啰嗦
*/
int result = (Integer) redisTemplate.opsForHash().get("hash-key","a");
result = (Integer)redisTemplate.opsForHash().get("hash-key","b");
redisTemplate.opsForHash().delete("hash-key","c");
参考:
(124条消息) 使用Java操作Redis_一心同学的博客-CSDN博客_java操作redis
(159条消息) Java使用RedisTemplate操作Redis_云梦归遥的博客-CSDN博客_redistemplate ttl