《SpringBoot》中使用的Redis

Redis入門

Linux中安裝Redisjava

redis的說明

Redis 是一個開源的,內存中的數據結構存儲系統它能夠用做數據庫、緩存和消息中間件。 它支持多種類型的數據結構redis

1. Redis經常使用命令

string類型:

命令 說明 案例
set 添加key-value set username admin
get 根據key獲取數據 get username
exists 判斷key是否存在 exists name(返回1存在 0不存在)
del 刪除redis中的key del key
Keys 用於查詢符合條件的key keys 查詢redis中所有的key,keys n?me 使用佔位符獲取數據 keys nam 獲取nam開頭的數據

Hash類型

命令 說明 案例
hset 爲對象添加數據 hset key field value
hget 獲取對象的屬性值 hget key field
hexists 判斷對象的屬性是否存在 HEXISTS key field1表示存在 0表示不存在
hdel 刪除hash中的屬性 hdel user field

List類型

說明

Redis中的List集合是雙端循環列表,分別能夠從左右兩個方向插入數據
List集合能夠當作隊列使用,也能夠當作棧使用spring

隊列:存入數據的方向和獲取數據的方向相反

棧:存入數據的方向和獲取數據的方向相同

命令 說明 案例
lpush 從隊列的左邊入隊一個或多個元素 LPUSH key value
rpush 從隊列的右邊入隊一個或多個元素 RPUSH key value
lpop 從隊列的左端出隊一個元素 LPOP key
rpop 從隊列的右端出隊一個元素 RPOP key

Redis事務命令

說明

說明:redis中操做能夠添加事務的支持.一項任務能夠由多個redis命令完成,若是有一個命令失敗致使入庫失敗時.須要實現事務回滾.數據庫

命令 說明 案例
multi 標記一個事務開始 127.0.0.1:6379> MULTI
exec 執行全部multi以後發的命令 127.0.0.1:6379> EXEC
discard 丟棄全部multi以後發的命令

Redis入門

導入jar包

<!--spring整合redis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
    </dependency>

客戶端操做String類型

前提

建立一個Java類測試類json

配置redis服務

主要目的測試程序遠程操做Redis是否有效
1.redis須要關閉IP綁定模式
2.redis關閉保護模式
3.redis最好開啓後端運行

redis入門案例(1)

總體結構

public void test01() throws InterruptedException {
    //1.測試連接
    Jedis jedis = new Jedis("192.168.126.129",6379);
    jedis.set("a", "動態獲取redis中的數據");
    System.out.println(jedis.get("a"));

    //2.測試數據是否存在
    if(jedis.exists("a")){
        jedis.set("a", "修改數據");
    }else{
        jedis.set("a", "新增數據");
    }

    //3.刪除redis
    jedis.del("a");

    //4.清空全部的數據
    jedis.flushDB();
    jedis.flushAll();

    //5.爲數據添加超時時間
    jedis.set("b", "設定超時時間");
    jedis.expire("b", 10);
    Thread.sleep(2000);
    System.out.println(jedis.ttl("b"));
}

1 . 測試連接

Jedis jedis = new Jedis("192.168.126.129",6379);
jedis.set("a", "動態獲取redis中的數據");
System.out.println(jedis.get("a"));
1 - Jedis是在springboot中使用redis的時候引入到包,他springboot中表明redis new一個Jedis的時候參數的方式來引入redis所在的ip地址和端口。
2 - set是 添加key和value
3 - get是 獲取根據key獲取value

2 . 測試數據是否存在

if(jedis.exists("a")){
        jedis.set("a", "修改數據");
    }else{
        jedis.set("a", "新增數據");
    }
exists 是判斷數據是否存在

判斷 a 是否存在 若是存在的話a的value值改爲<修改數據>,若是不存在的話a的value是<新增數據>segmentfault

3 . 刪除redis

jedis.del("a");
del 表示刪除

刪除key 是 a 的數據後端

4 . 清空全部的數據

jedis.flushDB();
jedis.flushAll();
flushDB 清空單個數據庫
flushAll 清空所有數據庫

此方法很危險刪除你的數據因此不建議使用緩存

5 . 爲數據添加超時時間

jedis.set("b", "設定超時時間");
jedis.expire("b", 10);
Thread.sleep(2000);
System.out.println(jedis.ttl("b"));

redis入門案例(2)

原子性

什麼是原子性?

一個事務是一個不可分割的最小工做單位,要麼都成功要麼都失敗。springboot

原子操做是指你的一個業務邏輯必須是不可拆分的.好比你給別人轉錢,你的帳號扣錢,別人的帳號
增長錢,這個業務邏輯就是原子性的,這個操做就是原子操做,要麼都成功要麼都失敗。數據結構

Redis全部單個命令的執行都是原子性的。

總體結構

public void test02(){
    Jedis jedis = new Jedis("192.168.126.129", 6379);
    jedis.set("c", "測試redis");
    //需求1: 若是數據不存在時,纔會爲數據賦值.
    jedis.setnx("d","測試setnx方法");
    System.out.println(jedis.get("d"));

    //需求2: 須要爲數據添加超時時間,同時知足原子性的要求
    //爲數據添加超時時間
    jedis.setex("s", 20, "爲數據添加超時111");
    System.out.println("獲取超時時間:"+jedis.ttl("s"));
}

需求1

若是數據不存在時,纔會爲數據賦值.

jedis.setnx("d","測試setnx方法");
     System.out.println(jedis.get("d"));
setnx - 在指定的 key 不存在時,爲 key 設置指定的值

若是d不存在的話才指定值

需求2

須要爲數據添加超時時間,同時知足原子性的要求

jedis.setex("s", 20, "爲數據添加超時111");
System.out.println("獲取超時時間:"+jedis.ttl("s"));

setex - 指定的key設置值及其過時時間。若是key已經存在, setex 命令將會替換舊的值

需求3

若是數據存在才修改,而且爲數據添加超時時間,知足原子性要求

SetParams:
    XX: 數據存在時賦值.
    NX: 數據不存在時賦值
    EX: 添加超時時間單位秒
    PX: 添加超時時間單位毫秒

使用Redis中的setparams

public void test03(){
    Jedis jedis = new Jedis("192.168.126.129", 6379);
    jedis.flushAll();
    
    SetParams setParams = new SetParams();
    setParams.xx().ex(20);
    jedis.set("a", "測試方法",setParams);
    System.out.println(jedis.get("a"));
}
flushAll - 清空所有數據庫(Redis)
xx().ex(20) - 分別爲 xx() 數據存在時,ex(20) 超時20毫秒

關於List集合說明

關於隊列應用場景

秒殺場景: 立刻過年了, 店鋪週年店慶 1部蘋果12proMax 12000 1元秒殺? 提早預付活動費 10塊… 若是秒殺不成功 則7日內退還?
image.png

入門案例測試

隊列:存入數據的方向和獲取數據的方向相反

@Test
public void testList(){
    Jedis jedis = new Jedis("192.168.126.129",6379);
    jedis.lpush("list", "1","2","3");
    System.out.println(jedis.rpop("list")); //隊列
}
lpush - 從列隊的左邊入隊 一個或者多個元素
rpop - 從隊列的右端出隊一個元素

SpringBoot整合Redis

1 . 編輯properties配置文件

redis是公共的,建議配置放到公共的目錄中

image.png
建立一個properties配置文件裏面寫redis的節點

2 . 編輯配置類

須要建立redis的一個配置類,配置類也放到公共的目錄中

@Configuration  //表示一個配置類  通常會與@Bean的註解聯用
@PropertySource("classpath:/redis.properties") //導入配置文件
public class RedisConfig {

@Value("${redis.host}")
private String host;
@Value("${redis.port}")
private Integer port;

@Bean   //將方法的返回值結果,交給spring容器進行管理.
public Jedis jedis(){

    return new Jedis(host, port);
    }
}
@Configuration - 當前的類是配置類
@PropertySource - 導入配置文件
@bean - 把結果交給spring管理

3 . 測試redis的案例

在test中測試咱們的配置

image.png

@SpringBootTest //目的:動態獲取spring容器中的數據
public class TestRedis {
    @Autowired
 private Jedis jedis;
    @Test
 public void testRedis(){
        jedis.set("jedis", "spring測試");
        System.out.println(jedis.get("jedis"));
    }
}

image.png
運行時出現這樣表示成功

JSON轉化工具API

測試1

@Test
    public void test01() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        //將對象轉化爲JSON 調用的是對象的get方法獲取屬性/屬性的值
        Sysprod sysprod = new Sysprod();
        sysprod.setId(1000).setTitle("對象與json轉化").setProd_name("prodname").setPrice(1000).setProd_id(1000);
        String json = objectMapper.writeValueAsString(sysprod);
        System.out.println(json);
        //將JSON串轉化爲對象 調用的是對象的set方法爲對象屬性賦值
        Sysprod sysprod1 = objectMapper.readValue(json, Sysprod.class);
        System.out.println(sysprod1.getTitle());
    }
objectMapper - 將java對象與json格式相互轉化的類
writeValuesAsString - 方法就能夠把對角轉化成json字符串(get方法)
readValue - 方法就能夠把對角轉化成json字符串(set方法)

把數據的get和set方式都要轉換json類型,獲取和賦值都轉成json

sysprod 是 pojo對象

測試2

@Test
public void test02() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    //將對象轉化爲JSON  調用的是對象的get方法獲取屬性/屬性的值
    ItemDesc itemDesc = new ItemDesc();
    itemDesc.setItemId(1000L).setItemDesc("對象與json轉化").setCreated(new Date()).setUpdated(new Date());
    ItemDesc itemDesc2 = new ItemDesc();
    itemDesc2.setItemId(2000L).setItemDesc("對象與json轉化2").setCreated(new Date()).setUpdated(new Date());

    List<ItemDesc> list2 = new ArrayList<>();
    list2.add(itemDesc);
    list2.add(itemDesc2);

    String json = objectMapper.writeValueAsString(list2);
    System.out.println(json);

    //將JSON串轉化爲對象 調用的是對象的set方法爲對象屬性賦值
    List list3 = objectMapper.readValue(json,list2.getClass());
    System.out.println(list3);
    }
}

若是有兩個pojo對象那麼把兩個pojo對象包裝給list集合

封裝工具API

該工具類,主要的功能實現對象與JSON串的互相轉化.

  • 1.對象轉化爲JSON
  • 2.JSON轉化爲對象
public class ObjectMapperUtil {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    //1.對象轉化爲JSON
    public static String toJSON(Object object){
        try {
            return MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    //2.JSON轉化爲對象 要求用戶傳遞什麼類型就返回什麼對象??
    public static <T> T toObj(String json,Class<T> target){

        try {
            return MAPPER.readValue(json, target);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
            }
        }
    }
第一步:new 一個 objectMapper類,(靜態的和常量)修飾符
第二步:對象轉化爲JSON(返回string類型),把異常不要拋出去並且調用
第三步:JSON轉化對象 要求用戶傳什麼類型就返回給對象

工具類的功能:

咱們發出的數據轉化成json格式到客戶端,用戶傳來的json數據到服務端就轉化對象

利用緩存實現查詢

說明:若是頁面的數據每次都數據庫裏查詢的話這樣的效率並不高,可使用redis緩存來提高效率

流程:

  • 1.用戶第一次查詢先查詢緩存
  • 2.緩存中沒有數據(這就是第一次查詢),查詢數據庫. 將數據庫記錄保存到緩存中便可.
  • 3.緩存中有記錄. 直接經過緩存獲取數據以後返回便可.
相關文章
相關標籤/搜索