目次
3. Java が Redis を操作するために使用する一般的なタイプのデータ ストレージ
序文
Redis は、高性能、複数のデータ構造のサポート、アトミック操作、高可用性およびスケーラビリティを備えたメモリ キャッシュ データベースとして、最新のインターネット サービスにおいて非常に重要な役割を果たしています。Redis を使用して一般的なデータ型を操作することは、Java アプリケーションでは不可欠なスキルです。この記事では、Java が文字列、ハッシュ テーブル、リスト、セット、順序付きセットなどの一般的なデータ型を Redis でどのように操作するかを紹介します。
1. ジェダイの紹介
Jedis は Java 言語で記述された Redis クライアントで、比較的包括的な Redis コマンド操作を提供し、Java コードを使用して Redis サーバーに簡単にアクセスして操作できます。Jedis の最下層は、優れたパフォーマンスと安定性を備えた Java ネットワーク IO フレームワーク Netty と Java シリアル化フレームワーク Kryo を使用します。
1. さまざまな側面におけるジェダイの役割
接続管理と接続プーリング:
- Jedis は、
Jedis
クラスを通じて Redis サーバーとの接続と通信を確立する機能を提供します。- Jedis には接続プール機能が組み込まれており、
JedisPool
クラスを通じて管理できます。接続プーリングにより、パフォーマンスが向上し、毎回の接続の作成と解放にかかるオーバーヘッドが軽減されます。データ型のサポート:
- Jedis は、文字列、ハッシュ テーブル、リスト、セット、順序付きセットなどを含む、Redis のすべてのデータ型をサポートします。
- Jedis は、データ型ごとに、追加、取得、更新、削除などの操作を実行するための対応するメソッドを提供します。
トランザクションのサポート:
- Jedis はトランザクション操作をサポートしており、複数の Redis コマンドを 1 つのトランザクションで実行できます。
- クラスを通じて
Transaction
、複数のコマンドをトランザクションに追加し、一緒にコミットまたはロールバックして、操作のアトミック性を確保できます。パイプラインのサポート:
- Jedis はパイプライン操作をサポートし、複数のコマンドを一度に送信できるため、Redis サーバーとのネットワーク往復回数が削減され、パフォーマンスが向上します。
- クラスを通じて
Pipeline
、複数のコマンドをパイプラインに追加し、Redis サーバーに一度に送信できます。パブリッシュ/サブスクライブ モデルは以下をサポートします。
- Jedis は、Redis のパブリッシュ/サブスクライブ モデルをサポートしており、メッセージ キューやイベント通知などの機能を実装するために使用できます。
- このクラスを通じて
JedisPubSub
、指定されたチャネルをリッスンし、メッセージの受信時に対応するコールバック メソッドを実行するサブスクライバーを作成できます。データのシリアル化と逆シリアル化:
- Jedis はカスタム データのシリアル化と逆シリアル化をサポートしており、
RedisSerializer
インターフェイスを実装することでデータ処理をカスタマイズできます。- デフォルトでは、Jedis は Java のシリアル化メカニズムを使用してデータをシリアル化および逆シリアル化しますが、JSON、XML などの他のシリアル化メソッドも提供します。
高度な機能のサポート:
- Jedis は、分散ロック、Lua スクリプトの実行、ビットマップ操作、地理的位置関連の操作など、いくつかの高度な機能を提供します。
- 分散ロックは、分散システムで同時実行制御を実装し、同時に 1 つのスレッドだけが共有リソースにアクセスできるようにします。
- クラスを通じて
JedisCluster
、Redis クラスターを簡単に操作し、データの読み取り、書き込み、管理を行うことができます。
2.特長
使いやすさ: Jedis はシンプルで使いやすい API を提供するため、Java 開発者は複雑なネットワーク通信やプロトコル解析コードを作成しなくても Redis と簡単に対話できます。
高性能: Jedis は、Redis サーバーからのリクエストに迅速に応答できる Netty ベースの高性能通信フレームワークを使用しており、接続の作成と解放のコストを削減できる接続プール機能を内蔵しています。
すべての Redis データ型をサポート: Jedis は、文字列、ハッシュ テーブル、リスト、セット、順序付きセットなどを含むすべての Redis データ型をサポートし、追加、取得、更新、削除などの操作を実行できます。
トランザクションとパイプラインのサポート: Jedis はトランザクションとパイプライン操作をサポートしており、複数のコマンドを Redis サーバーに一度に送信できるため、パフォーマンスが向上し、操作のアトミック性が確保されます。
パブリッシュ/サブスクライブ モードのサポート: Jedis は、メッセージ キューやイベント通知などの機能を実装するために使用できる Redis のパブリッシュ/サブスクライブ モードをサポートします。
データ シリアル化のサポート: Jedis はカスタム データ シリアル化メソッドをサポートしており、
RedisSerializer
インターフェイスを実装することでデータ処理をカスタマイズできます。分散ロックのサポート: Jedis は分散ロックの実装を提供します。これにより、分散システムで同時実行制御を実装し、1 つのスレッドだけが同時に共有リソースにアクセスできるようになります。
高度な機能のサポート: Jedis は、Lua スクリプトの実行、ビットマップ操作、地理的位置関連の操作など、いくつかの高度な機能を提供します。
クラスターのサポート: Jedis は
JedisCluster
クラスを通じてクラスター操作機能を提供し、Redis クラスターを簡単に操作できます。
2. Java が Redis に接続する
redis と mysq はどちらもデータベースです。Java で redis を操作するプロセスは、実際には mysql を操作するプロセスと似ています。まず、依存関係をインポートして接続を確立しますが、方法が異なります。Redis は非リレーショナル データベースであり、mysql はリレーショナル データベースです。
リレーショナル データベースと非リレーショナル データベースとは何ですか?
- リレーショナル データベースは、リレーショナル モデルに基づいたデータベース システムであり、データが表形式で編成され、SQL (構造化クエリ言語) を使用してクエリおよび管理されます。リレーショナル データベースでは、データは複数のテーブルで構成され、各テーブルには複数の行と列が含まれ、各行はレコードを表し、各列は属性を表します。リレーショナル データベース内のテーブル間に関係を確立でき、これらの関係を通じてデータの共同クエリと更新を実行できます。リレーショナル データベースの最も一般的な例は、MySQL、Oracle、SQL Server です。
- 従来のリレーショナル データベースと比較して、非リレーショナル データベース (NoSQL) は、非リレーショナル データ モデルを使用してデータを保存および処理します。非リレーショナル データベースは通常、テーブルを使用しませんが、大量の非構造化データをより適切に処理するために、キーと値のペア、ドキュメント、グラフなどの他の形式のデータ構造を使用します。NoSQL データベースは一般に、高いスケーラビリティ、柔軟性、パフォーマンスを備えており、複雑なデータ処理タスクを処理できます。非リレーショナル データベースの最も一般的な例は、MongoDB、Cassandra、Redis です。
1. pom 依存関係をインポートする
Maven プロジェクトに redis pom 依存関係をインポートします。
<!--redis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2. 接続を確立する
まず Redis を起動しましょう
package com.ctb.ssm.redis;
import redis.clients.jedis.Jedis;
/**
* @author 彪
* @remark
* @create 2023-11-06 10:30
*/
public class Demo1 {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);//主机地址,端口号
jedis.auth("123456");//密码
System.out.println(jedis.ping());
}
}
接続は成功しました
3. Java が Redis を操作するために使用する一般的なタイプのデータ ストレージ
1. 文字列
String は Redis で最も単純なデータ型であり、最も一般的なデータ型の 1 つです。
package com.ctb.ssm.redis;
// 导入Jedis库
import redis.clients.jedis.Jedis;
public class StringExample {
public static void main(String[] args) {
// 创建Jedis对象,连接Redis服务器
Jedis jedis = new Jedis("localhost");
// 存储字符串数据
jedis.set("name", "John Doe");
// 获取字符串数据
String name = jedis.get("name");
System.out.println("Name: " + name);
// 更新字符串数据
jedis.set("name", "Jane Doe");
name = jedis.get("name");
System.out.println("Updated Name: " + name);
// 删除字符串数据
jedis.del("name");
name = jedis.get("name");
System.out.println("Deleted Name: " + name);
// 关闭连接
jedis.close();
}
}
2. ハッシュテーブル
ハッシュ テーブルは Redis のキーと値の型のデータ構造であり、Java のマップに似ています。
// 导入Jedis库
import redis.clients.jedis.Jedis;
package com.ctb.ssm.redis;
import java.util.HashMap;
import java.util.Map;
public class HashExample {
public static void main(String[] args) {
// 创建Jedis对象,连接Redis服务器
Jedis jedis = new Jedis("localhost");
// 存储哈希表数据
Map<String, String> user = new HashMap<>();
user.put("name", "John Doe");
user.put("age", "30");
user.put("email", "[email protected]");
jedis.hset("user:1", user);
// 获取哈希表数据
Map<String, String> storedUser = jedis.hgetAll("user:1");
System.out.println("Name: " + storedUser.get("name"));
System.out.println("Age: " + storedUser.get("age"));
System.out.println("Email: " + storedUser.get("email"));
// 更新哈希表数据
jedis.hset("user:1", "age", "31");
storedUser = jedis.hgetAll("user:1");
System.out.println("Updated Age: " + storedUser.get("age"));
// 删除哈希表数据
jedis.hdel("user:1", "email");
storedUser = jedis.hgetAll("user:1");
System.out.println("Deleted Email: " + storedUser.get("email"));
// 关闭连接
jedis.close();
}
}
3. リスト
リストは、文字列型の複数の要素を格納できる Redis の順序付けされたデータ構造です。
package com.ctb.ssm.redis;
// 导入Jedis库
import redis.clients.jedis.Jedis;
import java.util.List;
public class ListExample {
public static void main(String[] args) {
// 创建Jedis对象,连接Redis服务器
Jedis jedis = new Jedis("localhost");
// 存储列表数据
jedis.lpush("fruits", "apple");
jedis.lpush("fruits", "banana");
jedis.lpush("fruits", "orange");
// 获取列表数据
List<String> fruits = jedis.lrange("fruits", 0, -1);
for (String fruit : fruits) {
System.out.println("Fruit: " + fruit);
}
// 弹出列表元素
String poppedFruit = jedis.lpop("fruits");
System.out.println("Popped Fruit: " + poppedFruit);
// 关闭连接
jedis.close();
}
}
4. 収集
セットは、複数の文字列型要素を格納できる Redis の順序なしデータ構造であり、各要素は一意です。
package com.ctb.ssm.redis;
// 导入Jedis库
import redis.clients.jedis.Jedis;
import java.util.Set;
public class SetExample {
public static void main(String[] args) {
// 创建Jedis对象,连接Redis服务器
Jedis jedis = new Jedis("localhost");
// 存储集合数据
jedis.sadd("tags", "java");
jedis.sadd("tags", "python");
jedis.sadd("tags", "javascript");
// 获取集合数据
Set<String> tags = jedis.smembers("tags");
for (String tag : tags) {
System.out.println("Tag: " + tag);
}
// 判断元素是否存在于集合中
boolean exists = jedis.sismember("tags", "python");
System.out.println("Python exists in tags set: " + exists);
// 删除集合元素
jedis.srem("tags", "python");
exists = jedis.sismember("tags", "python");
System.out.println("Python exists in tags set after removal: " + exists);
// 关闭连接
jedis.close();
}
}
5.注文回収
順序付きセットは、Redis の順序付きデータ構造です。複数の文字列型要素を格納できます。各要素には対応するスコアがあり、スコアに従って並べ替えることができます。
package com.ctb.ssm.redis;
// 导入Jedis库
import redis.clients.jedis.Jedis;
import java.util.Set;
public class SortedSetExample {
public static void main(String[] args) {
// 创建Jedis对象,连接Redis服务器
Jedis jedis = new Jedis("localhost");
// 存储有序集合数据
jedis.zadd("scores", 90, "Alice");
jedis.zadd("scores", 80, "Bob");
jedis.zadd("scores", 95, "Charlie");
// 获取有序集合数据
Set<String> topScorers = jedis.zrevrange("scores", 0, 2);
for (String scorer : topScorers) {
System.out.println("Top Scorer: " + scorer);
}
// 更新有序集合数据
jedis.zincrby("scores", 5, "Alice");
double aliceScore = jedis.zscore("scores", "Alice");
System.out.println("Updated Alice Score: " + aliceScore);
// 关闭连接
jedis.close();
}
}
4. Redisの具体的な活用シナリオ例
Redis は通常、会議ステータスなど、基本的に変更されないデータを保存するために使用されます。データベースに保存された値は、保留中の会議、過去の会議など、対応するステータスに変換する必要があります。
Redis を使用してストレージを実行し、対応する値に基づいて対応するコンテンツを見つけることができます。
1. 会議情報主体
package com.ctb.ssm.model;
public class Meeting {
private String id;
private String name;
private int state;
// 构造方法、getter和setter省略
}
このうち状態フィールドはint型で表され、1は開催される会議、2は過去の会議、3は解放された会議を表します。
2. カスタム注釈
package com.ctb.ssm.annotation;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface State {
String value();
int code();
}
アノテーションでは、value() メソッドを通じて会議ステータス名が取得され、code() メソッドを通じて会議ステータス値が取得されます。
3. アスペクトクラスの作成
会議情報をクエリするときに会議リストを走査し、ステータス フィールドの値に基づいて特別な処理を実行するために使用されます。
package com.ctb.ssm.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Aspect
@Component
public class MeetingAspect {
private JedisPool jedisPool;
public MeetingAspect() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPool = new JedisPool(jedisPoolConfig, "localhost", 6379);
}
@Around("execution(* com.example.MeetingService.getMeetings())")
public Object processMeetings(ProceedingJoinPoint joinPoint) throws Throwable {
Jedis jedis = jedisPool.getResource();
try {
List<Meeting> meetings = (List<Meeting>) joinPoint.proceed();
for (Meeting meeting : meetings) {
int stateCode = meeting.getState();
// 根据stateCode将会议状态存储到Redis中
jedis.hset("meeting_states", String.valueOf(stateCode), getStateNameByCode(stateCode));
}
return meetings;
} finally {
jedis.close();
}
}
private String getStateNameByCode(int stateCode) {
switch (stateCode) {
case 1:
return "待开会议";
case 2:
return "历史会议";
case 3:
return "发布会议";
default:
return "取消会议";
}
}
}
Redis を操作するための Jedis インスタンスを取得するために JedisPool を作成し、初期化しました。processMeetings メソッドでは、クエリされた会議リスト会議を取得し、各 Meeting オブジェクトを走査できます。会議オブジェクトのステータスフィールドに従って、メソッドを呼び出すことで、対応する会議ステータス名を Redis ハッシュテーブル「meeting_states」に保存state
できます。jedis.hset()
4. 制御層(コントローラー層)を作成する
@RestController
public class MeetingController {
@Autowired
private MeetingService meetingService;
@GetMapping("/meetings")
public List<Meeting> getMeetings() {
List<Meeting> meetings = meetingService.getMeetings();
return meetings;
}
}
すべての会議情報を取得するために、MeetingController にインターフェイス「/meetings」を定義しました。このインターフェイスでは、MeetingService の getMeetings メソッドを呼び出して、すべての会議情報を取得し、それをフロントエンドに直接返します。