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
类似上一篇文章,在腾讯云服务器初次选择系统和重装系统都可以选择 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
org.apache.commons
commons-pool2
路径: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("[email protected]").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("[email protected]").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博客