Redis是目前使用最多的缓存,包括Spring Boot 中我们也是会用Redis做很多事情。它是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库,具备数据持久化、多数据结构存储及数据备份等特点。Redis 和 Mongo 同属于文档型数据库,因此 Spring Boot 对于这两者的集成类似~
目录
2.3 基于 StringRedisTemplate 实现 CRUD
① RedisTemplate 和 StringRedisTemplate的区别
源码地址:尹煜 / redis_study · GitCode
类似上一篇文章,在腾讯云服务器初次选择系统和重装系统都可以选择 Docker 镜像~

docker pull redis
docker run --name redis -p 6379:6379 -v /docker/host/dir:/data -d redis redis-server --appendonly yes --requirepass yourpassword


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

还是通过编译器 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;
-
- }
SpringBoot2.0 默认采用 Lettuce 客户端来连接 Redis 服务,已经放弃 jedis 客户端了。
而且 Lettuce 客户端默认是不使用连接池的,只有配置 redis.lettuce.pool下的属性的时候才可以使用到redis连接池~
采用 Lettuce 使用连接池,要依赖 commons-pool2
- <dependency>
- <groupId>org.apache.commonsgroupId>
- <artifactId>commons-pool2artifactId>
- dependency>
路径: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
其实 RedisTemplate 和 StringRedisTemplate 的操作基本一致,只不过 RedisTemplate 的入参运行 Object ,StringRedisTemplate 只允许储存 String,但是由于 StringRedisTemplate 展示性更优,所以本文采用 StringRedisTemplate 举例相关操作。
Ⅰ特点
Ⅱ 存储展示形式
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 用于处理 Value :
Ⅰ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"是否还存在
- }
- @Test
- public void opsForListTest(){
- //1、opsForList 新增操作
- ListOperations
listOperations = stringRedisTemplate.opsForList(); - listOperations.leftPush("list", "hello");
- listOperations.leftPush("list", "world");
- listOperations.leftPush("list", "yinyu");
- //2、opsForList 查询操作
- List
list = stringRedisTemplate.opsForList().range("list",0,2);// 取 key 值为 list 的索引0到索引2的list - System.out.println(list);
- }
新增 List 成功!

Set类型 是 String类型 的无序集合。它的特点是无序且唯一,它是通过哈希表实现的,添加、删除、查找的复杂度都是 O(1)。
- @Test
- public void opsForSetTest(){
- //1、opsForSet 新增操作
- SetOperations
setOperations = stringRedisTemplate.opsForSet(); - setOperations.add("set", "hello");
- setOperations.add("set", "world");
- setOperations.add("set", "world");
- setOperations.add("set", "java");
- //2、opsForSet 查询操作
- Set
set = stringRedisTemplate.opsForSet().members("set"); - System.out.println(set);
- }
如图👇

ZSet 类型和 Set类型一样,也是 String类型元素的集合,且不允许有重复的成员。不同的是每个元素都会关联一个 double类型的分数。它正是通过分数来为集合中的成员进行从小到大的排序。ZSet 类型的成员是唯一的,但分数(score)却可以重复。
- @Test
- public void opsForZSetTest(){
- //1、opsForZSet 新增操作
- ZSetOperations
zSetOperations = stringRedisTemplate.opsForZSet(); - zSetOperations.add("zset", "java", 1);
- zSetOperations.add("zset", "hello", 3);
- zSetOperations.add("zset", "world", 2);
- //2、opsForZSet 查询操作
- Set
set = stringRedisTemplate.opsForZSet().range("zset",0,2); - System.out.println(set);
- }
如图👇

Hash类型 是一个键值对的集合。它是一个 String类型 的 field 和 value 组合的映射表,它特别适合用于存储对象。
- @Test
- public void opsForHashTest(){
- //1、opsForHash 新增操作
- HashOperations
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);
- }
如图👇

既然是缓存,那必不可少的就是设置过期时间了,需要确定的是 key ,适用于value、list、set等各种类型,下边举个例子👇
- @Test
- public void expireTest(){
- stringRedisTemplate.expire("set",5, TimeUnit.SECONDS);
- }
类似 MongoDB,Spring Data 也为其他的数据库提供了数据访问的支持,至于Redis 的话,虽然没有专属的 Repository 类,但可以使用 CrudRepository。
@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;
-
- }
继承CrudRepository接口,同时第一个入参为指定实体类!
路径:src/main/java/com/yinyu/redisdemo/repository/UserRepository.java
- @Repository
- public interface UserRepository extends CrudRepository
{ -
- }
个人理解可能这种方式是封装了 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博客