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

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博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值