【Java开发】 Spring 04:云服务器 Docker 环境下安装 Redis 并连接 Spring 项目实现简单 CRUD

news2025/1/16 3:44:36

Redis是目前使用最多的缓存,包括Spring Boot 中我们也是会用Redis做很多事情。它是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库,具备数据持久化、多数据结构存储及数据备份等特点。Redis 和 Mongo 同属于文档型数据库,因此 Spring Boot 对于这两者的集成类似~

目录

1 Docker 环境下安装 Redis 

1.1 腾讯云服务器系统选择

1.2 通过 Docker 启动 Redis

①获取镜像

②创建容器

③安全组

④测试连接

2 SpringBoot 连接 Redis 及实现简单操作

2.1 环境搭建

①创建项目

②添加配置

③添加实体类

2.2 Lettuce 配置连接池

①添加 commons-pool2 依赖

②添加 properties 配置

2.3 基于 StringRedisTemplate 实现 CRUD

① RedisTemplate 和 StringRedisTemplate的区别

② opsForValue

③ opsForList

④ opsForSet

⑤ opsForZSet

⑥ opsForHash

⑦ expire 设置过期时间

2.4 基于 CrudRepository 实现 CRUD

① 新增 RepositoryUser 实体类

② 添加Repository类

③ UserRepository测试


 源码地址:尹煜 / redis_study · GitCode

1 Docker 环境下安装 Redis 

1.1 腾讯云服务器系统选择

类似上一篇文章,在腾讯云服务器初次选择系统和重装系统都可以选择 Docker 镜像~

1.2 通过 Docker 启动 Redis

①获取镜像

docker pull redis

②创建容器

docker run --name redis -p 6379:6379 -v /docker/host/dir:/data -d redis redis-server --appendonly yes --requirepass yourpassword
  • -p 6379:6379 端口映射:前表示主机部分,:后表示容器部分。
  • --name redis 指定该容器名称,查看和进行操作都比较方便。
  • -v 挂载文件或目录 :前表示主机部分,:后表示容器部分。
  • -d redis 表示后台启动redis
  • //redis-server /etc/redis/redis.conf 以配置文件启动redis,加载容器内的conf文件,最终找到的是挂载的目录/usr/local/docker/redis.conf
  • --appendonly yes 开启redis 持久化
  • --requirepass 123456 设置密码为123456 

③安全组

④测试连接

上述步骤亲测可用,我使用IDE里的一个插件【Redis】用来测试,连接成功👇

2 SpringBoot 连接 Redis 及实现简单操作

2.1 环境搭建

①创建项目

还是通过编译器 IDEA 实现:

ⅠNew Project

Ⅱ 添加 Redis 依赖

也可在之前的项目的 pom.xml 文件中直接添加对应的依赖

②添加配置

Ⅰ配置properties

spring.redis.database=0 
spring.redis.host=localhost 
spring.redis.port=6379 #端口
spring.redis.password=root #密码
spring.redis.connect-timeout=5000
spring.data.redis.repositories.enabled=true

Ⅰ启动类继承 RedisAutoConfiguration

路径:src/main/java/com/yinyu/redisdemo/RedisDemoApplication.java

@SpringBootApplication
public class RedisDemoApplication extends RedisAutoConfiguration {

    public static void main(String[] args) {
        SpringApplication.run(RedisDemoApplication.class, args);
    }

}

③添加实体类

路径:src/main/java/com/yinyu/redisdemo/redisPojo/User.java

注意,存入 Redis 数据库的实体类必须使用(实现)序列化接口。

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    @Id
    private String id;
    private String name;
    private Integer age;
    private String email;
    private String createDate;
    
}

2.2 Lettuce 配置连接池

SpringBoot2.0 默认采用 Lettuce 客户端来连接 Redis 服务,已经放弃 jedis 客户端了。

而且 Lettuce 客户端默认是不使用连接池的,只有配置 redis.lettuce.pool下的属性的时候才可以使用到redis连接池~

①添加 commons-pool2 依赖

采用 Lettuce 使用连接池,要依赖 commons-pool2

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

②添加 properties 配置

路径:src/main/resources/application.properties

spring.redis.lettuce.pool.enabled=true
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.min-idle=5
spring.redis.lettuce.pool.max-wait=5000ms
  • max-active:连接池最大连接数(使用负值表示没有限制)
  • max-idle:连接池中的最大空闲连接
  • min-idle:连接池中的最小空闲连接
  • max-wait:连接池最大阻塞等待时间(使用负值表示没有限制)

2.3 基于 StringRedisTemplate 实现 CRUD

其实 RedisTemplate  和 StringRedisTemplate 的操作基本一致,只不过 RedisTemplate 的入参运行 Object ,StringRedisTemplate 只允许储存 String,但是由于 StringRedisTemplate 展示性更优,所以本文采用 StringRedisTemplate 举例相关操作

① RedisTemplate 和 StringRedisTemplate的区别

Ⅰ特点

  • 两者的关系是StringRedisTemplate继承RedisTemplate。
  • 两者的数据是不共通的;StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
  • SDR默认采用的序列化策略有两种,一种是String的序列化策略(StringRedisTemplate),一种是JDK的序列化策略(RedisTemplate ),保存的 key 和 value 都是采用对应策略序列化保存的。

Ⅱ 存储展示形式

RedisTemplate 执行插入操作,会将数据先序列化成字节数组然后在存入Redis数据库,数据库展示如下👇

StringRedisTemplate,默认存入的数据就是原文,因为stringRedistemplate默认使用的是string序列化策略👇

 Ⅲ 新增方式区别

//user构建
User user = User.builder().age(20).name("yu").email("yinyu@163.com").createDate(new Date().toString()).build();
//redisTemplate新增操作
redisTemplate.opsForValue().set("user",user);
//stringRedisTemplate新增操作
stringRedisTemplate.opsForValue().set("user", String.valueOf(user));

可以看到,redisTemplate 的第二个入参允许实体类,而 stringRedisTemplate 的第二个入参只允许String类,因此 redisTemplate 的适用范围更广。

② opsForValue

opsForValue 用于处理 Value :

  • 在 redisTemplate 中是 Object ,那么可以是 Integer、String 甚至是实体类
  • 在 stringRedisTemplate 就只是 String了,注意本文用 stringRedisTemplate

Ⅰset 新增—也适用于修改

@Test
public void opsForValueSetTest() {
    stringRedisTemplate.opsForValue().set("author", "yinyu");
}

新增成功👇

Ⅱ append 新增字符到末尾

根据存在的 key,在原有的 value 基础上新增字符串到末尾,若 key 不存在,直接创建。

@Test
public void opsForValueAppendTest() {
    stringRedisTemplate.opsForValue().append("author", "+java");
}

新增字符到末尾成功👇

Ⅲ get 查询

@Test
public void opsForValueGetTest() {
    String author = stringRedisTemplate.opsForValue().get("author");
    System.out.println(author);
}

Ⅳ set(K key, V value, long timeout, TimeUnit unit)—设置 Value 的过期时间

该功能可以说是很重要了,适合拿来做缓存!

@Test
@SneakyThrows
public void TimeOutTest() {
    stringRedisTemplate.opsForValue().set("timeOutKey", "timeOutVaule", 5, TimeUnit.SECONDS);
    String timeOutValue = stringRedisTemplate.opsForValue().get("timeOutKey");
    System.out.println("{timeOutKey=timeOutVaule}刚创建后获取的值:"+timeOutValue);
    Thread.sleep(5*1000);
    timeOutValue = stringRedisTemplate.opsForValue().get("timeOutKey");
    System.out.print("等待10s过后,获取的值:"+timeOutValue);
}

输出👇

Ⅴ delete 删除

@Test
public void opsForValueDeleteTest() {
    stringRedisTemplate.delete("author");
    System.out.println(stringRedisTemplate.hasKey("author"));//输出key="author"是否还存在
}

③ opsForList

@Test
public void opsForListTest(){
    //1、opsForList 新增操作
    ListOperations<String, String> listOperations = stringRedisTemplate.opsForList();
    listOperations.leftPush("list", "hello");
    listOperations.leftPush("list", "world");
    listOperations.leftPush("list", "yinyu");
    //2、opsForList 查询操作
    List<String> list = stringRedisTemplate.opsForList().range("list",0,2);// 取 key 值为 list 的索引0到索引2的list
    System.out.println(list);
}

新增 List 成功!

④ opsForSet

​Set类型 是 String类型 的无序集合。它的特点是无序且唯一,它是通过哈希表实现的,添加、删除、查找的复杂度都是 O(1)。

@Test
public void opsForSetTest(){
    //1、opsForSet 新增操作
    SetOperations<String, String> setOperations = stringRedisTemplate.opsForSet();
    setOperations.add("set", "hello");
    setOperations.add("set", "world");
    setOperations.add("set", "world");
    setOperations.add("set", "java");
    //2、opsForSet 查询操作
    Set<String> set = stringRedisTemplate.opsForSet().members("set");
    System.out.println(set);
}

如图👇

⑤ opsForZSet

ZSet 类型和 Set类型一样,也是 String类型元素的集合,且不允许有重复的成员。不同的是每个元素都会关联一个 double类型的分数。它正是通过分数来为集合中的成员进行从小到大的排序。ZSet 类型的成员是唯一的,但分数(score)却可以重复。

@Test
public void opsForZSetTest(){
    //1、opsForZSet 新增操作
    ZSetOperations<String, String> zSetOperations = stringRedisTemplate.opsForZSet();
    zSetOperations.add("zset", "java", 1);
    zSetOperations.add("zset", "hello", 3);
    zSetOperations.add("zset", "world", 2);
    //2、opsForZSet 查询操作
    Set<String> set = stringRedisTemplate.opsForZSet().range("zset",0,2);
    System.out.println(set);
}

如图👇

⑥ opsForHash

Hash类型 是一个键值对的集合。它是一个 String类型 的 field 和 value 组合的映射表,它特别适合用于存储对象。

@Test
public void opsForHashTest(){
    //1、opsForHash 新增操作
    HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash();
    hashOperations.put("key", "hashkey1", "hello");
    hashOperations.put("key", "hashkey2", "world");
    hashOperations.put("key", "hashkey3", "java");
    //2、opsForHash 查询操作
    String string = (String) stringRedisTemplate.opsForHash().get("key","hashkey2");
    System.out.println(string);
}

如图👇

⑦ expire 设置过期时间

既然是缓存,那必不可少的就是设置过期时间了,需要确定的是 key ,适用于value、list、set等各种类型,下边举个例子👇

@Test
public void expireTest(){
    stringRedisTemplate.expire("set",5, TimeUnit.SECONDS);
}

2.4 基于 CrudRepository 实现 CRUD

类似 MongoDB,Spring Data 也为其他的数据库提供了数据访问的支持,至于Redis 的话,虽然没有专属的 Repository 类,但可以使用 CrudRepository。

① 新增 RepositoryUser 实体类

@RedisHash(value = "user") 是用来指定 Redis 的

路径:src/main/java/com/yinyu/redisdemo/redisPojo/RepositoryUser.java

@Builder
@RedisHash(value = "user") // redis hash name
public class RepositoryUser {

    @Id // 指定id属性
    private String id;
    private String name;
    private Integer age;
    private String email;
    private String createDate;

}

② 添加Repository类

继承CrudRepository接口,同时第一个入参为指定实体类!

路径:src/main/java/com/yinyu/redisdemo/repository/UserRepository.java

@Repository
public interface UserRepository extends CrudRepository<RepositoryUser,String> {

}

③ UserRepository测试

个人理解可能这种方式是封装了 opsForHash ,实体类中的字段名替代了 hashkey ,确实比较方便,但是功能较少,确实设置过期、List等功能。

Ⅰ 注入Repository类:

    @Autowired
    private UserRepository userRepository;

Ⅱ save 新增

@Test
public void saveTest(){
    RepositoryUser user = RepositoryUser.builder().id("RepositoryKey").age(18).name("yinyu").email("yinyu@163.com").createDate(new Date().toString()).build();
    userRepository.save(user);
}

新增成功👇

Ⅲ findById 查询

@Test
public void findByIdTest(){
    RepositoryUser user = userRepository.findById("RepositoryKey").orElse(null);
}

Ⅳ deleteById 删除

@Test
public void deleteTest(){
    userRepository.deleteById("RepositoryKey");
}


参考文章

腾讯云centos7.6 docker安装redis_Marksunshine的博客-CSDN博客

SpringBoot 配置 Redis 连接池_普通网友的博客-CSDN博客

SpringBoot整合Redis(基本CRUD操作)【上】_小异常的博客-CSDN博客

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

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

相关文章

C++17新特性的使用场景总结

一、简单特性 1. namespace 嵌套 C17使我们可以更加简洁使用命名空间&#xff1a; 2. std::variant 升级版的C语言Union 在C17之前&#xff0c;通常使用Union来定义一个可以存储不同类型的变量&#xff0c;现在可以通过std::variant<T1,T2,...> 来定义一个可以存储不同…

Day2.

文章目录一、回文日期1、题目描述2、输入描述3、输出描述4、参考代码二、杨辉三角形1、题目描述2、输入描述3、输出描述4、参考代码一、回文日期 1、题目描述 2020 年春节期间&#xff0c;有一个特殊的日期引起了大家的注意&#xff1a;2020 年 2 月 2 日。因为如果将这个日期…

【2022年11月19日提高A组】消圈策略【DP】

思路&#xff1a; dis i 代表1 到 i 的最短路 因为它要求没有负环 无负环和可以求出最短路是充要条件 然后dis i 和 dis (i1)相差最多不超过1 因为有0边的存在 然后就对边的大小进行分类讨论 如果i<j即e i,j 为-1 那么dis (i) - 1 > dis j 然后移项 dis i - dis j > 1…

云原生|kubernetes|部署MySQL一主多从复制集群(基于GTID的复制)

前言&#xff1a; 一&#xff0c; MySQL的主从复制优点如下&#xff1a; 数据更安全&#xff1a;做了数据冗余&#xff0c;不会因为单台服务器的宕机而丢失数据 性能大大提升&#xff1a;一主多从&#xff0c;不同用户从不同数据库读取&#xff0c;性能提升 扩展性更优&…

如何使用Jekyll在GitHub Pages上搭建网站(个人博客)

本文很长&#xff0c;建议使用侧边栏进行跳转。 前言 Jekyll 是一个基于 Ruby 语言的&#xff0c;用于搭建静态网站的生成器&#xff0c;主要用于搭建博客网站&#xff08;官方自己的介绍为&#xff1a;Jekyll is a blog-aware, static site generator in Ruby&#xff09;。…

html制作网页案例代码----(故宫博物馆9页)特效很多

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 茶文化网站 | 中华传统文化题材 | 京剧文化水墨风书画 | 中国民间年画文化艺术网站 | 等网站的设计与制作 | HTML期末大学生网页设计作业&#xff0c;We…

Tauri+Vite+Vue3创建项目步骤

1、按照官网文档创建tauri项目 npm create tauri-app 然后按顺序填&#xff1a; 1、项目名称&#xff1a; 2、选择你的package manager 3、选择你的前端框架 然后再一步一步执行下面命令 cd 刚才创建的项目名称 npm install npm run tauri dev 然后出现 第一次可能没有反…

基于java+ssm的理论课_考勤,作业,签到管理系统

本理论课管理系统采用目前最流行的ssm框架和eclipse编辑器、mysql数据库设计并实现的 。主要包括登录模块、课程信息管理模块、考勤信息管理模块、成绩管理模块、和退出模块等多个模块 本系统基于SSM(SpringSpringMVCMyBatis)框架,适用于毕业设计&#xff0c;采用javaweb,基于B…

Android 驾车出行路线规划

好久没有写了&#xff0c;今天又是加班的一天&#xff0c;先随便写点东西吧。 最近在搞一款自驾游的项目&#xff0c;需要用到地图&#xff0c;扒了点高德上的数据&#xff0c;便集成了高德地图SDK。之前的项目大部分都只是用了定位&#xff0c;其中有一款也用了地图poi的搜索…

js的promise的究竟是同步还是异步的问题和promise.all可以同时请求多个接口是错误的回答的原因

个人理解 前景-代码输出结果是什么 我们都知道,循环队列的时候,同步任务大于异步任务(异步任务里面的微任务又大于宏任务),那么你猜猜这个代码输出结果是 什么呢 <script>setTimeout(() > {console.log(1); }, 0);new Promise(function(resolve,reject){console.lo…

各省市ZF工作BG环境规制环境词汇词频分析(2009-2019年)

各省市ZF工作报告及环境词汇词频分析 1、时间&#xff1a;2009-2019年 2、说明&#xff1a;环保词频汇总分析&#xff1a;通过手工搜集整理出2009-2019年全国31个省ZF工作报告中环境规制相关的环保词汇及环保词频。 3、词汇包括&#xff1a; 环境保护、环保、污染、能耗、减…

NeurIPS 22|四分钟内就能训练目标检测器!( AGVM)

文章目录引言方法介绍实验过程结果分析引言 来自商汤的基模型团队和香港大学等机构的研究人员提出了一种大批量训练算法 AGVM&#xff0c;该研究已被NeurIPS 2022接收。 本文提出了一种大批量训练算法 AGVM (Adaptive Gradient Variance Modulator)&#xff0c;不仅可以适配于…

Shell脚本

文章目录Shell脚本学习1. Shell概念1.1Shell脚本的好处1.2 Shell脚本的入门1.2.1 Linux环境中默认Shell版本1.2.2 Shell脚本1.2.3 编写简单的hello,world 脚本1.2.4 Shell 脚本的多种执行方法1.2.4.1 第一种 bash 或 sh 加文件的路径1.2.4.2 第二种 文件的路径直接执行1.2.4.2.…

Day07--wxs的概念以及其基本的用法

一.概念 1.啥子是wxs呢&#xff1f; *****************************************************************************************************************************************************************************************************************************…

【附源码】Python计算机毕业设计特大城市地铁站卫生防疫系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

数字电路和模拟电路-10时序逻辑电路的分析和设计

前言&#xff1a;学习同步时序逻辑电路的分析、设计 一、同步时序逻辑电路的分析 1、时序逻辑电路的分析步骤 步骤一 逻辑图 同步or异步 计数器or状态机 一条总线同步&#xff0c;多条总线是异步 计数器无输入&#xff0c;状态机有输入 状态机还分摩尔型和米里型 步骤二 驱动…

力扣(LeetCode)17. 电话号码的字母组合(C++)

回溯 将 222——999 和字母对应起来&#xff0c;用字符串数组保存。 递归遍历 digitsdigitsdigits 每一个数字&#xff0c;每一个数字对应的字母&#xff0c;又可以递归遍历&#xff0c;和下一个数字的字母组成排列。当排列长度等于 digitsdigitsdigits 的长度&#xff0c;就…

详解MySQL非常重要的日志—bin log

前言 bin log想必大家多多少少都有听过&#xff0c;它是MySQL中一个非常重要的日志&#xff0c;所以各位架构师们&#xff0c;如果有不了解的&#xff0c;一定要好好学习了&#xff0c;因为它涉及到数据库层面的主从复制、高可用等设计。 bin log是什么&#xff1f; bin log…

【博客538】BGP优雅重启机制

bgp优雅重启机制 背景 以BGP为代表的路由协议&#xff0c;从设计之初&#xff0c;就关注路由表的正确性&#xff0c;因为这是确保整个网络系统正常工作的最基本要求。因此每个BGP路由器&#xff0c;总是会以最快的速度收敛到整个网络最新的状态上。当一个BGP peer的BGP连接断开…

一种PEG衍生物Azide-PEG-Biotin|N3-PEG-Biotin|叠氮-PEG-生物素|956748-40-6

1、名称 英文&#xff1a;N3-PEG-Biotin&#xff0c;Azide-PEG-Biotin 中文&#xff1a;叠氮-聚乙二醇-生物素 2、CAS编号&#xff1a;956748-40-6 3、所属分类&#xff1a; Azide PEG Biotin PEG 4、分子量&#xff1a;可定制 5、质量控制&#xff1a;95% 6、储存&…