越來越發現包括redis在內的非關係型數據庫在工作實現中重要性。利用redis做數據的緩存處理、防止對數據庫的惡意攻擊等都有很大幫助。在這裏做個redis的系統介紹,和常用方法總結,供以後參看並和朋友們分享。
Redis安裝請自行百度,本篇文章redis部署在window10專業版上,且添加在了window服務進程當中,還有用到redis的桌面化工具redis-desktop-manager-0.8.8.384。在這裏附上我用的工具包
目錄
Redis介紹
要介紹Redis就要先說說非關係型數據庫NOSQL,NOSQL,即non-relational或者Not Only StrucStructured Query Language(兩者都是非關係型數據庫的意思,後者更爲通俗),其這樣的名字主要是爲了區分於常規的SQL(結構化查詢語言)。NOSQL的誕生是爲了解決Web2.0時代大規模數據集合多重數據種類帶來的挑戰,尤其是大數據應用難題。NOSQL沒有一個明確的範圍和定義,但都普遍存在易擴展、大數據量、高性能、高可用、靈活的數據模型等幾個特點。Redis作爲非關係型數據庫的一種,其自然也包含非關係型數據庫普遍擁有的特點。
Redis是用C語言編寫的一個開源的高性能鍵值對(key-value)數據庫,根據官方提供的測試數據,50個併發100000(十萬)個請求,讀的速度是110000次/s(十萬),寫的速度是81000次/s(萬),且redis通過提供多種鍵值數據類型來適應不同場景下的存儲需求,redis常用的鍵值數據類型如下
字符串類型string:key value 類型 最大能存儲512M,redis 的 string 可以包含任何數據。比如jpg圖片或者序列化的對象。,
散列類型 hash:hash 是一個鍵值(key=>value)對集合,特別適合用於存儲對象
列表類型 list:list 是鏈表結構,所有如果在頭部和尾部插入數據,性能會非常高,不受鏈表長度的影響;但如果在鏈表中插入數據,性能就會越來越差。
集合類型 set:Set 是 string 類型的無序不可重複集合,集合是通過哈希表實現的,所以添加,刪除,查找的複雜度都是 O(1)。
有序集合類型 sortedset(zset):zset 和 set 一樣也是string類型元素的集合,且不允許重複的成員,不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來爲集合中的成員進行從小到大的排序,zset的成員是唯一的,但分數(score)卻可以重複
redis默認端口號是6379
鍵值(key-value)數據類型簡介
|
增/改 |
查 |
刪 |
字符串String |
set key value |
get key |
del key |
字符串列表list |
lpush |
lrang key index1 index2 |
lpop/rpop(從左推/從右推) |
無序集合set |
sadd |
smembers key |
srem key mebmers[member1 member2] |
有序集合sorted set |
zadd key values[value1、value2…] (例:zadd sortlist 5 lisi 10 xiaoming 7 xiaohua 8 xiaogou) |
zrang key index1 index2 |
zrem key member |
散列(或者叫哈希)hash |
hset key field value (例:hset myhash username peng) |
hget key field ( hget myhash username /*或者*/hgetall myhash ) |
hdel myhash username[fiel1,fiel2,.....] |
通用命令 |
keys *(查看所有鍵) |
exists key(判斷鍵是否存在1,存在,0不存在) |
del key1 key2…(刪除指定鍵) |
|
keys key(返回指定的鍵) |
type key(獲取指定鍵的類型) |
|
SpringDataRedis總結
java使用redis需要導入的包
maven中的座標
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
Spring-data-redis是spring大家族的一部分,提供了在srping應用中通過簡單的配置訪問redis服務,對reids底層開發包(Jedis, JRedis, and RJC)進行了高度封裝,RedisTemplate提供了redis各種操作、異常處理及序列化,支持發佈訂閱,並對spring 3.1 cache進行了實現。
配置
配置參數:因爲創建的是springboot項目,相關配置只需要在application.yml中聲明配置即可,注意yml對格式要求極高,包括空格都不能錯
spring:
application:
name: user-auth
redis:
host: 127.0.0.1
port: 6379
password:
jedis:
pool:
max-active: 8
max-idle: 8
min-idle: 0
下面寫一個demo測試下redis是否連通
package com.heronsbill.redisdemo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: heronsbill
* @DATA: 2019/10/12
*/
@RestController
@RequestMapping("/redis")
public class RedisDemo01 {
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("/get")
public Object main() {
redisTemplate.boundValueOps("niu").set("11");
redisTemplate.opsForValue().set("muji","不好");
return redisTemplate.opsForValue().get("muji");
}
}
啓動springboot項目後,利用postman輸入連接http://127.0.0.1:8080/redis/get,最後得到“不好”
這裏要注意一點,RedisTemplate會默認使用JdkSerializationRedisSerializer作爲序列化工具,所以存在redis中的數據無論是key還是value前面都有一串特殊符號
特殊符號是redis默認的序列化方式產生的序列化標記,不影響數據的存取。想取消序列化標記,需要在啓動類中配redisTemplate
如下:
/**
* 設置 redisTemplate 的序列化設置
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 1.創建 redisTemplate 模版
RedisTemplate<Object, Object> template = new RedisTemplate<>();
// 2.關聯 redisConnectionFactory
template.setConnectionFactory(redisConnectionFactory);
// 3.創建 序列化類
GenericToStringSerializer genericToStringSerializer = new GenericToStringSerializer(Object.class);
// 6.序列化類,對象映射設置
// 7.設置 value 的轉化格式和 key 的轉化格式
template.setValueSerializer(genericToStringSerializer);
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
這樣,再存取數據,就不會有序列化標記了。到此配置完成。
不同類型數據的操作
關於spring-data-redis其實現了 連接池自動管理,並且提供了一個高度封裝的“RedisTemplate”類,裏面爲數據操作準備了兩套方法,一套是ops開頭的一套是bound開頭的,bound開頭的方法需要傳key值,裏面會對key進行一些初始化的設置,如空值的處理等。其他的區別還在研究中。但是在涉及到多個用戶同時操作同一數據時,ops這套方法能夠有效鎖住數據(類似於單線程操作),bound卻不能(類似於多線程操作)。這裏兩套方法都演示。
String
|
bound |
ops |
頂級接口 |
|
|
增 |
set(Object value) 簡單的給鍵賦值 set(Object value,long l) 給value的第幾個字節賦值,空出的位置用x00補位,字母和數字佔一個字節漢字佔3個字節 set(Object value,Duration timout) 設置當前字符串在redis的有效時間 set(Object value,long l TimeUnit timeUnit) TimeUnit是時間顆粒,秒級,分級等 |
bound有的方法,ops都有 但這裏還有一些其他很有用的方法
|
查 |
get() getAndSet(Object value) |
get(Object key) getAndSet(Object key,Object value) 獲取之前的值,並修改 |
刪 |
除了刪除Key值外,也可以通過設置有效時間爲1s實現刪除 |
|
其他 |
|
List
list是鏈表,所以涉及到的操作着重於頭和尾的操作,也就是壓棧和出棧
|
bound |
ops |
頂級接口 |
|
|
壓棧 |
rightPush(Object value) leftPush(Object value) rightPushAll(Object ... vs) leftPushAll(Object ... vs) rightPushIfPresent(Object value) leftPushIfPresent(Object value) |
|
出棧 |
出棧操作類似於壓棧操作將push換做pop(ops方法類似) |
|
改 |
set(long index,Object value)在第幾個位置修改,注意這裏不能修改不存在的值(ops方法類似) |
|
其他 |
|
set
|
bound |
ops |
頂級接口 |
|
|
增 |
add(Object... vs) |
|
查 |
members() |
|
刪 |
remove(Object object)(刪除集合裏面的單個對象) |
|
其他 |
|
zset
|
bound |
ops |
頂級接口 |
|
|
方法說明 |
|
Hash
hash類型集合適合用來存對象,但是java中的對象類都必須實現序列化接口,而存進redis中的數據也都是序列化後的數據,一串看不懂的字符串,但是不影響操作
|
bound |
ops |
頂級接口 |
|
|
增 |
put(Object hk,Object hv) |
|
查 |
get(object hk) |
ops方法類似 |
刪 |
delete() |
ops方法類似 |
其他 |
|
redis和json
json作爲現在比較流行的數據格式在redis中有重要得作用。在存儲數據時往往可以把數據轉換爲json格式字符串然後存進redis,取出來後在進行解析,或者傳給前端使用,都比較方便。這裏以阿里出品的fastjson爲例講解
代碼爲
@GetMapping("/jsonstr")
public Object jsonStr() {
BoundValueOperations jsonstr = redisTemplate.boundValueOps("jsonstr");
// 創建user對象
User user1 = new User(1, "小明", 19);
//將user對象解析爲JSON字符串
String s = JSON.toJSONString(user1);
// 將json字符串存進redis
jsonstr.set(s);
// 獲取redis中的json字符串
String s1 = jsonstr.get(0, -1);
System.out.println("json字符串"+s1);
// 重新解析爲user對象
User user = JSON.parseObject(s1, User.class);
System.out.println("json解析後的user對象"+user);
return user;
}
此時存在redis的是json格式的字符串
後臺輸出結果
當然實際的json操作遠不止現在所說的兩種,後面會繼續總結。
總結
在web2.0時代,數據和流量成爲至關重要的一部分,而大數據量的直接訪問數據庫,勢必會帶來難以修復大麻煩,而通過redis等一些非關係型數據庫作爲數據庫與用戶之間的一個緩存區,大大降低對數據庫的直接訪問。並且通過redis的中間攔截和判斷,也能夠阻攔一些惡意的攻擊。
redis的學習還要繼續。
能力尚淺,有待進步,如有不足,不吝賜教!