Redis装置

Redis的装置网上文档很多,官网也有十分具体的装置文档,这里就不再赘述,如果是集体开发,倡议应用Docker进行装置,只需以下一行命令即可实现残缺

docker run -itd --name redis -p 6379:6379 redis

执行以下命令查看是否运行胜利

➜ docker exec -it redis redis-cli 127.0.0.1:6379> pingPONG

Spring boot集成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>
  • 配置
spring.redis.host=127.0.0.1spring.redis.port=6379#客户端超时spring.redis.timeout=10000#最大连接数spring.redis.lettuce.pool.max-active=20#最小闲暇spring.redis.lettuce.pool.min-idle=5#连贯超时spring.redis.lettuce.pool.max-wait=5000ms#最大闲暇spring.redis.lettuce.pool.max-idle=20
  • 启动类增加注解@EnableCaching
@SpringBootApplication@EnableCachingpublic class RedisApplication {    public static void main(String[] args) {        SpringApplication.run(RedisApplication.class, args);    }}
  • 编写配置类,能够参考以下代码
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.cache.RedisCacheWriter;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.*;import java.time.Duration;import java.util.HashMap;import java.util.Map;/** * @Description: * @author: jianfeng.zheng * @since: 2021/3/3 10:53 下午 * @history: 1.2021/3/3 created by jianfeng.zheng */@Configurationpublic class RedisConfig {    @Bean    RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();        redisTemplate.setConnectionFactory(redisConnectionFactory);        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());        redisTemplate.setKeySerializer(new StringRedisSerializer());        redisTemplate.setHashKeySerializer(new StringRedisSerializer());        redisTemplate.afterPropertiesSet();        return redisTemplate;    }    @Bean    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));        redisCacheConfiguration.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));        Map<String, RedisCacheConfiguration> redisExpireConfig = new HashMap<>();        //这里设置了一个一分钟的超时配置,如果须要减少更多超时配置参考这个新增即可        redisExpireConfig.put("1min", RedisCacheConfiguration.defaultCacheConfig()                              .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))                .entryTtl(Duration.ofMinutes(1)).disableCachingNullValues());                RedisCacheManager redisCacheManager = RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))                .cacheDefaults(redisCacheConfiguration)                .withInitialCacheConfigurations(redisExpireConfig)                .transactionAware()                .build();        return redisCacheManager;    }}
Spring boot 1.x的redis配置和Spring boot 2.x的redis配置有很大差异,次要是2.x应用了lettuce客户端,所以网上看到的一些1.x的参考代码在2.x无奈应用
  • 一个简略的示例
@RestController@RequestMapping(value = "/user")public class UserController {    @GetMapping(value = "/info")    @Cacheable(value = "user", key = "#uid")    public User getUser(@RequestParam(value = "uid") String uid) {        System.out.println("getUser====>" + uid);        User user = new User();        user.setUid(uid);        user.setEmail(uid + "@definesys.com");        user.setName(uid + ":" + System.currentTimeMillis());        return user;    }}

@Cacheable(value = "user", key = "#uid")注解将开启缓存,接口返回的数据将会被缓存,value是缓存的名称,key是缓存的健,能够应用SpEL表达式。

用curl调用接口

➜  curl  http://localhost:8089/user/info\?uid\=jianfeng {"uid":"jianfeng","name":"jianfeng:1614870102913","email":"jianfeng@definesys.com"}%                         

redis-cli登录redis查看

➜  skywalking git:(master) ✗ docker exec -it redis redis-cli127.0.0.1:6379> keys *1) "user::jianfeng"127.0.0.1:6379> get user::jianfeng{    "@class": "com.poc.redis.User",    "uid": "jianfeng",    "name": "jianfeng:1614870102913",    "email": "jianfeng@definesys.com"}127.0.0.1:6379> ttl user::jianfeng(integer) -1

能够看到,redis创立了一个名称为user::jianfeng的键,值为java对象的JSON字符串,并且减少了一个@class的字段示意序列化的类,该缓存过期工夫为-1也就是永不过期。这时候再用curl测试会发现后果还是一样的

➜  curl  http://localhost:8089/user/info\?uid\=jianfeng {"uid":"jianfeng","name":"jianfeng:1614870102913","email":"jianfeng@definesys.com"}% 

如果没有缓存,因为咱们name字段的代码是 user.setName(uid + ":" + System.currentTimeMillis());所以实践上每次调用都应该不一样,因为有了缓存所以办法逻辑不会被执行,间接从缓存中取出数据。

缓存过期工夫

咱们在缓存配置类外面设置了一个1min的配置

redisExpireConfig.put("1min", RedisCacheConfiguration.defaultCacheConfig()                              .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))

咱们批改下代码

@Cacheable(value = "1min", key = "#uid")public User getUser(@RequestParam(value = "uid") String uid) {...}

调用接口后查看redis缓存数据

➜  docker exec -it redis redis-cli                     127.0.0.1:6379> keys *1) "1min::jianfeng"127.0.0.1:6379> ttl 1min::jianfeng(integer) 45

这时候你一直的执行ttl 1min::jianfeng命令会发现工夫在缩小,当缩小到0时,redis就会革除掉缓存

Cacheable能够指定多个名称 @Cacheable(value = {"1min", "2min"}, key = "#uid")这样只有其中任何一个缓存无效都能失去数据

缓存相干注解

除了Cacheable还有其余跟缓存相干的注解

  • CachePut

CachePut能够将数据放入缓存,个别insert操作和update操作能够应用该注解,如果指定的key数据存在就更新数据

  • CacheEvict

CacheEvict能够删除缓存数据,个别delete操作的接口能够应用该注解

  • Caching

Caching是三个的汇合,定义如下

public @interface Caching {    Cacheable[] cacheable() default {};    CachePut[] put() default {};    CacheEvict[] evict() default {};}

一个残缺的增删改查缓存例子

@RestController@RequestMapping("user")public class RedisController {    @Autowired    private UserMapper userMapper;    @PostMapping("/add")    @CachePut(value = "neverExpire", key = "#user.uid")    public User add(@RequestBody User user) {        userMapper.insert(user);        return user;    }    @PostMapping("/update")    @CachePut(value = "neverExpire", key = "#user.uid")    public User update(@RequestBody User user) {        return user;    }    @GetMapping("/delete")    @CacheEvict(value = "neverExpire", key = "#uid")    public String delete(@RequestParam(value = "uid") String uid) {        return uid;    }    @GetMapping("/detail")    @Cacheable(value = "neverExpire", key = "#result")    public User deteail(@RequestParam(value = "uid") String uid) {        QueryWrapper<User> queryWrapper = new QueryWrapper<>();        queryWrapper.eq("uid", uid);        return userMapper.selectOne(queryWrapper);    }}