当前位置: 首页 > article >正文

Java操作Redis

介绍

前面我们讲解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在
java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使
用JDBC操作MySQL数据库一样。


Redis 的 Java 客户端很多,官方推荐的有

        *Jedis
        *Lettuce
        *Redisson

Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目
中还提供了对应的Starter,即 spring-boot-starter-data-redis。
 

一: Jedis使用介绍

Jedis 是 Redis 的 Java 版本的客户端实现。
maven坐标:

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>

使用 Jedis 操作 Redis 的步骤:
获取连接
执行操作
关闭连接

1.2 Jedis类常用方法

每个方法就是redis中的命令名,方法的参数就是命令的参数。


在每次访问Redis数据库的时候,都需要创建一个Jedis对象。每个Jedis对象似于JDBC
中Connection对象,类似于mybatis中session对象。

1.3 Jedis的基本操作

使用Jedis上面的方法来访问Redis,向服务器中写入字符串、hash类型,并且取出打
印到控制台上。
        *操作字符串数据

@Test
public void test() {
//获取连接 p1:服务器ip地址 p2:redis端口号
Jedis jedis=new Jedis("192.168.112.128",6379);
//往redis数据库中存储字符串数据
jedis.set("username","张三");
//获取数据
String key = jedis.get("username");
System.out.println(key);
//一次性添加多个数据
jedis.mset("addr","sh","age","23");
//获取所有的数据
List<String> list = jedis.mget("username", "addr", "age");
System.out.println(list);
//关闭连接
jedis.close();
}

操作hash数据

@Test
public void test() {
//获取连接 p1:服务器ip地址 p2:redis端口号
Jedis jedis=new Jedis("192.168.112.128",6379);
//往redis数据库中存储hash数据
jedis.hset("user","username","lisi");
jedis.hset("user","password","123456");
//获取redis中的hash数据
Map<String, String> map = jedis.hgetAll("user");
System.out.println(map);
//关闭连接
jedis.close();
}

五.Spring Data Redis

5.1 介绍

Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就
可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可
以使用Spring Data Redis来简化 Redis 操作。

网址:Spring Data Redis

Spring Boot提供了对应的Starter,maven坐标:

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

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对 Jedis 客户
端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

        ValueOperations:简单K-V操作
        SetOperations:set类型数据操作
        ZSetOperations:zset类型数据操作
        HashOperations:针对hash类型的数据操作

        ListOperations:针对list类型的数据操作

5.2 环境搭建

创建maven项目,配置pom.xml文件

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/>
</parent>
<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>

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

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.5</version>
</plugin>
</plugins>
</build>

编写启动类

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

配置application.yml

spring:
    #Redis相关配置
    redis:
        host: 192.168.112.128 # 连接linux系统的redis
        port: 6379 # 端口号
        database: 0 #操作的是0号数据库

spring.redis.database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个
数据库,编号分别是从0到15。
可以通过修改Redis配置文件来指定数据库的数量。

        提供配置类

//@Configuration
public class RedisConfig extends CachingConfigurerSupport {
/*
    RedisConnectionFactory 是获取RedisConnection对象的,
    RedisConnection相当于jdbc中的连接对象Connection表示和Redis进行
    连接
    */
    @Bean
    public RedisTemplate<Object, Object>
    redisTemplate(RedisConnectionFactory connectionFactory) {
    //创建Redis模板对象
    RedisTemplate<Object, Object> redisTemplate = new
    RedisTemplate<>();
    //默认的Key序列化器为:JdkSerializationRedisSerializer
    //StringRedisSerializer支持字符串类型的转化,而且默认使用UTF-8编码
    //下面代码的意思是使用StringRedisSerializer序列化器替换默认的Key
    //序列化器JdkSerializationRedisSerializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(connectionFactory);

    return redisTemplate;
    }
}

因为默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后
的数据和原始数据有差别。如果我们想要存储的key是正常的key,我们可以使用如下
配置类,当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate
对象。

        *提供测试类

@SpringBootTest
public class SpringDataRedisTest {
//自动装配:从SpringIOC容器中获取RedisTemplate模板对象
@Autowired
private RedisTemplate redisTemplate;
}

5.3 操作字符串类型数据


        *存入数据和取出数据
        *存值并设置过期时间
        *如果存在值则不执行任何操作

//操作String类型的数据
@Test
public void test01(){
//1.存入数据和取出数据
//根据模板对象redisTemplate获取操作string类型的接口
ValueOperations对象
ValueOperations valueOperations =
redisTemplate.opsForValue();
//使用valueOperations对象调用方法
valueOperations.set("username","张三");
//获取数据
String username = (String)
valueOperations.get("username");
System.out.println(username);
//2.存值并设置过期时间
valueOperations.set("address","cs",15, TimeUnit.SECONDS);
//3.如果值不存在则存储,如果存在则不存储
Boolean b = valueOperations.setIfAbsent("age", 23);
System.out.println(b);
}
5.4 操作哈希类型数据

        存储几个哈希类型的数据
        获取哈希类型的数据
        根据键获取哈希类型中的所有字段
        获得hash结构中的所有值

//操作哈希类型数据
@Test
public void test02(){
//获取操作hash类型数据的接口对象
HashOperations hashOperations =
redisTemplate.opsForHash();
//1.存储几个哈希类型的数据
hashOperations.put("person","username","zhangsan");
hashOperations.put("person","password","123456");
//2.获取哈希类型的数据
Object obj = hashOperations.get("person", "username");
System.out.println(obj);
//3.根据键获取哈希类型中的所有字段
Set ks = hashOperations.keys("person");
System.out.println(ks);
//4.获得hash结构中的所有值
List vs = hashOperations.values("person");
System.out.println(vs);
}
}
5.5 操作列表类型数据

        向列表中添加数据
        查询列表中所有数据

//操作List类型的数据
@Test
public void test03(){
//获取操作redis服务器的value类型是list类型的接口对象
        ListOperations listOperations =
    redisTemplate.opsForList();
    //1.向列表中添加数据
    listOperations.leftPushAll("addrs","北京","上海","广州","深圳");
    //2.查询列表中所有数据
    List list = listOperations.range("addrs", 0, -1);
        System.out.println(list);
}
5.6 操作set集合类型数据

        向set集合中添加数据
        获取指定set集合的所有的元素
        删除指定set集合的数据

//操作Set类型的数据
@Test
public void test04(){
//获取操作set类型的接口对象
SetOperations setOperations = redisTemplate.opsForSet();
//1.向set集合中添加数据
setOperations.add("myset","数学", "语文", "英语");
//2.获取指定set集合的所有的元素
Set myset = setOperations.members("myset");
System.out.println(myset);
//3.删除指定set集合的数据
Long count = setOperations.remove("myset", "语文");
Set my = setOperations.members("myset");
System.out.println(my);
}
5.7 操作有序集合类型数据

        向zset中添加数据
        从zset中取出数据
        对某个值的分数进行加20

        删除数据

//操作ZSet类型的数据
@Test
public void test05(){
//获取操作zSet类型的接口对象
ZSetOperations zSetOperations =
redisTemplate.opsForZSet();
//1.向zset中添加数据
zSetOperations.add("country","USA",1);
zSetOperations.add("country","USB",100);
//2.从zset中取出数据
Set set = zSetOperations.range("country", 0, -1);
System.out.println(set);
//3.对某个值的分数进行加20
zSetOperations.incrementScore("country","USB",20);
Set<ZSetOperations.TypedTuple> cs =
zSetOperations.rangeWithScores("country", 0, -1);
for (ZSetOperations.TypedTuple c : cs) {
Double score = c.getScore();
Object value = c.getValue();
System.out.println(value+"..."+score);
}
//4.删除数据
zSetOperations.remove("country","USB");
}
5.8 通用操作

        获取Redis中所有的key
        判断某个key是否存在
        删除指定key
        获取指定key对应的value的数据类型

//通用操作,针对不同的数据类型都可以操作
@Test
public void test06(){
//获取Redis中所有的key
Set<String> keys = redisTemplate.keys("*");
System.out.println(keys);

//判断某个key是否存在
Boolean itcast = redisTemplate.hasKey("country");
System.out.println(itcast);
//删除指定key
redisTemplate.delete("addrs");
//获取指定key对应的value的数据类型
DataType dataType = redisTemplate.type("myset");
System.out.println(dataType.name());
}

六.Redis持久化机制

6.1 Redis持久化

问:把服务端关闭了,再重新开启服务器,数据会不会丢失?

会部分丢失,因为默认redis服务器每隔一段时间写入一次内存中数据到硬盘上。

什么是Redis的持久化:

Redis是一个内存存储的数据库,内存必须在通电的情况下才能够对数据进行存储。
如果 ,在使用redis的过程中突然发生断电,数据就会丢失。为了防止数据丢失,
redis提供了数据持久化的支持。

持久化:把内存中的数据保存到硬盘上。
作用:防止数据在断电的情况下丢失。

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步
到磁盘来保证持久化。redis支持两种持久化方式,一种是RDB(快照)也是默认方式,
另一种是Append Only File(缩写AOF)的方式。下面分别介绍:

        RDB:Redis DataBase 默认的持久化方式,以二进制的方式将数据写入文件
        中。每隔一段时间写入一次。

        AOF:Append Only File 以文本文件的方式记录用户的每次操作,数据还原时
        候,读取AOF文件,模拟用户的操作,将数据还原。

6.2 RDB持久化介绍

        RDB是默认的持久化方式。这种方式就是将内存中数据以快照的方式写入到二进制文
        件中,默认的文件名为:dump.rdb
        快照:当前内存中数据的状态。

可以通过配置设置自动做快照持久化的方式。如下面配置的是RDB方式数据持久化时
机,必须两个条件都满足的情况下才进行持久化的操作:

缺点: 可能导致数据丢失。因为RDB是每隔一段时间写入数据,所以系统一旦
在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
优点:持久化效率高,持久化的是内存中的数据;数据库宕机后,数据恢复的效率要更
高;

6.3 AOF的存储方式

由于快照方式是在一定间隔时间做一次的,所以如果redis宕机,就会丢失最后一次
快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用AOF持久化方
式。
AOF指的是Append only file,使用AOF持久化方式时,redis会将每一个收到的写命令
都通过write函数追加到文件中(默认是appendonly.aof).当redis重启时会通过重新执
行文件中保存的写命令来在内存中重建整个数据库的内容。

AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。也可以通过
该文件完成数据的重建。该机制可以带来更高的数据安全性,所有的操作都是异步完
成的。

6.3.1 AOF持久化机制配置

        开启AOF持久化
AOF默认是关闭的,首先需要开启AOF模式

AOF持久化时机

        everysec:每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中。
        alway:收到写命令就立即写入磁盘,最慢,但是保证完全的持久化。
        no:完全依赖操作系统,性能最好,持久化无法保证。

6.3.2 AOF的持久化

打开AOF的配置文件redis.conf,设置appendonly yes

通过./redis-server redis.conf启动服务器,在服务器目录下出现appendonly.aof
文件。大小是0个字节。

添加键和值

打开appendonly.aof文件,查看文件的变化。会发现文件记录了所有操作的过
程。

*2表示有两个命令 select 0 选择第一个数据库
$6表示select 有六个字符 $1 表示0有一个字符

 

6.4 Redis持久化机制RDB和AOF的区别

6.4.1 RDB持久化机制优点和缺点

优点
方便备份与恢复

启动效率更高:相比于AOF机制,如果数据集很大,RDB的启动效率会更高。因
为RDB文件中存储的是数据,启动的时候直接加载数据即可,而AOF是将操作数
据库的命令存放到AOF文件中,然后启动redis数据库服务器的时候会将很多个命
令执行加载数据。如果数据量特别大的时候,那么RDB由于直接加载数据启动效
率会比AOF执行命令加载数据更高。
性能最大化:对于Redis的服务进程而言,在开始持久化时,会在后台开辟子线
程,由子线程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操
作了。

缺点:

不能完全避免数据丢失:因为RDB是每隔一段时间写入数据,所以系统一旦在定
时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
会导致服务器暂停的现象:由于RDB是通过子线程来协助完成数据持久化工作
的,因此当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1
秒钟。就是数据量过大,会开辟过多的子线程进行持久化操作,那么会占用服务
器端的大量资源,那么有可能会造成服务器端卡顿。同时会造成服务器停止几百
毫秒甚至一秒。

6.4.2 AOF持久化机制优点和缺点

优点
AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。也可以通过
该文件完成数据的重建。该机制可以带来更高的数据安全性,所有的操作都是异步完
成的。
缺点
运行效率比RDB更慢:根据同步策略的不同,AOF在运行效率上往往会慢于
RDB。
文件比RDB更大:对于相同数量的数据集而言,AOF文件通常要大于RDB文件。


http://www.kler.cn/a/451418.html

相关文章:

  • ROM修改进阶教程------修改刷机包init.rc 自启用户自定义脚本的一些基本操作 代码格式与注意事项
  • leetcode hot100 将有序数组转化为二叉搜索树
  • Linux复习4——shell与文本处理
  • 【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
  • AtCoder Beginner Contest 385(A~F)题解
  • springBoot Maven 剔除无用的jar引用
  • [工具]GitHub Copilot 直接提供免费额度了
  • 【IoTDB 线上小课 10】为什么选择 IoTDB 管理时序数据?
  • 2.利用docker进行gitlab服务器迁移
  • rust学习: 有用的命令
  • Datawhale-AI活动2024.12.24
  • 【docker】docker desktop 在windows上支持 host模式
  • SQL语法基础知识总结
  • 抢票神器:大麦网抢票实战教程
  • Qt笔记:文件I/O操作
  • Android studio开启虚拟机闪退、闪屏、死机、电脑重启
  • Web Server for Chrome 使用教程
  • 虚幻引擎结构之AActor
  • 电子应用设计方案70:智能挂钟系统设计
  • C语言——数据在内存中的存储
  • Django REST framework (DRF)中的api_view和APIView权限控制
  • 如何设置爬虫的访问频率?
  • 物理层知识要点
  • Oracle 数据库锁与阻塞分析与解决指南
  • 优化程序中的数据:从代数到向量解
  • 2024最新鸿蒙开发面试题合集-HarmonyOS NEXT Release(API 12 Release)