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自动装配

输出结果如下

相关推荐
空谷忧人11 分钟前
【SpringMVC】详细介绍SpringMVC的执行流程
java·后端·mvc·springmvc
小灵蛇1 小时前
网络基础入门
linux·网络·后端
LiberInfo1 小时前
Docker + Nacos + Spring Cloud Gateway 实现简单的动态路由配置修改和动态路由发现
java·spring boot·spring cloud·docker·nacos·gateway·动态路由
AskHarries4 小时前
Spring Boot集成protobuf快速入门Demo
java·spring boot·后端·protobuf
熬夜苦读学习6 小时前
C++的STL简介(四)
c语言·开发语言·c++·后端
一只懒鱼a7 小时前
SpringBoot 集成原生 Servlet、Filter、Listener
java·spring boot·后端·spring
未来的JAVA高级开发工程师7 小时前
使用SpringAOP实现公共字段填充
java·开发语言·后端·spring·mybatis
2401_844137577 小时前
Java灵活用工兼职全职报价单微信小程序+APP+微信公众号源码
开发语言·后端·微信·微信小程序·小程序·架构·微信开放平台
Li清水8 小时前
Spring 框架面试题
后端
JohnYan8 小时前
我也来爬一爬12306 - Day2 主页和车站
后端·爬虫·node.js