Redis 介紹
Redis是一款開源的使用ANSI C語言編寫、遵守BSD協議、支持網絡、可基於內存也可持久化的日志型、Key-Value高性能數據庫。
數據模型
Redis 數據模型不僅與關系數據庫管理系統(RDBMS)不同,也不同於任何簡單的 NoSQL 鍵-值數據存儲。Redis 數據類型類似於編程語言的基礎數據類型,所以開發人員感覺很自然。每個數據類型都支持適用於其類型的操作。受支持的數據類型包括:
- string(字符串)
- hash(哈希)
- list(列表)
- set(集合)
- zset(sorted set:有序集合)
關鍵優勢
Redis 的優勢包括它的速度、它對富數據類型的支持、它的操作的原子性,以及它的通用性:
- 讀速度為110000次/s,寫速度為81000次/s,性能極高。
- 豐富的數據類型,Redis 對大多數開發人員已知道的大多數數據類型提供了原生支持,這使得各種問題得以輕松解決。
- 原子性,因為所有 Redis 操作都是原子性的,所以多個客戶端會並發地訪問一個 Redis 服務器,獲取相同的更新值。
- 豐富的特性,Redis 是一個多效用工具,有非常多的應用場景,包括緩存、消息隊列(Redis 原生支持發布/訂閱)、短期應用程序數據(如 Web 會話、Web 頁面命中計數)等。
springboot集成Redis
1、創建集成redis的springboot項目
我直接用idea創建一個新的工程,在創建的時候,直接集成Redis,如下圖
2.application 配置(application.yml)
spring:
redis:
# Redis 服務器地址
host: 192.168.142.128
# Redis 服務器連接端口
port: 6379
# Redis 服務器連接密碼(默認為空)
password:
# Redis 數據庫索引(默認為0)
database: 1
jedis:
pool:
# 連接池最大連接數(使用負值表示沒有限制)
max-active: 8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
max-wait: -1
# 連接池中的最大空閑連接
max-idle: 8
3、Redis 對多種數據類型的操作
這里我直接在Test類中進行操作,注入RedisTemplate
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisDemo01ApplicationTests {
@Resource
private RedisTemplate redisTemplate;
@Test
public void contextLoads() {
}
- String類型
/**
* 測試存儲String
*/
@Test
public void testString(){
redisTemplate.opsForValue().set("maomao", "hello");
System.out.println(redisTemplate.opsForValue().get("maomao").toString());
}
//輸出hello
- hash類型
hash set 的時候需要傳入三個參數,第一個為 key,第二個為 field,第三個為存儲的值。一般情況下 Key 代表一組數據,field 為 key 相關的屬性,而 value 就是屬性對應的值.
/**
* hash
*/
@Test
public void testHash() {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put("hash","hello","java");
String value=(String) hash.get("hash","hello");
System.out.println("hash value :"+value);
}
//輸出 hash value :java
- list類型
Redis list 的應用場景非常多,也是 Redis 最重要的數據結構之一。 使用 List 可以輕松的實現一個隊列,List 典型的應用場景就是消息隊列,可以利用 list 的 PUSH 操作,將任務存在 list 中,然后工作線程再用 POP 操作將任務取出進行執行。
@Test
public void testListPop() {
String key="list";
redisTemplate.delete(key);
ListOperations<String, String> list = redisTemplate.opsForList();
list.leftPush(key,"just");
list.leftPush(key,"do");
list.leftPush(key,"it");
String value=list.leftPop(key);
System.out.println("list value :"+value);
}
//輸出結果 list value :it
使用 range 來讀取,range 后面的兩個參數就是插入數據的位置,輸入不同的參數就可以取出隊列中對應的數據。
@Test
public void testListRange() {
String key="list";
redisTemplate.delete(key);
ListOperations<String, String> list = redisTemplate.opsForList();
list.rightPush(key,"just");
list.rightPush(key,"do");
list.rightPush(key,"it");
List<String> values=list.range(key,0,3);
for (String v:values){
System.out.println("list range :"+v);
}
}
//輸出結果
//list range :just
//list range :do
//list range :it
- set類型
Redis set 對外提供的功能與 list 類似是一個列表的功能,特殊之處在於 set 是可以自動排重的,當需要存儲一個列表數據,又不希望出現重復數據時,set 是一個很好的選擇,並且 set 提供了判斷某個成員是否在一個 set 集合內的重要接口,這個也是 list 所不能提供的。
@Test
public void testSet(){
String key = "set";
redisTemplate.delete(key);
SetOperations<String,String> set = redisTemplate.opsForSet();
set.add(key,"just");
set.add(key,"do");
set.add(key,"do");
set.add(key,"it");
Set<String> values = set.members(key);
for (String value:values){
System.out.println("set value :"+value);
}
}
//輸出結果
//set value :just
//set value :it
//set value :do
Redis 為集合提供了求交集、並集、差集等操作,可以非常方便的使用
@Test
public void testSetMore() {
SetOperations<String, String> set = redisTemplate.opsForSet();
String key1="setMore1";
String key2="setMore2";
set.add(key1,"just");
set.add(key1,"do");
set.add(key1,"do");
set.add(key1,"it");
set.add(key2,"java");
set.add(key2,"do");
Set<String> diffs=set.difference(key1,key2);
for (String v:diffs){
System.out.println("diffs set value :"+v);
}
//輸出
//diffs set value :it
//diffs set value :just
String key3="setMore3";
String key4="setMore4";
set.add(key3,"just");
set.add(key3,"do");
set.add(key3,"java");
set.add(key4,"it");
set.add(key4,"do");
set.add(key4,"hello");
Set<String> unions=set.union(key3,key4);
for (String v:unions){
System.out.println("unions value :"+v);
}
//輸出
//unions value :do
//unions value :java
//unions value :just
//unions value :it
//unions value :hello
}
- zset
Redis sorted set 的使用場景與 set 類似,區別是 set 不是自動有序的,而 sorted set 可以通過用戶額外提供一個優先級(score)的參數來為成員排序,並且是插入有序,即自動排序。
@Test
public void testZset(){
String key="zset";
redisTemplate.delete(key);
ZSetOperations<String, String> zset = redisTemplate.opsForZSet();
zset.add(key,"just",1);
zset.add(key,"now",5);
zset.add(key,"it",4);
zset.add(key,"do",3);
Set<String> zsets=zset.range(key,0,3);
for (String v:zsets){
System.out.println("zset value :"+v);
}
//zset value :just
//zset value :do
//zset value :it
//zset value :now
Set<String> zsetB=zset.rangeByScore(key,0,3);
for (String v:zsetB){
System.out.println("zsetB value :"+v);
}
//zsetB value :just
//zsetB value :do
}
4.Redis 其他的操作
- 超時失效
/**
* 測試超時失效
* @throws InterruptedException
*/
@Test
public void testExpire() throws InterruptedException {
ValueOperations<String, String> operations=redisTemplate.opsForValue();
operations.set("expire", "java",100,TimeUnit.MILLISECONDS);
Thread.sleep(1000);
boolean exists=redisTemplate.hasKey("expire");
if(exists){
System.out.println("exists is true");
}else{
System.out.println("exists is false");
}
}
// 輸出 exists is false
- 刪除數據
/**
* 刪除數據
*/
@Test
public void testDelete() {
ValueOperations<String, String> operations=redisTemplate.opsForValue();
operations.set("deletekey", "springboot");
redisTemplate.delete("deletekey");
//判斷key是否還在
boolean exists=redisTemplate.hasKey("deletekey");
if(exists){
System.out.println("exists is true");
}else{
System.out.println("exists is false");
}
}
//輸出 exists is false
5、封裝
在實際的使用過程中,不會給每一個使用的類都注入 redisTemplate 來直接使用,一般都會對業務進行簡單的包裝,最后提供出來對外使用. 這里就不在展示
完整代碼下載:github