Spring Boot 实践之九 Spring Boot 缓存管理(默认缓存管理/缓存注解/Spring Boot整合Redis缓存实现/自定义Redis缓存序列化机制)

Spring Boot 实践之九 Spring Boot 缓存管理

​ 缓存是分布式系统中的重要组件,主要解决数据库数据的高并发访问。在实际开发中,尤其是用户访问量较大的网站,用户对高频热点数据的访问非常频繁,为了提高服务器访问性能、减少数据库的压力、提高用户体验,使用缓存显得尤为重要。

​ 本章将针对Spring Boot的缓存管理进行介绍,并完成与Redis缓存中间件的整合使用。

1 Spring Boot默认缓存管理

​ Spring Boot 管理缓存的枋心是将缓存应用于操作数据的方法中,从 而减速少操作数据的次数,同时不会对程序本身造成任何干扰。继承了Spring框架的缓存管理功能,通过使用@EnableCaching注解开启基于注解的缓存支持,Spring Boot可以启动缓存管理的自动化配置。下面我们将针对Spring Boot的默认缓存管理进行讲解。

1.1 基础环境搭建

使用缓存的主要目的是减小数据库数据的访问压力、提高用户体验。为此,这里我们结合数据库的访问操作对Spring Boot的缓存管理进行演示说明。

  1. 准备数据

    • 启动PHPSTUDY,利用我们之前创建好的MYSQL数据库

在这里插入图片描述

  • 运行SQLyogl,查阅数据库及表数据是否正常。关于数据的创建和访问如有疑问请参考前面章节。如图:

在这里插入图片描述

  1. 创建项目

    • 1)使用Spring Initializr方式创建一个Spring Boot项目chapter06,这里将Group设置为com.itheima, Artifact,在Dependencies依赖选择项中JPA依赖、MySQL依赖和Web依赖。依赖选择如图:

在这里插入图片描述

  • 2)编写数据库表对应的实体类。在chapter06中创建名为com.itheima.domain的包,在该包下针对数据库表t_coment编写对应的实体类 Comment,并使用JPA相关注解配置映射关系。Comment.java内容如下:

    package com.itheima.domain;
    
    import javax.persistence.*;
    //步骤2:添加@Entity注解,指定Comment类与数据库中哪张表映射
    @Entity(name = "t_comment")
    public class Comment {
        //步骤1:创建与数据库对应的属性
        @Id //表明映射对应的主键id
        @GeneratedValue(strategy = GenerationType.IDENTITY)  //设置主键自增策略
        private Integer id;
        private String content;
        private String author;
        @Column(name = "a_id") //因为名称不一样,指定aId映射的表字段名为a_id",如果 一致,可以不用此注解。
        private Integer aId;
    
        //步骤3:按Alt+Insert键,选择所有变量生成相关的Getter and Setter方法
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public String getAuthor() {
            return author;
        }
    
        public void setAuthor(String author) {
            this.author = author;
        }
    
        public Integer getaId() {
            return aId;
        }
    
        public void setaId(Integer aId) {
            this.aId = aId;
        }
        //步骤4:按Alt+Insert键,选择所有变量生成相关的toString()方法
    
        @Override
        public String toString() {
            return "Comment{" +
                    "id=" + id +
                    ", content='" + content + '\'' +
                    ", author='" + author + '\'' +
                    ", aId=" + aId +
                    '}';
        }
    }
    
    
  • 3)编写数据库操作的Repository接口文件。

    • 在chapter06中的com.itheima包下创建名为repository的包,并在该包下创建一个用于操作Commetn实体的Repository接口文件,CommentRepository.java文件内容如下:

      package com.itheima.repository;
      
      import com.itheima.domain.Comment;
      import org.springframework.data.jpa.repository.JpaRepository;
      import org.springframework.data.jpa.repository.Modifying;
      import org.springframework.data.jpa.repository.Query;
      
      //步骤1:声明是JpaRepository接口,操作的实体为Comment,主键的数据类型为Integer
      public interface CommentRepository extends JpaRepository<Comment,Integer>{
          //加入@Modifying ,表明这是更新操作
          @Modifying
          //步骤3:根据修改方法的使用,利用JPA方法写数据库操作语句@Query
          @Query("update t_comment c set c.author = ?1 where id=?2")//1?表示该占位符等于下句话的第1个参数author,?2表示该占位符等于第2个参数id
          //步骤2:根据评论id修改评论作者author
          public int updateComment(String author,Integer id);
      }
      
  • 编写业务操作类Service文件,在com.itheima创建service的包,并在该包下创建一个用于Commnet相关业务操作的Service实体类,CommentService.java内容如下:

    //业务操作类,实现查询、删除、更新操作
    package com.itheima.service;
    
    import com.itheima.domain.Comment;
    import com.itheima.repository.CommentRepository;
    import org.hibernate.annotations.Cache;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    
    import java.util.Optional;
    
    //步骤1:加入@Service注解,生成实例,存入容器中
    @Service
    public class CommentService {
        //步骤3:注入@Autowired 注解:可以对实例对象commentRepository进行标注,让 spring 完成 bean 自动装配的工作
        @Autowired
        //步骤2;引入CommentRepository类实例对象,用来完成后续的数据操作
        private CommentRepository commentRepository;
        /*
        * 步骤id查询,返回Comment对象
        * */
    
        public Comment findById(Integer id){
            Optional<Comment> byId = commentRepository.findById(id);
            if(byId.isPresent()){ //判断是否有值
                return byId.get();
            }
            return null;//没值返回空值
        }
    
        /*
         * 步骤5:实现更新操作
         * */
        public int updateComment(Comment comment){//更新操作有无返回值均可
            //updateComment为CommentRepository定义的方法,传递作者和id两个参数
           int i = commentRepository.updateComment(comment.getAuthor(), comment.getId());
            return i;
        }
    
        /*
         * 步骤6:实现删除操作
         * */
        public void deleteComment(Integer id){
            commentRepository.deleteById(id);
        }
    }
    
    
  • 编写Web访问层Controll文件,在com.itheima创建包controller的包,并在该包下创建一个用于Comment访问的Controller实体类,CommentController.java内容如下:

    //编写Web访问层,实现查询、更新、删除控制
    package com.itheima.controller;
    
    import com.itheima.domain.Comment;
    import com.itheima.service.CommentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    //步骤1:加入组合注解@RestController,相当于@Controller+@ResponseBody两个注解的结合
    //@Controller 表明了这个类是一个控制器类。注入服务
    //@ResponseBody 表示方法的返回值直接以指定的格式写入Http response body中,而不是解析为跳转路径
    @RestController
    public class CommentController {
        //步骤2:使用@Autowired对commentService进行标注,让 spring 完成 bean 自动装配的工作
        @Autowired
        private CommentService commentService;
        /*
         * 步骤3:实现查询控制
         * */
        @GetMapping("/get/{id}")//这里的id为路径访问传递过来的值
        public Comment findById(@PathVariable("id") Integer id){//@PathVariable*是spring3.0的一个新功能:接收请求路径中占位符的值
            Comment comment = commentService.findById(id);
            return comment;
        }
    
        /*
         * 步骤4:实现更新操作,需要接收两个参数
         * */
        @GetMapping("/update/{id}/{author}")
        public int updateComment(@PathVariable("id") int id,@PathVariable("author") String author){
            Comment comment = commentService.findById(id);
            comment.setAuthor(author);
            int i = commentService.updateComment(comment);
            return i;
        }
    
        /*
         * 步骤4:实现删除操作,需要接收id参数
         * */
        @GetMapping("/delete/{id}")
        public void deleteById(@PathVariable("id") Integer id){
            commentService.deleteComment(id);
        }
    }
    

这里我们定义了一个CommentController评论管理控制类,使用注入的CommentService对象完成对Comment评论数据的查询、修改和删除操作。

  1. 编写配置文件

    在项目全局配置文件application.properties中编写对应的数据库连接配置,内容如下:

    #MySQL数据库连接配置,请根据自己的数据库配置修正端口,用户名和密码等参数
    spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC
    spring.datasource.username=root
    spring.datasource.password=root
    #显示使用JPA进行数据库查询的SQL语句
    spring.jpa.show-sql=true
    
    
  2. 项目测试

    运行项目主程序Chapter06Application,正常调试项目启动程序 ,如图:

在这里插入图片描述

浏览器访问:http://localhost:8080/get/1,效果如图:

在这里插入图片描述

说明:在application.properties里面配置

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
server.servlet.encoding.enabled=true

可解决部分浏览器访问乱码的问题

分析:http://localhost:8080/get/1会通过在CommentController的findById查询一个comment对象,并把它的响应反馈给前台。对该页面进行刷新,则控制台会访问数据库一次。多次刷新则多次访问。如图:

在这里插入图片描述

当用户增加,数据规模越来越大时,数据库的操作会直接影响用户的体验。此时,使用缓存往往是解决这一问题的非常好的一种手段。下一节我们来开启默认缓存

1.2 Spring Boot默认缓存体验

在前面搭建的Web应用基础上,开启Spring Boot默认支持的缓存

  • 步骤1:在项目启用类前面使用添加@EnableCaching注解,开启Spring Boot默认缓存的管理

    @EnableCaching
    
    
  • 步骤2:使用@Cacheable注解对数据操作方法进行缓存管理。这里,我们将@Cacheable注解标注在Service(业务)类CommentService的查询方法上。

    //使用@Cacheable注解对数据操作方法进行缓存管理
    @Cacheable(cacheNames = "comment")  //把当前根据id查询的结果Comment对象存放在Spring Boot默认缓存中名为comment的名称空间(namespace)中,对应缓存的唯一标识默认为方法参数id的值 
    
    public Comment findById(Integer id){
    
    
  • 步骤3,重启项目主程序类,并用浏览器访问网址http://localhost:8080/get/1,然后多次刷新,我们可以看到控制台显示如图:

在这里插入图片描述

说明:后几次刷新查看的Web内容,默认访问的是缓存内容而不需要再次访问数据库。

2 Spring Boot缓存注解介绍

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 Spring Boot整合Redis缓存实现

3.1 Spring Boot 支持的缓存组件

在这里插入图片描述
在这里插入图片描述

3.2 基于注解的Redis缓存实现

我们在前面第1小节Spring Boot默认缓存管理的基础上引入Redis缓存组件,使用基于注解的方式讲解Spring Boot整合Redis缓存的具体实现。

  • 步骤1:在项目的pom.xml文件中添加Spring Data Redis依赖启动器。

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
  • 步骤2:Redis服务连接配置

    • 1):开启Redis服务。进入之前使用的Redis-x64-3.2.100的文件包中,如图:

在这里插入图片描述

说明:redis-server.exe用于开启Redis服务,redies-cli.exe用于开启客户端工具。

  • 2):双击redis-server.exe指令开启Redis服务。效果如图所示:
    在这里插入图片描述

  • 3)使用一个Redis客户端可视化管理工具Redis Desktop Manager来连接Redis服务进行管理。安装后执行效果如图:
    在这里插入图片描述

说明:name可自定义,Host为本机时,可写为127.0.0.1,端口默认为6379

  • 单击OK,即可进入可视化界面。
    在这里插入图片描述

    • 4)在项目的全局配置文件中application.properties添加Redis服务的连接配置。

      # Redis服务地址
      spring.redis.host=127.0.0.1
      # Redis服务器连接端口
      spring.redis.port=6379
      # Redis连接密码(默认为空)
      spring.redis.password=
      
  • 步骤3:使用@Cacheable、@CachePut、@CacheEvict注解定制缓存管理(参考:https://blog.csdn.net/u012240455/article/details/80844361 )。对CommentService类中的方法进行修改,修改后的内容如文件6-7所示。

    //业务操作类,实现查询、删除、更新操作
    package com.itheima.service;
    
    import com.itheima.domain.Comment;
    import com.itheima.repository.CommentRepository;
    import org.hibernate.annotations.Cache;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.Optional;
    
    //步骤1:加入@Service注解,生成实例,存入容器中
    @Service
    public class CommentService {
        //步骤3:注入@Autowired 注解:可以对实例对象commentRepository进行标注,让 spring 完成 bean 自动装配的工作
        @Autowired
        //步骤2;引入CommentRepository类实例对象,用来完成后续的数据操作
        private CommentRepository commentRepository;
        /*
        * 步骤id查询,返回Comment对象
        * */
        //6.1.2 使用@Cacheable注解对数据操作方法进行缓存管理
        @Cacheable(cacheNames = "comment",unless = "#result==null")  //把当前根据id查询的结果Comment对象存放在Spring Boot默认缓存中名为comment的名称空间(namespace)中,对应缓存的唯一标识默认为方法参数id的值 。
        public Comment findById(Integer id){
            Optional<Comment> byId = commentRepository.findById(id);
            if(byId.isPresent()){ //判断是否有值
                return byId.get();
            }
            return null;//没值返回空值
        }
    
        /*
         * 步骤5:实现更新操作
         * */
        @CachePut(cacheNames = "comment",key = "#result")
        public Comment updateComment(Comment comment){//更新操作有无返回值均可
            //updateComment为CommentRepository定义的方法,传递作者和id两个参数
            int i = commentRepository.updateComment(comment.getId(),comment.getAuthor());
            return i;
        }
    
        /*
         * 步骤6:实现删除操作
         * */
        @CacheEvict(cacheNames = "comment")
        public void deleteComment(Integer id){
            commentRepository.deleteById(id);
        }
    }
    
    
  • 步骤4:启动项目,通过浏览器访:“http://localhost:8080/get/1”,发现浏览器数据响应错误,同时控制台出现异常信息。提示信息要求对应Comment实体类必须实现序列化:DefaultSerializer requires a Serializable payload but received an object of type

  • 步骤5:将缓存对象实现序列化:对Comment类进行改进:

    public class Comment {
    
    

    修改为:

    public class Comment implements Serializable {
    
    

    实现对实体类对象进行缓存存储时先实现序列化(一般基本数据类型不需要序列化)。

  • 再次启动项目,运行基本注解的Redis缓存查询测试,测试效果如图:

在这里插入图片描述

多次刷新,可以从控制台看到,数据库只执行了一次SQL语句。
在这里插入图片描述

打开Redis客户端可视化管理工具Redis Desktop Manager连接本地启用的Redis服务,查看具体的数据缓存效果。如图:
在这里插入图片描述

可以看出,执行findById()方法查询出的用户评论信息Comment正确 存储到了Redis缓存库中名为comment的名称空间下。其唯一标识key值 是以comment::1的字符串形式体现的,而value值 则是以经过JDK默认序列格式化后的HEX格式存储。

  • 步骤6:实践更新操作:

    • 1)在CommentService添加事务支持

      @Transactional
      public class CommentService {
      
      

      访问http://localhost:8080/update/1/shitou效果如图:

在这里插入图片描述

并在控制台可以看到update语句执行:
Hibernate: update t_comment set author=? where id=?
但想重新访问第1条记录时显示500错误
http://localhost:8080/get/1
在这里插入图片描述

  • 2)这是更新访问返回结果为整形i值 ,整形不能转换为Comment存入缓存。修改CommentService的更新操作方法为:

  • @CachePut(cacheNames = "comment",key = "#result.id")
    public Comment updateComment(Comment comment){
        int i = commentRepository.updateComment(comment.getAuthor(), comment.getId());
        Optional<Comment> byId = commentRepository.findById(comment.getId());
        if(byId.isPresent()){ //判断是否有值
            return byId.get();
        }
        return null;//没值返回空值
    }
    
    
    • 2)修改CommentController的更新操作方法及其返回值:

      public Comment updateComment(@PathVariable("id") int id,@PathVariable("author") String author){
          Comment comment = commentService.findById(id);
          comment.setAuthor(author);
          Comment comment1 = commentService.updateComment(comment);
          return comment1;
      }
      
      
    • 3)重启项目,并删除Redis中的comment,访问:http://localhost:8080/get/1,正常显示 。

    • 4)更新操作http://localhost:8080/update/1/shito2成功:

在这里插入图片描述

  • 5)数据库和Redis均正常

在这里插入图片描述

  • 步骤7:实践删除操作,可查看到数据库记录进行了删除,Redis和控制台等效果如图:
    在这里插入图片描述
    至此,使用实现基于注解的Redis缓存实现。
3.3 基于API的Redis缓存实现

Spring Boot 整合Redis缓存实现中,除了基于注解形式的Redis缓存实现外,还有一种开发中常用的方式-----基于API的Redis缓存实现。以下为具体实现过程。

  • 步骤1:使用Redis API进行业务数据缓存管理,这里我们在service包下编写一个进行业务处理的类ApiCommentService,内容如下:

    //基于API的Redis缓存实现
    package com.itheima.service;
    
    import com.itheima.domain.Comment;
    import com.itheima.repository.CommentRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.Optional;
    import java.util.concurrent.TimeUnit;
    
    @Service
    @Transactional//事务注解
    public class ApiCommentService {
    
    
        @Autowired
        private CommentRepository commentRepository;
        @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         * 查询方法:先从缓存中查询数据,需要前面有注入一个RedisTemplate
         */
        public Comment findById(Integer id){
            Object o = redisTemplate.opsForValue().get("comment_" + id);
            if(o!=null){
                //缓存中有数据
                return (Comment) o;
            }else{
                //缓存中没有数据,就进入数据库根据id查询
                Optional<Comment> byId = commentRepository.findById(id);
                if(byId.isPresent()){
                    //数据库中查到有数据,将查询结果进行缓存,并设置有效期为1天
                    Comment comment = byId.get();
                    redisTemplate.opsForValue().set("comment_"+id,comment,1, TimeUnit.DAYS);
                    return comment;
                }
                return null;
    
            }
        }
    
        /**
         * 更新方法
         */
        public Comment updateComment(Comment comment){
            //更新数据
            commentRepository.updateComment(comment.getId(),comment.getAuthor());
            //更新Redis缓存
            redisTemplate.opsForValue().set("comment_"+comment.getId(),comment);
            return comment;
        }
    
    
        /**
         * 删除方法
         */
    
        public void deleteComment(Integer id){
            //删除数据
            commentRepository.deleteById(id);
            //缓存删除
            redisTemplate.delete("comment_"+id);
        }
    }
    
  • 步骤2:编写web访问层Controller文件。这里可以直接复制CommentController.java,重命名为ApiCommentController.java,修改为以下内容:

    //编写web访问层Controller文件
    package com.itheima.controller;
    
    import com.itheima.domain.Comment;
    import com.itheima.service.ApiCommentService;
    import com.itheima.service.CommentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    //步骤1:加入组合注解@RestController,相当于@Controller+@ResponseBody两个注解的结合
    @RestController
    @RequestMapping("/api") //窄化请求路径
    public class ApiCommentController {
        //步骤2:使用@Autowired对commentService进行标注,让 spring 完成 bean 自动装配的工作
        @Autowired
        private CommentService commentService;
    
        @Autowired
        private ApiCommentService apiCommentService;
        /*
         * 步骤3:实现查询控制
         * */
        @GetMapping("/get/{id}")//这里的id为路径访问传递过来的值
        public Comment findById(@PathVariable("id") Integer id){//@PathVariable*是spring3.0的一个新功能:接收请求路径中占位符的值
            Comment comment = apiCommentService.findById(id);
            return comment;
        }
    
        /*
         * 步骤4:实现更新操作,需要接收两个参数
         * */
        @GetMapping("/update/{id}/{author}")
        public Comment updateComment(@PathVariable("id") int id,@PathVariable("author") String author){
            Comment comment = apiCommentService.findById(id);
            comment.setAuthor(author);
            Comment comment1 = apiCommentService.updateComment(comment);
            return comment1;
        }
    
        /*
         * 步骤4:实现删除操作,需要接收id参数
         * */
        @GetMapping("/delete/{id}")
        public void deleteById(@PathVariable("id") Integer id){
            apiCommentService.deleteComment(id);
        }
    }
    
    
  • 步骤3:基于API的Redis缓存实现的相关配置

    1)基于API的Redis缓存实现不需要@EnableCaching注解开启,项目启动类的该注解可删除或注释(不处理也不影响)

    2)单独使用API的Redis缓存同时需要在pom.xml文件中引入Redis依赖启动器,并在配置文件中进行Redis服务连接配置。(参考前面注解实现Redis缓存的设置)

  • 步骤4:启动项目类进行如上一节的测试,注意访问路径均需要加设定的路径如:这里图跟上小节类似,不再截图。

    1)查询:http://localhost:8080/api/get/4

    2)更新:http://localhost:8080/api/update/2/shitou

    3)删除:http://localhost:8080/api/delete/5

4 自定义Redis缓存序列化机制

缓存管理的实体类数据使用的是JDK序列化机制,不便于使用可视化管理工具进行查看和管理。接下来我们使用基于注解的Redis缓存实现和基于API的Redis缓存实现中的数据序列化机制进行介绍,并自定义JSON的数据序列化机制进行数据缓存管理。

4.1自定义RedisTemplate

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.自定义Redis Template序列化机制

  • 步骤1:项目中com.itheima下创建包config,在该包下创建一个类Redisconfig配置类。如图:
    在这里插入图片描述

  • 步骤2:编写Redisconfig配置类

    	package com.itheima.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.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    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.RedisSerializationContext;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    import java.time.Duration;
    
    @Configuration //定义这是一个配置类
    public class RedisConfig {
        @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<Object, Object> template = new RedisTemplate();
            template.setConnectionFactory(redisConnectionFactory);
            // 使用JSON格式序列化对象,对缓存数据key和value进行转换
            Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
            // 解决查询缓存转换异常的问题
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jacksonSeial.setObjectMapper(om);
    
            // 设置RedisTemplate模板API的序列化方式为JSON
            template.setDefaultSerializer(jacksonSeial);
            return template;
        }
    }
    
    
  • 步骤3:启动项目,浏览器运行:http://localhost:8080/api/get/4,效果如图
    在这里插入图片描述

  • 步骤4:多次刷新,从控制台可以看到仅一次查询,说明缓存起了作业。

在这里插入图片描述

  • 步骤5:查看缓存是不是以JSON格式存储。

在这里插入图片描述

4.2 自定义RedisCacheManager

自定义RedisTemplate对于基于注解的Redis缓存实现来说,是没有作用的。接下来,针对基于注解的Redis缓存机掉和自定义序列化方式的实现进行讲解。

在代码上对RedisCacheConfiguration按CTRL+左键,可以查看RedisCacheConfiguration源码,了解其缓存管理器RedisCacheManager和JdkSerializtionRedisSerializer序列化方式。

这里我们想使用自定义序列化方式的RedisCacheManager进行数据缓存操作。

步骤1:在上一小节创建的Redisconfig配置类中增加一个Bean组件cacheManager,示例代码如下:

 @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 分别创建String和JSON格式序列化对象,对缓存数据key和value进行转换
        RedisSerializer<String> strSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jacksonSeial =
                new Jackson2JsonRedisSerializer(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);
        
// 定制缓存数据序列化方式及时效
    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofDays(1))
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(strSerializer))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jacksonSeial))
            .disableCachingNullValues();

    RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
    return cacheManager;
}

在这里插入图片描述

  • 步骤2:使用自定义序列化机制的RedisCacheManager测试时,实体类可以不用实现序列化接口)。找到domain包下的Comment实体类,去掉 implements Serializable.

  • 步骤3:重启项目,重新浏览器运行:http://localhost:8080/api/get/4,效果如图,
    在这里插入图片描述

    可以看出,访问正常,但控制台没有刷新查询语句,说明刚刚自定义的RedisCacheManager起了作用。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: Spring Boot中集成Redis可以通过以下步骤实现: 1. 添加Redis依赖:在Spring Boot项目的pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 配置Redis连接信息:在application.properties文件中添加以下配置信息: ``` spring.redis.host=redis服务器IP spring.redis.port=redis服务器端口号 spring.redis.password=redis密码 ``` 3. 创建RedisTemplate:在Java代码中创建RedisTemplate对象,并注入到需要使用Redis的类中。 ``` @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class)); redisTemplate.afterPropertiesSet(); return redisTemplate; } } ``` 4. 使用RedisTemplate操作Redis:通过RedisTemplate对象的方法,可以进行各种Redis操作,如set、get、delete等。 以上是Spring Boot集成Redis的基本步骤,具体实现还需根据具体需求进行配置和调整。 ### 回答2: Spring Boot是一个基于Spring框架的快速开发框架,它提供了简化的配置和开箱即用的功能,使得我们可以快速构建和部署应用程序。而Redis是一个高性能的键值对存储数据库,它常被用于缓存和数据存储。 在Spring Boot中集成Redis,首先需要引入相关的依赖。可以通过Maven或Gradle来引入spring-boot-starter-data-redis依赖,该依赖会自动引入Redis相关的配置和依赖库。 然后,在配置文件中添加Redis的连接信息。在application.properties或application.yml中,可以配置Redis的主机地址、端口号、密码等信息。 接下来,在需要使用Redis的地方,可以使用@Autowired注解来注入RedisTemplate对象。RedisTemplate是Spring提供的操作Redis的模板类,它封装了常用的操作方法。 使用RedisTemplate,可以通过调用其对应的方法来操作Redis数据库,比如设置键值对、获取键值对、设置过期时间等。 除了RedisTemplate,Spring Boot还提供了RedisCacheManager类用于缓存管理,它可以通过注解@Configuration和@EnableCaching来启用缓存功能。在需要缓存的方法上使用@Cacheable注解,就可以将方法的返回值缓存Redis中,下次调用时可以直接从缓存中获取,提高了性能。 总的来说,集成RedisSpring Boot中,只需要引入依赖、配置连接信息,然后通过RedisTemplate操作Redis数据库,或使用RedisCacheManager进行数据缓存管理就可以了。这样可以简化我们与Redis的交互,提高开发效率和应用性能。 ### 回答3: 在Spring Boot中,集成Redis可以通过以下步骤实现: 1. 在pom.xml文件中添加Redis的依赖库: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 在application.properties或application.yaml文件中配置Redis连接信息: ```properties spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= ``` 3. 创建一个Redis配置类,用于配置Redis连接工厂: ```java @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean @Override public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { // 生成缓存的key,可以根据实际需求定制 return ""; } }; } @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); // 设置value的序列化方式 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 设置key的序列化方式 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } } ``` 4. 在需要使用Redis的类中,通过注入RedisTemplate来操作Redis: ```java @Autowired private RedisTemplate<String, Object> redisTemplate; public void cacheData(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public Object getData(String key) { return redisTemplate.opsForValue().get(key); } ``` 通过以上步骤,我们就成功在Spring Boot中集成了Redis,可以方便地使用Redis进行缓存、存储和读取数据。在配置Redis时,我们需要根据实际情况修改host、port和password等配置项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值