本文記錄學習在SpringBoot中使用Redis。java
Redis 是一個速度很是快的非關係數據庫(Non-Relational Database),它能夠存儲鍵(Key)與 多種不一樣類型的值(Value)之間的映射(Mapping),能夠將存儲在內存的鍵值對數據持久化到硬盤,可使用複製特性來擴展讀性能,還可使用客戶端分片來擴展寫性能。Redis主要有如下幾個優勢:redis
1 性能極高,它每秒可執行約 100,000 個 Set 以及約 100,000 個 Get 操做;spring
2 豐富的數據類型,Redis 對大多數開發人員已知的大多數數據類型提供了原生支持,這使得各類問題得以輕鬆解決;數據庫
3 原子性,由於全部 Redis 操做都是原子性的,因此多個客戶端會併發地訪問一個 Redis 服務器,獲取相同的更新值;緩存
4 豐富的特性,Redis 是一個多效用工具,有很是多的應用場景,包括緩存、消息隊列(Redis 原生支持發佈/訂閱)、短時間應用程序數據(好比 Web 會話、Web 頁面命中計數)等。安全
目前咱們經常使用的Value的數據類型有String(字符串),Hash(哈希),List(列表),Set(集合),Zset(有序集合)。服務器
SpringBoot提供了對Redis的集成的模塊,包是spring-boot-starter-data-redis,它依賴於 spring-data-redis 和 lettuce,lettuce是一個線程安全的redis客戶端。併發
在pom.xml中引入依賴app
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
在application.properties中配置Redis的鏈接信息spring-boot
# redis 配置
## redis數據庫索引(默認0)
spring.redis.database=0
## redis 服務器地址
spring.redis.host=localhost
## redis 服務器端口
spring.redis.port=6379
## redis數據庫密碼(默認爲空)
spring.redis.password=
## redis鏈接池最大鏈接數(使用負數表示沒有顯示,默認8)
spring.redis.lettuce.pool.max-active=8
## 鏈接池最大阻塞等待時間(使用負值表示沒有限制,默認-1)
spring.redis.lettuce.pool.max-wait=-1
## 鏈接池中的最大空閒鏈接 默認 8
spring.redis.lettuce.pool.max-idle=8
## 鏈接池中的最小空閒鏈接 默認 0
spring.redis.lettuce.pool.min-idle=0
有了上邊這兩個步驟以後,咱們啓動服務後,SpringBoot就會幫咱們鏈接到Redis服務器,並給咱們提供了一個RedisTemplate類供咱們使用操做Redis。咱們在須要用的地方注入RedisTemplate就能夠輕鬆完成操做。
使用Junit作測試,在咱們的單元測試類中注入RedisTemplate
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
}
String字符串操做,value是一個字符串,經過delete(key)刪除
@Test
public void testString() throws InterruptedException {
//字符串
ValueOperations strOps = redisTemplate.opsForValue();
strOps.set("name", "梓&藝");
System.out.println("字符串結果name:"+strOps.get("name"));
//刪除key
redisTemplate.delete("name");
}
對象操做,value是一個對象
@Test
public void testObject() throws InterruptedException {
ValueOperations objOps = redisTemplate.opsForValue();
City city = new City(1, "X`A", "西安");
objOps.set("city", city);
System.out.println(objOps.get("city").toString());
redisTemplate.delete("city");
}
設置key的過時時間,在set時加上過時時間,經過hasKey(key)來判斷key是否還存在
@Test
public void testExpire(){
//過時
ValueOperations objOps1 = redisTemplate.opsForValue();
City city1 = new City(1, "BJ", "北京");
objOps1.set("expire", city1, 2000, TimeUnit.MILLISECONDS);
System.out.println(objOps1.get("expire").toString());
Thread.sleep(2000);
System.out.println(redisTemplate.hasKey("expire"));
}
hash哈希操做
@Test
public void testHash() {
HashOperations hashOps = redisTemplate.opsForHash();
hashOps.put("hash","hashKey","hashValue");
System.out.println(hashOps.get("hash", "hashKey"));
}
在上邊的代碼中能夠看出,Hash Set的時候就是在哈希表 Key 中的域(Field)的值設爲 value。若是 Key 不存在,一個新的哈希表被建立並進行 Hash set 操做;若是域(Field)已經存在於哈希表中,舊值將被覆蓋。
List列表操做
@Test
public void testList() {
ListOperations<String, String> listOps = redisTemplate.opsForList();
listOps.leftPush("list","梓");
listOps.leftPush("list","&");
listOps.leftPush("list","藝");
System.out.println(listOps.leftPop("list"));
}
列表操做時咱們經過 leftPush 或者 rightPush 來將數據存入列表中,經過 leftPop 或者rightPop將數據取出來,咱們能夠利用它來實現一個隊列。
Set集合操做
@Test
public void testSet() {
SetOperations<String, String> setOps = redisTemplate.opsForSet();
setOps.add("set","梓");
setOps.add("set","&");
setOps.add("set","&");
setOps.add("set","藝");
System.out.println(setOps.members("set"));
}
Set是一個沒有順序的集合,key相同時,若是value已經存在了,後邊進入的會把前邊的覆蓋掉
ZSet有序集合操做
@Test
public void testZSet() {
ZSetOperations zSetOps = redisTemplate.opsForZSet();
zSetOps.add("zSet", "梓", 1);
zSetOps.add("zSet", "&", 2);
zSetOps.add("zSet", "藝", 3);
zSetOps.add("zSet", "zi", 1);
zSetOps.add("zSet", "yi", 3);
System.out.println(zSetOps.rangeByScore("zSet", 1, 3));
}
add 方法的3個參數分別是key,value,數據插入位置。ZSet中存儲的數據都是有順序的,輸出時順序按照存儲時設置的從小到大,若是遇到key相同,Value和順序同樣的,後邊的會把前邊的覆蓋掉,range方法後邊的2個參數時插入的位置。如上的輸出