Redis——SpringBoot整合Redis实战

news2025/1/17 5:54:18

1、基本配置

1.1、引入依赖

首先,建立Maven项目,在Maven项目中引入pom.xml文件:

<dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-redis</artifactId> 
 </dependency>

Jedis封装了Spring Boot与Redis的连接工具。

1.2、application.properties

# Redis数据库索引(默认为0) 
spring.redis.database=0 
 
# Redis服务器地址 
spring.redis.host=127.0.0.1 
 
# Redis服务器连接端口 
spring.redis.port=6379 
 
# Redis服务器连接密码(默认为空) 
spring.redis.password= 

2、RedisTemplate API详解

Redis有5种不同的数据类型,这5种数据类型分别为String、List、Set、Hash和Sorted Set。Spring封装了RedisTemplate对象来对5种数据类型操作,它支持所有的Redis原生的API:

  • redisTemplate.opsForValue():操作String。
  • redisTemplate.opsForHash():操作Hash。
  • redisTemplate.opsForList():操作List。
  • redisTemplate.opsForSet():操作Set。
  • redisTemplate.opsForZSet():操作Sorted Set。

编写RedisService类,通过注解的方式调用RedisTemplate对象来操作Redis的5种数据类型。在RedisService类中使用了@Service注解来标注业务层,RedisService类将自动注入到Spring容器中。本实例使用“RedisService.java”,内容如下:

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.redis.core.*; 
import org.springframework.stereotype.Service; 
 
import java.io.Serializable; 
import java.util.List; 
import java.util.Set; 
import java.util.concurrent.TimeUnit; 
 
@Service 
public class RedisService { 
   @Autowired 
   private RedisTemplate redisTemplate; 
     
}

2.1、写入和读取缓存

在RedisService类中封装写入Redis缓存的业务逻辑的具体内容如下,使用redisTemplate.opsForValue()操作String:

public boolean set(final String key, Object value) { 
   boolean result = false; 
   try { 
      ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); 
      operations.set(key, value); 
      result = true; 
   } catch (Exception e) { 
      e.printStackTrace(); 
   } 
   return result; 
} 

其中封装写入Redis缓存设置过期时间的业务逻辑的具体内容如下,需要调用redisTemplate.expire(key,expireTime,TimeUnit.SECONDS):

public boolean set(final String key, Object value, Long expireTime) { 
   boolean result = false; 
   try { 
      ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); 
      operations.set(key, value); 
      redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); 
      result = true; 
   } catch (Exception e) { 
      e.printStackTrace(); 
   } 
   return result; 
}

其中封装批量删除对应的key的业务逻辑的具体内容如下:

public void remove(final String... keys) { 
   for (String key : keys) { 
      remove(key); 
   } 
} 

其中封装删除对应的key的业务逻辑的具体内容如下,需要调用redisTemplate.delete(key):

public void remove(final String key) { 
   if (exists(key)) { 
      redisTemplate.delete(key); 
   } 
}

其中封装判断Redis缓存中是否有对应的key的业务逻辑的具体内容如下,需要调用redisTemplate.hasKey(key):

public boolean exists(final String key) { 
   return redisTemplate.hasKey(key); 
} 

其中封装读取Redis缓存的业务逻辑的具体内容如下,使用redisTemplate.opsForValue()获得operations句柄,然后使用operations.get(key)获得Redis中对应的key的业务逻辑:

public Object get(final String key) { 
   Object result = null; 
   ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); 
   result = operations.get(key); 
   return result; 
}

2.2、添加和获取散列数据

在RedisService类中封装添加散列数据的业务逻辑的具体内容如下,使用redisTemplate.opsForHash()操作Hash:

public void hmSet(String key, Object hashKey, Object value) { 
   HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); 
   hash.put(key, hashKey, value); 
} 

封装获取散列数据的业务逻辑的具体内容如下,使用redisTemplate.opsForHash()获得hash句柄,然后使用hash.get(key,hashKey)获得key对应的Hash值:

public Object hmGet(String key, Object hashKey) { 
   HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); 
   return hash.get(key, hashKey); 
}

2.3、添加和获取列表数据

在RedisService类中封装添加列表数据的业务逻辑的具体内容如下,使用redisTemplate.opsForList()操作List:

public void lPush(String k, Object v) { 
   ListOperations<String, Object> list = redisTemplate.opsForList(); 
   list.rightPush(k, v); 
}

封装获取列表数据的业务逻辑的具体内容如下,使用redisTemplate.opsForList()获得list句柄,然后使用list.range(k,l,l1)获得Redis的列表数据:

public List<Object> lRange(String k, long l, long l1) { 
   ListOperations<String, Object> list = redisTemplate.opsForList(); 
   return list.range(k, l, l1); 
} 

2.4、添加和获取集合数据

在RedisService类中封装添加集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForSet()操作Set:

public void add(String key, Object value) { 
   SetOperations<String, Object> set = redisTemplate.opsForSet(); 
   set.add(key, value); 
}

封装获取集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForSet()获得SetOperations<String,Object>对象,然后使用set.members(key)获得Redis的集合数据:

public Set<Object> setMembers(String key) { 
   SetOperations<String, Object> set = redisTemplate.opsForSet(); 
   return set.members(key); 
}

2.5、添加和获取有序集合数据

在RedisService类中封装添加有序集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForZSet()操作Sorted Set:

public void zAdd(String key, Object value, double scoure) { 
   ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
   zset.add(key, value, scoure); 
}

封装获取有序集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForZSet()获得ZSetOperations<String,Object>对象,然后使用zset.rangeByScore(key,scoure,scoure1)获得Redis的有序集合数据:

public Set<Object> rangeByScore(String key, double scoure, double scoure1) { 
   ZSetOperations<String, Object> zset = redisTemplate.opsForZSet(); 
   redisTemplate.opsForValue(); 
   return zset.rangeByScore(key, scoure, scoure1); 
}

3、Spring Boot集成Spring Session

传统Session的问题在于Session是由Web容器管理的,即一个Session只保存在一台服务器上,适合于单体应用。随着架构不断地向微服务分布式集群演进,传统的Session在集群环境下就不能正常工作了。例如,现在有3台Web服务器,客户端访问服务器通过负载均衡Nginx负载到某一台服务器上,用户此次的数据就保存到这台服务器的Web容器中了,如果用户下次请求被负载到其他服务器上,就获取不到之前保存的数据了。

这时候就需要整个服务器集群共享同一个Session。为了解决所有服务器共享一个Session的问题,Session就不能单独保存在自己的Web容器中,而是保存在一个公共的会话仓库(Session Repository)中,所有服务器都访问同一个会话仓库,这样所有服务器的状态都一致了。Spring Session支持的会话仓库有Redis、MongoDB、JDBC,本帖使用Redis作为Spring Session的会话仓库。

Spring Session有以下优点:

  • Spring Session是基于Servlet规范实现的一套Session管理框架。Spring Session主要解决了分布式场景下Session的共享问题。Spring Session最核心的类是SessionRepositoryFilter,用于包装用户的请求和响应。
  • 可在程序中直接替换HttpSession,而无须修改一行代码。
  • 可以很方便地与Spring Security集成,增加诸如findSessionsByUserName、rememberMe,限制同一个账号可以同时在线的Session数(例如设置成1,即可达到把前一次登录替换的效果)等。

3.1、配置Spring Boot项目

在Maven项目的pom.xml文件里引入必要的依赖包:

<dependency> 
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-web</artifactId> 
</dependency> 
 
<dependency> 
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-web</artifactId> 
</dependency> 
 
<dependency> 
   <groupId>org.springframework.session</groupId> 
   <artifactId>spring-session-data-redis</artifactId> 
</dependency> 
 
<dependency> 
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-data-redis</artifactId> 
</dependency>

配置文件application.properties,内容如下:

# Redis 配置 
# Redis数据库索引(默认为0) 
spring.redis.database=0 
# Redis服务器地址 
spring.redis.host=127.0.0.1 
# Redis服务器连接端口 
spring.redis.port=6379 
# Redis服务器连接密码(默认为空) 
spring.redis.password=

3.2、创建配置类和控制器类

创建配置类RedisHttpSessionConfiguration,本实例使用“Configuration.java”,内容如下:

 
import org.springframework.context.annotation.Configuration; 
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 
 
@Configuration 
//maxInactiveIntervalInSeconds默认是1800s过期,这里测试修改为60s 
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60) 
public class RedisHttpSessionConfiguration { 
 
}

配置类RedisHttpSessionConfiguration使用@Configuration注解表明这是一个配置类。在这个类中也添加了注解@EnableRedisHttpSession,表示开启Redis的Session管理。如果需要设置会话失效时间,可以使用@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60)表示在60秒后会话失效。

创建用户类User,用户类只有两个属性username和password,保存用户登录的用户名和密码。本实例使用“User.java”,内容如下:

  
import java.io.Serializable; 
  
public class User implements Serializable{ 
    private String name; 
    private String password; 
  
    public String getName() { 
         return name; 
    } 
  
    public void setName(String name) { 
         this.name = name; 
    } 
  
    public String getPassword() { 
         return password; 
    } 
  
    public void setPassword(String password) { 
         this.password = password; 
    } 
  
    @Override 
    public String toString() { 
         return "User{" + 
                  "name='" + name + '\'' + 
                  ", password='" + password + '\'' + 
                  '}'; 
    } 
}

创建控制器类SessionController,在这个类中定义了2个方法。login方法用于登录验证,当输入username等于“xinping”,password等于“123”,判断用户登录成功,在Session中保存用户信息。get方法用于从Session中获取用户信息。本实例使用“SessionController.java”,内容如下:

package com.dxtd.SpringSessionDemo.controller; 
  
import org.springframework.web.bind.annotation.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import java.util.HashMap; 
import java.util.Map; 
  
@RestController 
public class SessionController {
    /** 
     * 登录系统 
     *     
     * */ 
    @RequestMapping(value="/session/login", method = RequestMethod.GET) 
    @ResponseBody 
    public Map login(@RequestParam("username") String username,@RequestParam
("password") String password,HttpServletRequest request, HttpSession session) { 
        String message = "login failure"; 
        Map<String, Object> result = new HashMap<String, Object>(); 
        if(username != null && "xinping".equals(username) && "123".equals
(password)){ 
            User user = new User(); 
            user.setName(username); 
            user.setPassword(password); 
            request.getSession().setAttribute("admin", user); 
            message = "login success"; 
            result.put("message" , message); 
            result.put("sessionId",session.getId()); 
        }else{ 
            result.put("message" , message); 
        } 
  
        return result; 
    } 
  
    /** 
     * 查询用户 
     *    
     * */ 
    @RequestMapping(value="/session/get", method = RequestMethod.GET) 
    @ResponseBody 
    public Map get(@RequestParam("username") String username,HttpServletRequest 
request, HttpSession session) { 
        Object value = request.getSession().getAttribute("admin"); 
        Map<String,Object> result = new HashMap<String,Object>(); 
        result.put("message" ,value); 
        result.put("sessionId",session.getId()); 
        return result; 
    } 
  
}

3.3、项目验证

启动项目,运行SpringSessionDemoApplication.java,进入SpringSessionDemo项目所在目录:

D:\quant\Redis\Chapter08\SpringSessionDemo>mvn clean package

在SpringSessionDemo\target目录下获得编译好的压缩包SpringSessionDemo-0.0.1-SNAPSHOT.jar,如下图所示:
在这里插入图片描述
使用如下命令分别以两个不同的端口(8081和8082)启动项目,用于模拟分布式应用中的两个服务:

java -jar SpringSessionDemo-0.0.1-SNAPSHOT.jar --server.port=8081 
java -jar SpringSessionDemo-0.0.1-SNAPSHOT.jar --server.port=8082

启动项目,如下图所示:
在这里插入图片描述
第1步:访问http://127.0.0.1:8081/session/login?username=xinping&password=123。第一次访问URL地址端口为8081的Spring Boot项目时模拟用户登录,在浏览器中访问这个请求后的结果如下图所示:
在这里插入图片描述
第2步:访问地址http://127.0.0.1:8082/session/get?username=xinping。第二次访问URL地址端口为8082的Spring Boot项目时模拟获取登录的用户信息,在浏览器中访问这个请求后的结果如下图所示:
在这里插入图片描述
可以看出成功获取了保存在Redis中的用户名为xinping的用户信息,并且两次请求的Session ID是相同的,实现了Session的共享。

通过Spring Boot使用Redis来实现Session的共享很方便,再配合Nginx进行负载均衡,便能实现分布式的应用了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1432452.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HarmonyOS应用开发】后台提醒(十六)

简述 随着生活节奏的加快&#xff0c;我们有时会忘记一些重要的事情或日子&#xff0c;所以提醒功能必不可少。应用可能需要在指定的时刻&#xff0c;向用户发送一些业务提醒通知。例如购物类应用&#xff0c;希望在指定时间点提醒用户有优惠活动。为满足此类业务诉求&#xf…

机器学习 | 解析聚类算法在数据检测中的应用

目录 初识聚类算法 聚类算法实现流程 模型评估 算法优化 特征降维 探究用户对物品类别的喜好细分(实操) 初识聚类算法 聚类算法是一种无监督学习方法&#xff0c;用于将数据集中的对象按照相似性分组。它旨在发现数据中的内在结构和模式&#xff0c;将具有相似特征的数据…

Photoshop CS6 下载安装教程,保姆级教程,小白也能轻松搞的,附安装包

前言 Adobe Photoshop CS6强大的照片拍摄和突破性的新功能&#xff0c;用于复杂的图形、选择、逼真的绘画和装饰智能。创建惊人的高动态范围(HDR)图像。用逼真的笔触和混合的颜色绘画。消除噪音&#xff0c;添加种子&#xff0c;并绘制一个国家最先进的摄影设备的草图。凭借原…

【HarmonyOS应用开发】ArkUI 开发框架-进阶篇-Video组件的使用(十)

一、Video组件的使用 1、概述 在手机、平板或是智慧屏这些终端设备上&#xff0c;媒体功能可以算作是我们最常用的场景之一。无论是实现音频的播放、录制、采集&#xff0c;还是视频的播放、切换、循环&#xff0c;亦或是相机的预览、拍照等功能&#xff0c;媒体组件都是必不可…

MacBook有必要装清理软件吗?CleanMyMac的一些主要特点

MacBook是苹果公司的一款高端笔记本电脑&#xff0c;但是&#xff0c;随着使用时间的增长&#xff0c;MacBook也会出现一些问题&#xff0c;比如运行缓慢、卡顿、垃圾文件堆积、磁盘空间不足等。这些问题不仅影响了用户的使用体验&#xff0c;也可能对MacBook的寿命和安全性造成…

Shell脚本⑧免交互

目录 一.Here Document 1.定义 2.变量 &#xff08;1&#xff09;变量替换成实际值 &#xff08;2&#xff09;整行内容作为变量并输出结果 &#xff08;3&#xff09;多行注释 &#xff08;4&#xff09;自动划分磁盘免交互 二.Expect 1.定义 2.安装 3.免交互操作 …

django线上教育学习平台大数据分析系统python

随着互联网技术不断地发展&#xff0c;网络与大数据成为了人们生活的一部分&#xff0c;而线上教育平台大数据分析作为网上应用的一个全新的体现&#xff0c;由于其特有的便捷性&#xff0c;已经被人们所接受。目前主流的线上教育平台大数据分析服务不仅不明确并且管理盈利较低…

基于STM32的UART/USART数据传输的错误检测和纠错机制研究

在STM32微控制器中&#xff0c;UART/USART模块的数据传输可以通过错误检测和纠错机制来提高数据的可靠性。下面将介绍一些常用的错误检测和纠错机制&#xff0c;并提供一个示例代码来演示如何使用这些机制。 ✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技…

SpringCloud-微服务概述、SpringCloud入门概述、服务提供与消费

1.学习前言 1.1 学习前提 熟练使用SpringBoot 微服务快速开发框架了解过Dubbo Zookeeper 分布式基础电脑配置内存不低于8G 1.2 文章大纲 Spring Cloud 五大组件 服务注册与发现——Netflix Eureka负载均衡&#xff1a; ​ 客户端负载均衡——Netflix Ribbon ​ 服务端负载…

Oracle喊你领取免费AI 助理级证书啦!

拿证秘籍如下&#xff1a; 1. 登录Oracle的考试中心网站&#xff1a;https://education.oracle.com/certification 2. 选择AI 助理级考试&#xff0c;考试代码&#xff1a;1Z0-1122-23&#xff0c;也可以点击这里直达 3. AI学习视频免费看&#xff0c;也可以选择不看 3.5 去…

一台机器上如何部署多个web项目

1、综述 随着计算机硬件水平的不断提高&#xff0c;往往不是一台机器上只部署一个web项目了&#xff0c;而是尽可能多部署几个项目&#xff0c;以用来节省资源&#xff0c;现在我们看看如何一台机器部署多个项目&#xff0c;我们先结合上一篇文章中提到的tomcat架构&#xff0…

重温《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》 –– 学习笔记(二)

第二部分&#xff1a;自动内存管理机制 第2章&#xff1a;Java内存区域与内存溢出异常 2.1 概述 Java 与 C 之间有一堵由内存动态分配和垃圾收集技术围成的高墙。 Java 程序员在 虚拟机自动内存管理机制 的帮助下&#xff0c;无需为每一个 new 操作去写配对的 delete/free …

TOP100-链表(四)

9.24. 两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2…

myql 项目数据库和表的设计

1.表的设计和创建 2.在navicate运行这些代码 create table user(id int not null auto_increment primary key,name varchar(50) not null unique,password varchar(50) not null,state enum(online,offline) default offline ); create table friend(userid int not null,…

java之ReentrantLock

在讲RentrantLock之前需要先讲一下AQS和LockSupport&#xff0c;因为rentrantLock底层是用AQS实现的&#xff0c;而AQS中获取阻塞和唤醒底使用LockSupport实现的。 1、LockSupport实现 下面代码中&#xff0c;LockSupport.park方法是当前线程等待&#xff0c;直到获得许可&am…

06:原生云K8S解密|K8S集群安装部署|K8S网络插件

原生云K8S解密&#xff5c;K8S集群安装部署&#xff5c;K8S网络插件 K8SK8S集群架构图解 K8S部署仓库初始化kube-master安装计算节点的安装token管理 配置flannel网络&#xff08;master主机操作&#xff09; K8S 有大量夸主机的容器需要管理&#xff0c;快速部署应用&#xff…

问题:根据全面推进国防和军队现代化的战略安排,_____把人民军队全面建成世界一流军队。 #经验分享#媒体

问题&#xff1a;根据全面推进国防和军队现代化的战略安排&#xff0c;_____把人民军队全面建成世界一流军队。 A、2020年 B、2035年 C、本世纪中叶 D、2045年 参考答案如图所示 问题&#xff1a;判断题&#xff1a;高处作业传递物件应使用绳索&#xff0c;在确认作业下方…

面试数据结构与算法总结分类+leetcode目录【基础版】

&#x1f9e1;&#x1f9e1;&#x1f9e1;算法题目总结&#xff1a; 这里为大家总结数据结构与算法的题库目录&#xff0c;如果已经解释过的题目会标注链接更新&#xff0c;方便查看。 数据结构概览 Array & String 大家对这两类肯定比较清楚的&#xff0c;同时这也是面试…

C#,雅各布斯塔尔—卢卡斯(Jacobsthal Lucas Number)的算法与源代码

1 雅各布斯塔尔序列 雅各布斯塔尔序列是一个与斐波那契序列类似的加法序列&#xff0c;由递归关系JnJn-12Jn-2定义&#xff0c;初始项J00&#xff0c;J11。序列中的一个数字称为雅可布沙尔数。它们是卢卡斯序列Un&#xff08;P&#xff0c;Q&#xff09;的一种特殊类型&#x…

【stm32】hal库学习笔记-ADC模数转换(超详细!)

【stm32】hal库学习笔记-ADC模数转换&#xff08;超详细&#xff01;&#xff09; 本篇章介绍了ADC实现电压检测的三种方式 ADC原理及选型 ADC将连续的模拟电压信号转换为二进制的数字信号 选型参数 速度&#xff08;采样频率&#xff09; 功耗 精度 转换原理 ADC hal库驱…