Spring Boot demo系列 :Redis缓存

简介: 目录Spring Boot demo系列 :Redis缓存12.2.1 手动添加`@class`12.2.2 将实体类设置为`open`

Spring Boot demo系列 :Redis缓存


本文演示了如何在Spring Boot中将Redis作为缓存使用,具体的内容包括:

  • 环境搭建
  • 项目搭建
  • 测试
  • Redis
  • MySQL
  • MyBatis Plus


Redis安装非常简单,以笔者的Manjaro为例,直接paru安装:

paru -S redis


UbuntuCentOS之类的都提供了软件包安装:


sudo apt install redis
sudo yum install redis


如果想从源码编译安装:


wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make


Windows以及其他系统的安装可以参考此处

新建项目,加入如下依赖:

Maven


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>


Gradle


implementation("com.baomidou:mybatis-plus-boot-starter:3.4.2")
implementation("mysql:mysql-connector-java:8.0.23")


项目结构:


9.png


MyBatis Plus+Redis配置类:


@Configuration
@MapperScan("com.example.demo.dao")
public class MyBatisPlusConfig {
}
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableCaching
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(factory);
        return template;
    }
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
        .serializeKeysWith(
            RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())
        ).serializeValuesWith(
            RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())
        );
        return RedisCacheManager.builder(factory).cacheDefaults(configuration).build();
    }
}


重点说一下Redis配置类,这个类主要生成两个Bean:


RedisTemplate:简化Redis操作的数据访问类

CacheManager:Spring的中央缓存管理器

其中RedisTemplate是一个模板类,第一个参数的类型是该template使用的键的类型,通常是String,第二个参数的类型是该template使用的值的类型,通常为Object或Seriazable。


setKeySerializer和setValueSerializer分别设置键值的序列化器。键一般为String类型,可以使用自带的StringRedisSerializer。对于值,可以使用自带的GenericJackson2RedisSerializer。


CacheManager的配置类似,就不重新说了。


@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String name;
}


public interface UserMapper extends BaseMapper<User> {
}


@org.springframework.stereotype.Service
@Transactional
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class Service {
    private final UserMapper mapper;
    @CachePut(value = "user",key = "#user.id")
    public User save(User user){
        User oldUser = mapper.selectById(user.getId());
        if(oldUser == null){
            mapper.insert(user);
            return user;
        }
        if(mapper.updateById(user) == 1)
            return user;
        return oldUser;
    }
    @CacheEvict(value = "user",key = "#id")
    public boolean delete(Integer id){
        return mapper.deleteById(id) == 1;
    }
    @Cacheable(value = "user",key = "#id")
    public User select(Integer id){
        return mapper.selectById(id);
    }
    @Cacheable(value="allUser",key = "#root.target+#root.methodName")
    //root.target是目标类,这里是com.example.demo.Service,root.methodName是方法名,这里是selectAll
    public List<User> selectAll(){
        return mapper.selectList(null);
    }
}


注解说明如下:

  • @CachePut:执行方法体再将返回值缓存,一般用于更新数据
  • @CacheEvict:删除缓存,一般用于删除数据
  • @Cacheable:查询缓存,如果有缓存就直接返回,没有缓存的话执行方法体并将返回值存入缓存,一般用于查询数据


三个注解都涉及到了key以及value属性,实际上,真正的存入Rediskey是两者的组合,比如:


@Cacheable(value="user",key="#id")


则存入的Redis中的key为:


10.png


而存入对应的值为方法返回值序列化后的结果,比如如果返回值为User,则会被序列化为:


11.png


spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
logging:
  level:
    com.example.demo: debug


spring.redis.database指定数据库的索引,默认为0,hostport分别指定主机(默认本地)以及端口(默认6379)。

也就是说,简单配置的话可以完全省略Redis相关配置,仅指定数据库连接url、用户名以及密码:


spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456
logging:
  level:
    com.example.demo: debug


Redis服务器启动需要一个配置文件,默认位置为/etc/redis.conf(源码编译安装的话在源文件夹内),建议先复制一份:


cp /etc/redis.conf ~/Desktop/


默认的配置文件为单机Redis配置,端口6379redis-server可以直接运行:


sudo redis-server redis.conf


连接可以通过自带的redis-cli命令:


redis-cli -h localhost -p 6379


默认情况下可以直接使用


redis-cli


连接。

基本操作:

  • keys *:查询所有键
  • get key:查询key所对应的值
  • flushall:清空所有键


12.png


@SpringBootTest
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
class DemoApplicationTests {
    private final Service service;
    @Test
    void select() {
        service.select(1);
        service.select(1);
    }
    @Test
    void selectAll(){
        service.selectAll();
        service.selectAll();
    }
    @Test
    void delete(){
        service.delete(1);
    }
    @Test
    void save(){
        User user = new User(1,"name1");
        service.save(user);
        service.select(user.getId());
        user.setName("name2");
        service.save(user);
        service.select(user.getId());
    }
}


执行其中的select,会发现MyBatis Plus只有一次select的输出,证明缓存生效了:


13.png


而把缓存注解去掉后,会有两次select输出:


14.png


其它测试方法就不截图了,原理类似。

其实@Cacheable/@CacheEvict/@CachePut中的value都是String [],在Java中可以直接写上value,在Kotlin中需要[value]

序列化到Redis时,实体类会被加上一个@class字段:


15.png


这个标识供Jackson反序列化时使用,笔者一开始的实体类实现是:


data class User(var id:Int?=null, var name:String="")


但是序列化后不携带@class字段:


16.png


在反序列化时直接报错:

Could not read JSON: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class'
 at [Source: (byte[])"{"id":1,"name":"name2"}"; line: 1, column: 23]; nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class'
 at [Source: (byte[])"{"id":1,"name":"name2"}"; line: 1, column: 23]


解决方法有两个:

  • 手动添加@class字段
  • 将实体类设为open


12.2.1 手动添加@class


准确来说并不是手动添加,而是让注解添加,需要添加一个类注解@JsonTypeInfo


@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
data class User(var id:Int?=null, var name:String="")


该注解的use用于指定类型标识码,该值只能为JsonTypeInfo.Id.CLASS


12.2.2 将实体类设置为open


在Java中,实体类没有任何额外配置,Redis序列化/反序列化一样没有问题,是因为值序列化器GenericJackson2JsonRedisSerializer,该类会自动添加一个@class字段,因此不会出现上面的问题。


但是在Kotlin中,类默认不是open的,也就是无法添加@class字段,因此便会反序列化失败,解决方案是将实体类设置为open:


open class User(var id:Int?=null, var name:String="")

但是缺点是不能使用data class了。

Java版:

Kotlin版:


目录
相关文章
|
NoSQL 安全 Java
深入理解 RedisConnectionFactory:Spring Data Redis 的核心组件
在 Spring Data Redis 中,`RedisConnectionFactory` 是核心组件,负责创建和管理与 Redis 的连接。它支持单机、集群及哨兵等多种模式,为上层组件(如 `RedisTemplate`)提供连接抽象。Spring 提供了 Lettuce 和 Jedis 两种主要实现,其中 Lettuce 因其线程安全和高性能特性被广泛推荐。通过手动配置或 Spring Boot 自动化配置,开发者可轻松集成 Redis,提升应用性能与扩展性。本文深入解析其作用、实现方式及常见问题解决方法,助你高效使用 Redis。
1469 4
|
11月前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
883 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
11月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
1821 5
|
11月前
|
存储 缓存 Java
Spring中@Cacheable、@CacheEvict以及其他缓存相关注解的实用介绍
缓存是提升应用性能的重要技术,Spring框架提供了丰富的缓存注解,如`@Cacheable`、`@CacheEvict`等,帮助开发者简化缓存管理。本文介绍了如何在Spring中配置缓存管理器,使用缓存注解优化数据访问,并探讨了缓存的最佳实践,以提升系统响应速度与可扩展性。
458 0
Spring中@Cacheable、@CacheEvict以及其他缓存相关注解的实用介绍
|
NoSQL Java Redis
Redis基本数据类型及Spring Data Redis应用
Redis 是开源高性能键值对数据库,支持 String、Hash、List、Set、Sorted Set 等数据结构,适用于缓存、消息队列、排行榜等场景。具备高性能、原子操作及丰富功能,是分布式系统核心组件。
851 2
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
409 32
|
存储 缓存 NoSQL
Spring Cache缓存框架
Spring Cache是Spring体系下的标准化缓存框架,支持多种缓存(如Redis、EhCache、Caffeine),可独立或组合使用。其优势包括平滑迁移、注解与编程两种使用方式,以及高度解耦和灵活管理。通过动态代理实现缓存操作,适用于不同业务场景。
820 0
|
NoSQL Java API
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Spring Boot 集成 Redis
本文介绍了在Spring Boot中集成Redis的方法,包括依赖导入、Redis配置及常用API的使用。通过导入`spring-boot-starter-data-redis`依赖和配置`application.yml`文件,可轻松实现Redis集成。文中详细讲解了StringRedisTemplate的使用,适用于字符串操作,并结合FastJSON将实体类转换为JSON存储。还展示了Redis的string、hash和list类型的操作示例。最后总结了Redis在缓存和高并发场景中的应用价值,并提供课程源代码下载链接。
2819 0
|
NoSQL Java Redis
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 安装
本教程介绍在 VMware 虚拟机(CentOS 7)或阿里云服务器中安装 Redis 的过程,包括安装 gcc 编译环境、下载 Redis(官网或 wget)、解压安装、修改配置文件(如 bind、daemonize、requirepass 等设置)、启动 Redis 服务及测试客户端连接。通过 set 和 get 命令验证安装是否成功。适用于初学者快速上手 Redis 部署。
487 0
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?