SpringDataRedis简介
Spring-data-redis是spring大家族的一部分,提供了在spring应用中通过简单的配置访问redis服务,对reids底层开发包(比如jedis)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化。
基于上一篇
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.5.1</version>
</dependency>
创建redis配置文件
在src/main/resources下创建redis.properties
# redis配置
spring.redis.pool.max-idle=10
spring.redis.pool.min-idle=5
spring.redis.pool.max-total=20
spring.redis.hostName=192.168.117.180
spring.redis.port=6379
spring.redis.password=qzcsbj
创建redis配置类
在src/main/java/com/qzcsbj/demo/config下创建RedisConfig
package com.qzcsbj.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPoolConfig;
/**
* @公众号 : 全栈测试笔记
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 :
*/
@Configuration // 配置类
@PropertySource("classpath:redis.properties") // 指定配置文件
public class RedisConfig {
@Bean
@ConfigurationProperties(prefix = "spring.redis.pool")
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
@Bean
@ConfigurationProperties(prefix="spring.redis")
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig config){
JedisConnectionFactory factory = new JedisConnectionFactory();
// 关联配置对象
factory.setPoolConfig(config);
return factory;
}
@Bean
public RedisTemplate<String,Object> redisTemplate(@Qualifier("jedisConnectionFactory") JedisConnectionFactory factory){
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
}
测试(五种数据类型:string、hash、list、set、zset)
操作string
value为String
set存字符串
package com.qzcsbj.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
/**
* @公众号 : 全栈测试笔记
* @博客 : www.cnblogs.com/uncleyong
* @微信 : ren168632201
* @描述 : <>
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootdemoApplication.class)
public class TestString {
@Autowired
RedisTemplate<String, Object> redisTemplate;
@Test
public void testSet(){
redisTemplate.opsForValue().set("name","jack");
System.out.println("set字符串完成。");
}
}
get取字符串
@Test
public void testGet(){
Object o = redisTemplate.opsForValue().get("name");
System.out.println("获取到字符串name:" + o);
}
value为对象
存user对象
@Test
public void testSetUser(){
// 从数据库获取对象
User user = userService.findById(1);
System.out.println("从mysql获取到的user: " + user);
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.opsForValue().set("user",user);
System.out.println("set对象完成。");
}
存入的内容是序列化后的
取user对象
@Test
public void testGetUser(){
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
User u = (User)redisTemplate.opsForValue().get("user");
System.out.println("从redis获取到的user: " + u);
System.out.println("get对象完成。");
}
基于JSON格式存User对象
@Test
public void testSetUserByJSON(){
User user = userService.findById(1);
System.out.println("从mysql获取到的user: " + user);
this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(User.class));
this.redisTemplate.opsForValue().set("user_json", user);
System.out.println("set为json对象完成。");
}
基于JSON格式取User对象
@Test
public void testGetUseByJSON(){
this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(User.class));
User user = (User)this.redisTemplate.opsForValue().get("user_json");
System.out.println("从redis获取到的user: " + user);
System.out.println("get对象完成。");
}
存User对象集合
@Test
public void testSetUserList(){
// 从数据库获取对象集合
List<User> users = userService.findAll();
System.out.println("从mysql获取到的user集合: " + users);
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.opsForValue().set("users",users);
System.out.println("set对象集合完成。");
}
取User对象集合
@Test
public void testGetUserList(){
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
List<User> users = (List<User>)redisTemplate.opsForValue().get("users");
System.out.println("从redis获取到的user集合: " + users);
System.out.println("get对象集合完成。");
}
操作hash
存
@Test
public void testSetValue() {
redisTemplate.boundHashOps("token").put("jack", "62f7f5673e94eca21");
redisTemplate.boundHashOps("token").put("tom", "62f7f5673e94eca22");
redisTemplate.boundHashOps("token").put("laowang", "62f7f5673e94eca23");
System.out.println("hash存值完成");
}
获取所有的key
@Test
public void testGetKeys() {
Set keys = redisTemplate.boundHashOps("token").keys();
System.out.println("获取到的key是:" + keys);
}
根据key取值
@Test
public void getValueByKey() {
String value = (String) redisTemplate.boundHashOps("token").get("jack");
System.out.println("jakc的值是:" + value);
}
移除某个key
@Test
public void removeValue() {
// 如果移除前存值,返回1,不存在,返回0
redisTemplate.boundHashOps("token").delete("jack");
}
操作list
左压栈
@Test
public void testSet() {
redisTemplate.boundListOps("stulist").leftPush("tom");
redisTemplate.boundListOps("stulist").leftPush("jack");
redisTemplate.boundListOps("stulist").leftPush("老王");
}
获取值
@Test
public void testGet() {
List list = redisTemplate.boundListOps("stulist2").range(0, -1);
System.out.println("获取到的list:" + list);
}
右压栈
@Test
public void testSet2() {
redisTemplate.boundListOps("stulist").rightPush("tom");
redisTemplate.boundListOps("stulist").rightPush("jack");
redisTemplate.boundListOps("stulist").rightPush("老王");
}
获取值
@Test
public void testGet2() {
List list = redisTemplate.boundListOps("stulist").range(0, -1);
System.out.println("获取到的list:" + list);
}
操作set
存
@Test
public void setValue() {
redisTemplate.boundSetOps("stuset").add("tom");
redisTemplate.boundSetOps("stuset").add("jack");
redisTemplate.boundSetOps("stuset").add("老王");
}
取
@Test
public void getValue() {
Set set = redisTemplate.boundSetOps("stuset").members();
System.out.println("获取到的stuset:" + set);
}
操作zset
存
@Test
public void testAdd() {
redisTemplate.boundZSetOps("zSet").add("A", 10);
redisTemplate.boundZSetOps("zSet").add("B", 40);
redisTemplate.boundZSetOps("zSet").add("C", 50);
redisTemplate.boundZSetOps("zSet").add("D", 20);
redisTemplate.boundZSetOps("zSet").add("E", 30);
}
取
@Test
public void testRange(){
Set zSet = redisTemplate.boundZSetOps("zSet").range(0,-1);
System.out.println(zSet);
基本应用
项目中,redis是主流技术栈,使用redis,可以减轻关系型数据库的压力。
下面以获取用户列表为例:
增、删、改:成功后,都要清除缓存
// restful api:增
@PostMapping("/users")
public ResultCommon add(User user){
int n = userService.add(user);
if (n>0){
System.out.println("新增数据成功,清除缓存");
// 清除缓存
redisTemplate.delete("users");
return ResultCommon.success(ResultCode.SUCCESS);
} else {
return ResultCommon.fail(ResultCode.FAIL);
}
}
// restful api:删
@DeleteMapping("/users/{id}")
public ResultCommon delete(@PathVariable("id") Integer id){
int n = userService.delete(id);
if (n>0){
System.out.println("删除数据成功,清除缓存");
// 清除缓存
redisTemplate.delete("users");
return ResultCommon.success(ResultCode.SUCCESS);
} else {
return ResultCommon.fail(ResultCode.FAIL);
}
}
// restful api:改
@PutMapping("/users")
public ResultCommon update(User user){
int n = userService.update(user);
if (n>0){
System.out.println("修改数据成功,清除缓存");
// 清除缓存
redisTemplate.delete("users");
return ResultCommon.success(ResultCode.SUCCESS);
} else {
return ResultCommon.fail(ResultCode.FAIL);
}
}
查
先从redis查,查到,则返回,未查到,则从数据库查,把结果存到redis,然后再返回
// restful api:查所有
@GetMapping("/users")
public ResultCommon findAll(){
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
// 先从redis取值
List<User> users = (List<User>)redisTemplate.opsForValue().get("users");
if (users!=null && users.size()>0){
System.out.println("redis缓存中有数据,从redis获取数据。");
} else {
users = userService.findAll();
System.out.println("redis缓存中没有数据,从mysql中获取数据。");
// 往缓存中存一份
redisTemplate.opsForValue().set("users",users);
}
清空redis
第一次请求
日志
第二次、第三次相同请求
【bak】
本文作者:持之以恒(韧)
关于博主:擅长性能、全链路、自动化、企业级自动化持续集成(DevOps/TestOps)、测开等