初识redis

how to use redis in springBoot?

Posted by lily on April 17, 2023

springBoot整合redis


spring使用redis原理

spring提供了一个RedisConnectionFactory接口,获取Redisconnection接口对象。由于现在使用的是jedis驱动,所以spring就会提供RC接口的实现类JedisConnectionFactory,通过JedisConnectionFactory获取JedisConnection接口的实现类JedisConnection,通过JedisConnection来操作redis数据库。 所以顶级接口是redisConnction,我们可以通过它来操作redis数据。

RedisTemplate核心类

但由于使用jedisFoctory需要自己打开连接和关闭,所以spring提供了RedisTemplate来操作redis,它是一个模板类,提供了一些操作redis的方法,比如:

等,我们可以通过这些方法来操作redis数据库。

#### Spring-RedisTemplate的创建
```java
@Bean(name = "redisTemplate")
public RedisTemplate<object, object> initRedisTemplate(){
    RedisTemplate<object, object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(initConnectionFactory());
    return redisTemplate;
}
//  然后使用annotationCongigApplicationContext来获取redisTemplate即可

redis序列化器

redisTemplate默认使用的是JdkSerializationRedisSerializer,这个序列化器是使用jdk的序列化器来序列化对象的,他会把可序列化对象转为复杂的二进制字符串redis中键(key)也是以字符串的形式存储的也会被转换为复杂字符串,无法读取, 所以需要更改自定义Java对象为String时的序列化器,用StringRedisSerializer,它会使得spring把redis的key当作字符串处理

// hash 键值
setHashKeySerializer(StringRedisSerializer());
setHashValueSerializer(StringRedisSerializer());
// Key
setKeySerializer(StringRedisSerializer());

数据类型封装


redis特点以及为什么要使用redis

  • redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
  • redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • 速度:redis的读写速度非常快的,单机每秒可以执行110000次读写操作。
  • 为什么要使用redis:

先学习spring整合redis

在spring中使用redis


redis缓存机制

springBoot使用方式

  1. 启用注解缓存:在sb启动类上使用@EnableCaching
  2. spring支持多种缓存的使用,并提供了CacheManger与之相关的类
  3. redis使用的缓存管理器是RedisCacheManager,
  4. springBoot允许我们使用配置文件生成缓存管理器 在配置文件中配置redis的连接信息
    spring:
     data:
      redis:
       port: 6379
       password: ***
       # boot天然支持jedis连接驱动,这里配置了jedis的连接池信息
       jedis:
         pool:
           min-idle: 5
           max-idle: 10
           max-active: 10
           max-wait: 2000
     cache:
     # 重点是这里,配置了缓存的类型为redis,缓存的名称为redisCache
       type: redis
       cache-names: redisCache
    

为什么要使用redis缓存

  • 通过使用redis缓存机制,在需要大量查询、更改数据的过程中可以采取先从redis Cache中读取或存放一部分数据,加快响应速度,减少数据库的压力,提高系统的响应速度。
  • 所以可以在用户与数据库之间加入redis缓存,当用户第一次访问数据库时,将数据存入redis缓存中,当用户再次访问时,先从redis缓存中读取数据,如果redis缓存中没有数据,再从数据库中读取数据,并将数据存入redis缓存中。

    在controller中使用redis缓存

    service层

      @Autowired
      private UserDao userDao = null;
    
      @Transactional
      @Cashable(value = "redisCache",key = "redis_user_"+"#id")
      public User getUser(int id){
          return useDao.getUser();
      }
    
      @Transactional
      @CashEvict(value = "redisCache",key = "redis_user_"+"#id", beforeInvocation = false)
      public void deleteUser(int id){
          userDao.deleteUser(id);
      }
    
      @Transactional
      @CashPut(value = "redisCache", condition="#result != null", key = "redis_user_"+"#id")
      public User updateUser(int id, String name){
          User user = userDao.getUser(id);
          if (user == null)
              return null;
          user.setName(name);
          userDao.updateUser(user);
          return user;
      }
    

在controller中加入从缓存中操作数据的逻辑

    
    @Autowired
    private UserService userService;

    @RequestMapping("/getUser")
    public User getUser(){
        User user = (User) redisTemplate.opsForValue().get("user");
        if(user == null){
            user = userService.getUser();
            redisTemplate.opsForValue().set("user",user);
        }
        return user;
    }
    ....

注解含义

@Cashable:先从缓存中通过自定义键查询,如果可以查询到数据,则直接返回,如果查询不到数据,则执行方法体,将方法返回值存入缓存中。

@CashEvict:通过自定义的键移除缓存,beforeInvocation = false表示在方法执行之后移除缓存,beforeInvocation = true表示在方法执行之前移除缓存。默认值为false。

@CashPut:先执行方法体,将方法返回值存入缓存中,condition表示在满足条件的情况下才会将方法返回值存入缓存中。

其中参数value表示redis缓存(redis可以有多个缓存库)的名称,key表示缓存的键,其中使用了SpEL表达式,

condition表示在满足条件(返回true)的情况下才会将方法返回值存入缓存中,三个注解都可以使用这个参数

很多时候可以看到”redis_user_”+”#id”,id来源于方法参数

“#result”代表返回结果对象,”result.id”就代表返回这个user对象的id属性了