SpringBoot整合Redis 之 lettuce#私藏项目实操分享#

【SpringBoot整合Redis 之 lettuce#私藏项目实操分享#】炒沙作縻终不饱,缕冰文章费工巧。这篇文章主要讲述SpringBoot整合Redis 之 lettuce#私藏项目实操分享#相关的知识,希望能为你提供帮助。
功能说明SpringBoot2.2.6整合Redis,实现

  • 对Redis各种类型数据的操作
  • 业务层查改删缓存的管理
代码下载地址:< a rel=" nofollow" href=https://www.songbingjia.com/android/" https://github.com/hcitlife/IntegrateRedis"> 代码< /a>
第一步:创建项目 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);


    推荐阅读