SpringBoot整合redis

SpringBoot整合

SpringBoot 操作数据:spring-data jpa jdbc mongodb redis!

SpringData 也是和 SpringBoot 齐名的项目!

说明: 在 SpringBoot2.x 之后,原来使用的jedis 被替换为了 lettuce?
jedis : 采用直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用 jedis pool 连接

池! 更像 BIO 模式
lettuce : 采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据

了,更像 NIO 模式

RedisAutoConfiguration自动配置类

自动配置类springboot已经帮我们写好,来看看源码

源码分析,下面是springboot中 RedisAutoConfiguration自动配置类 的源码中的方法

java 复制代码
@Bean
@ConditionalOnMissingBean(name = "redisTemplate") // 我们可以自己定义一个
redisTemplate来替换这个默认的!
public RedisTemplate<Object, Object>redisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
    // 默认的 RedisTemplate 没有过多的设置,redis 对象都是需要序列化!
    // 两个泛型都是 Object, Object 的类型,我们后使用需要强制转换 <String, Object>
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}
@Bean
@ConditionalOnMissingBean // 由于 String 是redis中最常使用的类型,所以说单独提出来了一
个bean!
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

整合测试一下

  1. 导入springboot-redis的 依赖
xml 复制代码
<!-- 操作redis -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置连接,在application.properties中
xml 复制代码
# 配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
  1. 测试!在测试类中自动装配RedisTemplate(因为springboot已经通过RedisAutoConfiguration配置类帮我们注入了RedisTemplate),然后通过RedisTemplate 去操作 Redis
java 复制代码
@SpringBootTest
class Redis02SpringbootApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void contextLoads() {
        // redisTemplate 操作不同的数据类型,api和我们的指令是一样的
        // opsForValue 操作字符串 类似String
        // opsForList 操作List 类似List
        // opsForSet
        // opsForHash
        // opsForZSet
        // opsForGeo
        // opsForHyperLogLog
        // 除了进本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务,和基本的 CRUD
        // 获取redis的连接对象
        // RedisConnection connection =
        redisTemplate.getConnectionFactory().getConnection();
        // connection.flushDb();
        // connection.flushAll();
        redisTemplate.opsForValue().set("mykey","关注狂神说公众号");
        System.out.println(redisTemplate.opsForValue().get("mykey"));
    }
}


关于对象的保存:

对象没有序列化传输保存会报错

序列化对象,才能在redis的value中正常保存并获取对象

java 复制代码
public class User implements Serializable {
    private String name;
    private int age;
}

自定义RedisTemplete

默认序列化是jdk的序列化方式,自定义RedisTemplete配置config可以自定义序列化方式

可以自己配置具体的序列化方式,代码如下所示我们来编写一个自己的 RedisTemplete(下面是一个固定的模板,可以直接用)

自己写一个配置类,注入自己定义的RedisTemplate

java 复制代码
package com.kuang.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
    // 这是我给大家写好的一个固定模板,大家在企业中,拿去就可以直接使用!
    // 自己定义了一个 RedisTemplate
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 我们为了自己开发方便,一般直接使用 <String,Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String,Object>();
        template.setConnectionFactory(factory);
        //Json序列化配置,创建序列化方式的对象
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
        Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        
        // String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

所有的redis操作,其实对于java开发人员来说,十分的简单,更重要是要去理解redis的思想和每一种数据结构的用处和作用场景!

在测试test中使用自定义的RedisTemplete

首先自动装配,因为在配置类中注入过了

装配时要选择自定义的RedisTemplate而不是源码中的

自定义RedisTemplete后测试

java 复制代码
    //保存对象到redis
    @Test
    public void test() throws JsonProcessingException {
        User user = new User("hhb", 20);

        //String jsonUser = new ObjectMapper().writeValueAsString(user);  //转换为json字符串
        redisTemplate.opsForValue().set("user",user);
        System.out.println(redisTemplate.opsForValue().get("user"));
    }

结果

因为key 已经采用 String序列化方式

自定义RedisTemplate并为其设置序列化方式之前,key是乱码

在企业开发中,大部分情况下都不会使用原生方式编写redis

不会像下面这样

编写RedisUtils代替原生(操作RedisTemplate)的方式

在真实开发中,或者公司,一般都会看到一个封装的 RedisUtil工具类文件(在文章标题处给出RedisUtil工具类附件),因为文件代码太长所以提供文件附件(百度csdn中应该也有很多容易搜到)

示例部分代码如下,都是封装了一些redis的操作,把redis的操作封装为了RedisUtils的方法。

java 复制代码
@Component
@SuppressWarnings({"unchecked", "all"})
public class RedisUtils {
    private static final Logger log = LoggerFactory.getLogger(RedisUtils.class);
    private RedisTemplate<Object, Object> redisTemplate;
    // @Value("${jwt.online-key}")
    // private String onlineKey;

    public RedisUtils(RedisTemplate<Object, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        this.redisTemplate.setKeySerializer(new StringRedisSerializer());
        this.redisTemplate.setStringSerializer(new StringRedisSerializer());
    }

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
        return true;
    }

    /**
     * 指定缓存失效时间
     *
     * @param key      键
     * @param time     时间(秒)
     * @param timeUnit 单位
     */
    public boolean expire(String key, long time, TimeUnit timeUnit) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, timeUnit);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
        return true;
    }

    /**
     * 根据 key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(Object key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
}

测试,使用redisUtils操作redis

因为RedisUtils被注册成了组件,所以可以Autowired自动装配

输出结果如下

相关推荐
Victor35635 分钟前
MySQL(138)如何设置数据归档策略?
后端
Victor35636 分钟前
MySQL(137)如何进行数据库审计?
后端
白仑色4 小时前
Spring Cloud Gateway 实战指南
spring boot·微服务·路由转发·限流熔断
Hello.Reader5 小时前
RedisJSON 路径语法深度解析与实战
数据库·redis·缓存
设计师小聂!8 小时前
Linux系统中部署Redis详解
linux·运维·数据库·redis
Touper.8 小时前
Redis 基础详细介绍(Redis简单介绍,命令行客户端,Redis 命令,Java客户端)
java·数据库·redis
FreeBuf_8 小时前
黄金旋律IAB组织利用暴露的ASP.NET机器密钥实施未授权访问
网络·后端·asp.net
张小洛9 小时前
Spring AOP 是如何生效的(入口源码级解析)?
java·后端·spring
追风少年浪子彦10 小时前
mapstruct与lombok冲突原因及解决方案
java·spring boot·spring·spring cloud
军军君0110 小时前
基于Springboot+UniApp+Ai实现模拟面试小工具四:后端项目基础框架搭建下
spring boot·spring·面试·elementui·typescript·uni-app·mybatis