Spring boot 集成Redis

柳彪
• 阅读 9488

Redis安装

Redis的安装网上文档很多,官方也有非常详细的安装文档,这里就不再赘述,如果是个人开发,建议使用Docker进行安装,只需以下一行命令即可完成完整

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

执行以下命令查看是否运行成功

➜ docker exec -it redis redis-cli 
127.0.0.1:6379> ping
PONG

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.1
spring.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
@EnableCaching
public 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
 */
@Configuration
public 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-cli
127.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);
    }

}
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Wesley13 Wesley13
3年前
ubuntu 18.04 安装 Redis
Redis安装Redis是一款内存键值存储,以其灵活性,性能和广泛的语言支持而闻名。本教程将演示如何在Ubuntu18.04服务器上安装和配置Redis。主要内容包括:1.安装Redis2.Redis配置3.Redis控制一、安装Redis使用apt从官方Ubuntu
Stella981 Stella981
3年前
Linux查看GPU信息和使用情况
1、Linux查看显卡信息:lspci|grepivga2、使用nvidiaGPU可以:lspci|grepinvidia!(https://oscimg.oschina.net/oscnet/36e7c7382fa9fe49068e7e5f8825bc67a17.png)前边的序号"00:0f.0"是显卡的代
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Nginx + lua +[memcached,redis]
精品案例1、Nginxluamemcached,redis实现网站灰度发布2、分库分表/基于Leaf组件实现的全球唯一ID(非UUID)3、Redis独立数据监控,实现订单超时操作/MQ死信操作SelectPollEpollReactor模型4、分布式任务调试Quartz应用
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
Java服务使用Redis实现分布式全局唯一标识
此处以SpringBoot为例,示范如何使用Redis构造全局唯一标识.1\.RedisTemplate配置spring.redis.database0spring.redis.hostspring.redis.port6379spring.