【SpringBoot整合Redis 之 lettuce#私藏项目实操分享#】炒沙作縻终不饱,缕冰文章费工巧。这篇文章主要讲述SpringBoot整合Redis 之 lettuce#私藏项目实操分享#相关的知识,希望能为你提供帮助。
功能说明SpringBoot2.2.6整合Redis,实现
- 对Redis各种类型数据的操作
- 业务层查改删缓存的管理
第一步:创建项目 maven依赖
<
dependency>
<
groupId>
junit<
/groupId>
<
artifactId>
junit<
/artifactId>
<
version>
4.12<
/version>
<
scope>
test<
/scope>
<
/dependency>
<
dependency>
<
groupId>
org.projectlombok<
/groupId>
<
artifactId>
lombok<
/artifactId>
<
version>
1.18.10<
/version>
<
/dependency>
<
!--解决java8新日期API反序列化异常:com.fasterxml.jackson.databind.exc.InvalidDefinitionException-->
<
dependency>
<
groupId>
com.fasterxml.jackson.datatype<
/groupId>
<
artifactId>
jackson-datatype-jsr310<
/artifactId>
<
/dependency>
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter<
/artifactId>
<
/dependency>
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-web<
/artifactId>
<
/dependency>
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-test<
/artifactId>
<
scope>
test<
/scope>
<
/dependency>
<
dependency>
<
groupId>
com.fasterxml.jackson.core<
/groupId>
<
artifactId>
jackson-core<
/artifactId>
<
version>
2.10.1<
/version>
<
/dependency>
<
dependency>
<
groupId>
com.fasterxml.jackson.core<
/groupId>
<
artifactId>
jackson-databind<
/artifactId>
<
version>
2.10.1<
/version>
<
/dependency>
<
dependency>
<
groupId>
com.fasterxml.jackson.core<
/groupId>
<
artifactId>
jackson-annotations<
/artifactId>
<
version>
2.10.1<
/version>
<
/dependency>
<
!--redis默认使用的Lettuce客户端-->
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-data-redis<
/artifactId>
<
/dependency>
<
!--使用默认的Lettuce时,若配置spring.redis.lettuce.pool则必须配置该依赖-->
<
dependency>
<
groupId>
org.apache.commons<
/groupId>
<
artifactId>
commons-pool2<
/artifactId>
<
/dependency>
application.yml
server:
port: 80
servlet:
context-path: /ir
spring:
redis:
database: 0
host: 172.16.85.140
port: 6379
password: 1234
timeout: 10000ms# 超时时间
lettuce:
pool:
max-idle: 8 # 最大空闲连接数,默认值为8
max-wait: -1ms # 最大连接阻塞等待时间,默认值-1
min-idle: 2 # 最小空闲连接数
max-active: 20 #最大连接数
第二步:Redis配置文件
@Configuration
//继承CachingConfigurerSupport,为了自定义生成KEY的策略,可以不继承。
public class RedisConfig extends CachingConfigurerSupport
private Duration timeToLive = Duration.ofDays(1);
//过期时间1天
private StringRedisSerializer keySerializer = new StringRedisSerializer();
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
private Jackson2JsonRedisSerializer valueSerializer = new
Jackson2JsonRedisSerializer(Dept.class);
//解决缓存转换异常的问题
ObjectMapper objectMapper = new ObjectMapper();
//下面两行解决Java8新日期API序列化问题
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
//设置所有访问权限以及所有的实际类型都可序列化和反序列化
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
valueSerializer.setObjectMapper(objectMapper);
System.out.println("--------------------");
@Bean(name = "cacheManager")
public RedisCacheManager cacheManager(RedisConnectionFactory factory)
// 配置序列化(解决乱码的问题),通过config对象对缓存进行自定义配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(this.timeToLive)// 设置缓存的默认过期时间
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer))
.disableCachingNullValues();
// 不缓存空值//缓存配置
Map<
String,RedisCacheConfiguration>
cacheConfig=new HashMap<
>
();
//自定义缓存名,后面使用的@Cacheable的CacheName
cacheConfig.put("dept",config);
//根据redis缓存配置和reid连接工厂生成redis缓存管理器
RedisCacheManager redisCacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.transactionAware()
.withInitialCacheConfigurations(cacheConfig)
.build();
return redisCacheManager;
//缓存键自动生成器
@Override
@Bean(name = "myKeyGen")
public KeyGenerator keyGenerator()//设置自定义keyClassName + methodName + params
return (target, method, params) ->
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(".");
sb.append(method.getName());
sb.append("(");
for (int i = 0;
i <
params.length;
i++)
sb.append(params[i].toString());
if (i != (params.length - 1))
sb.append(",");
sb.append(")");
return sb.toString();
;
//自定义keyGenerator,Key生成器
@Bean(name = "updateByIdKeyGen")
public KeyGenerator updateByIdkeyGenerator()
return (target, method, params) ->
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(".");
sb.append("findDeptByDeptno(");
try
Field id = params[0].getClass().getDeclaredField("deptno");
id.setAccessible(true);
sb.append(id.get(params[0]).toString());
catch (IllegalAccessException e)
e.printStackTrace();
catch (NoSuchFieldException e)
e.printStackTrace();
sb.append(")");
return sb.toString();
;
//自定义keyGenerator,Key生成器
@Bean(name = "deleteByIdKeyGen")
public KeyGenerator deleteByIdkeyGenerator()
return (target, method, params) ->
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(".");
sb.append("findDeptByDeptno(");
for (int i = 0;
i <
params.length;
i++)
sb.append(params[i].toString());
if (i != (params.length - 1))
sb.append(",");
sb.append(")");
return sb.toString();
;
/**
* @param factory
* @return
*/
@Bean(name = "redisTemplate")
public RedisTemplate<
String,Object>
redisTemplate(RedisConnectionFactory factory)
RedisTemplate<
String,Object>
redisTemplate = new RedisTemplate<
>
();
//配置连接工厂
redisTemplate.setConnectionFactory(factory);
//设置key的序列化规则
redisTemplate.setKeySerializer(keySerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(keySerializer);
//设置value的序列化规则
redisTemplate.setValueSerializer(valueSerializer);
// hash的value序列化方式采用jackson
redisTemplate.setHashValueSerializer(valueSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
在SpringBoot2.0之后,spring容器自动的生成了StringRedisTemplate和RedisTemplate< Object,Object> ,可以直接注入。但是在实际使用中,大多情况下不会直接使用RedisTemplate< Object,Object> ,而是会对key和value进行序列化,所以我们还需要新增一个配置类。
第三步:Redis工具类参看博客:Redis工具类:RedisTemplate
第四步:实体类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Dept implements Serializable
private static final long serialVersionUID = -1092294594385392402L;
private Integer deptno;
private String dname;
private String loc;
第五步:Service 接口及实现类: DeptService.java
public interface DeptService
Dept findDeptByDeptno(Integer deptno);
Dept updateDept(Dept dept);
Dept deleteDeptByDeptno(Integer deptno);
DeptServiceImpl.java
@Service
@CacheConfig(cacheManager = "cacheManager", cacheNames = "dept")
public class DeptServiceImpl implements DeptService
@Override
@Cacheable(keyGenerator = "myKeyGen")
public Dept findDeptByDeptno(Integer deptno)
System.out.println("DeptService findDeptByDeptno ...");
return new Dept(10, "aa", "aaaaaaa");
@CachePut(keyGenerator = "updateByIdKeyGen")
@Override
public Dept updateDept(Dept dept)
System.out.println("DeptService updateDept ...");
return new Dept(10, "123", "rewrweq");
@CacheEvict(keyGenerator = "deleteByIdKeyGen")
@Override
public Dept deleteDeptByDeptno(Integer deptno)
System.out.println("DeptService deleteDeptByDeptno ...");
return new Dept(10, "aa", "aaaaaaa");
第六步:Controller层:
@RestController
@RequestMapping("/redis")
public class DemoController
@Autowired
private RedisUtil redisUtil;
//http://localhost:8080/redis/setStr?key=ab&
value=https://www.songbingjia.com/android/aaabbb
@RequestMapping("/setStr")
public String setStr(String key, String value)
redisUtil.set(key, value);
return "success";
//http://localhost:8080/redis/getStr?key=ab
@RequestMapping("/getStr")
public Object getStr(String key)
return redisUtil.get(key);
//http://localhost:8080/redis/setList?key=abc&
value1=aa&
value2=bb&
value3=cc
@RequestMapping("/setList")
public String setList(String key, String value1, String value2, String value3)
List<
String>
list = new ArrayList<
>
();
list.add(value1);
list.add(value2);
list.add(value3);
redisUtil.lSets(key, Collections.singletonList(list));
return "success";
@Resource
private DeptService deptService;
@RequestMapping("/findDeptByDeptno/deptno")
public Dept getEmpByEmpno(@PathVariable("deptno") int deptno)
return deptService.findDeptByDeptno(deptno);
测试 运行程序,在网页中进行测试。 DeptService测试
@RunWith(SpringRunner.class)
@SpringBootTest
class DeptServiceImplTest @Resource
private DeptService deptService;
@Test
void findDeptByDeptno()
Dept dept = deptService.findDeptByDeptno(10);
System.out.println(dept);
@Test
void updateDept()
Dept dept0 = new Dept(10,"abc","cba");
Dept dept = deptService.updateDept(dept0);
System.out.println(dept);
@Test
void deleteDeptByDeptno()
Dept dept = deptService.deleteDeptByDeptno(10);
System.out.println(dept);
推荐阅读
- linux Apache设置https访问以及加载mod_ssl.so模块以及问题解决
- 算法 | 第3章 栈与队列相关《程序员面试金典》#yyds干货盘点#
- Redis数据类型详细讲解(sethashzset)
- Shell脚本基本编辑规范及变量
- #yyds干货盘点#十大经典排序之(基数排序 |计数排序)
- 流水线pipeline招式之声明式(前篇)
- go -Unmarshal 错误的几种情况
- #yyds干货盘点#ECMAScript 6 - Symbol
- vue日期转换及时区问题 #yyds干货盘点#