redis介紹及spring data redis方法總結

越來越發現包括redis在內的非關係型數據庫在工作實現中重要性。利用redis做數據的緩存處理、防止對數據庫的惡意攻擊等都有很大幫助。在這裏做個redis的系統介紹,和常用方法總結,供以後參看並和朋友們分享。

 Redis安裝請自行百度,本篇文章redis部署在window10專業版上,且添加在了window服務進程當中,還有用到redis的桌面化工具redis-desktop-manager-0.8.8.384。在這裏附上我用的工具包

目錄

Redis介紹

鍵值(key-value)數據類型簡介

SpringDataRedis總結

java使用redis需要導入的包

配置

不同類型數據的操作

String   

List

set 

zset

Hash

redis和json

總結


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

頂級接口

BoundValueOperations
redisTemplate.boundValueOps(Object key)

 

ValueOperations
redisTemplate.opsForValue()

 

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都有

但這裏還有一些其他很有用的方法

setIfAbsent() 如果沒有的時候設置
setIfPresent() 如果有的說話設置
這兩個方法的返回值都是Boolean

 

get()

getAndSet(Object value)

get(Object key)

getAndSet(Object key,Object value)  獲取之前的值,並修改

除了刪除Key值外,也可以通過設置有效時間爲1s實現刪除

其他

首先,如果這裏存的是數字,可以使用decrement()和increment()實現遞減和遞增的功能,但這裏ops的是類似於同步的遞減遞增,bound類似於多線程的遞減遞增
其次,還有和append方法,可以直接追加

 

 

List

  list是鏈表,所以涉及到的操作着重於頭和尾的操作,也就是壓棧和出棧

 

bound

ops

頂級接口

BoundListOperations
redisTemplate.boundListOps(Object key)

 

ListOperations
redisTemplate.opsForList()

 

壓棧

rightPush(Object value)

leftPush(Object value)

rightPushAll(Object ... vs)

leftPushAll(Object ... vs)

rightPushIfPresent(Object value)

leftPushIfPresent(Object value)

bound有的方法,ops都有,但這裏多了一套方法就是從一個list裏面出棧同時推棧到另一個list即:
rightPopAndLeftPush(Objectk1,Object k2)
注意,如果這裏的k1和k2是同一個list那麼實現的效果就是同一個list內部值得轉換

出棧

出棧操作類似於壓棧操作將push換做pop(ops方法類似)

set(long index,Object value)在第幾個位置修改,注意這裏不能修改不存在的值(ops方法類似)

其他

rang(long l1,long l2)這是查詢的方法,l1和l2表示第幾個到第幾個,如果寫成0,-1表示查所有(ops方法類似)

 

set 

 

bound

ops

頂級接口

BoundSetOperations
redisTemplate.boundSetOps(Object key)
SetOperations
redisTemplate.opsForSet()

add(Object... vs)


 

members()

 

remove(Object object)(刪除集合裏面的單個對象)

其他

diff(Object key) 當前集合與key集合不同的地方
diffAndStore(Object key1,Object key2)key1合併key2,去除重複項,並刪除key2
distinctRandomMembers(long num)隨機獲取num個集合中的元素,返回值是set集合

zset

 

bound

ops

頂級接口

BoundZSetOperations
redisTemplate.boundZSetOps(Object key);
ZSetOperations
redisTemplate.opsForZSet();

方法說明

zset和set的使用基本相似,不同的是,zset是有序集合,所以在存數據的時候需要標記score值,雖然set的value值不能重複,但是score卻可以重複

 

Hash

  hash類型集合適合用來存對象,但是java中的對象類都必須實現序列化接口,而存進redis中的數據也都是序列化後的數據,一串看不懂的字符串,但是不影響操作

 

bound

ops

頂級接口

BoundHashOperations
redisTemplate.opsForHash(Object key)

 

 

HashOperations
redisTemplate.boundHashOps();

 

put(Object hk,Object hv)

ops方法類似

get(object hk)

ops方法類似

delete()

ops方法類似

其他

這裏面有個設置有效期的方法expire(long var1, TimeUnit var3
) 和expireAt(Date date)

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的學習還要繼續。

能力尚淺,有待進步,如有不足,不吝賜教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章