自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何使用Redis作為關(guān)系數(shù)據(jù)庫

數(shù)據(jù)庫
下面是一個Spring應用程序小案例,分別使用Mysql和Redis作為數(shù)據(jù)庫。在數(shù)據(jù)庫中存儲的是一個包含內(nèi)部聯(lián)接的關(guān)系數(shù)據(jù)庫對象。

Redis可以用作關(guān)系數(shù)據(jù)庫嗎?

相信大多數(shù)人在使用Redis時都把它作為服務的緩存。而在Java + Spring中使用Redis有卻可以實現(xiàn)關(guān)系數(shù)據(jù)庫的功能。

要在Redis中實現(xiàn)這一點,首先,我們需要在Redis中安裝插件,包括:RedisJSON和RediSearch。其中RedisJSON允許我們以JSON格式存儲對象,RediSearch允許我們通過對象的任何字段進行搜索,甚至是嵌套字段。

為了在java端使用Redis,可以選擇Spring Data JPA,使用優(yōu)秀的Redis OM Spring庫(https://github.com/redis/redis-om-spring),它允許我們使用數(shù)據(jù)庫的抽象。Redis OM Spring擁有Spring和Jedis使用數(shù)據(jù)庫所需的所有依賴。

下面是一個Spring應用程序小案例,分別使用Mysql和Redis作為數(shù)據(jù)庫。在數(shù)據(jù)庫中存儲的是一個包含內(nèi)部聯(lián)接的關(guān)系數(shù)據(jù)庫對象。

實現(xiàn)案例

我們假設(shè)需要將一個名為"downtime"(停機記錄)的實體寫入數(shù)據(jù)庫。在這個實體中,添加了其他對象,如"place"(位置)、"reason"(原因)等。

關(guān)系數(shù)據(jù)庫的實體:

Mysql ,Java對象:


@Entity
@Table(schema = "test", name = "downtime")
public class Downtime {


    @Id
    private String id;
    private LocalDateTime beginDate;
    private LocalDateTime endDate;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "area")
    private Place area;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "cause")
    private Cause cause;
    ...

Redis,Java對象:

@Document
public class DowntimeDoc {
    @Id
    @Indexed
    private String id;
    @Indexed
    private LocalDateTime beginDate;
    private LocalDateTime endDate;
    @Indexed
    private PlaceDoc area;
    @Indexed
    private CauseDoc cause;
    ....

在上面的例子中,我們使用@Entity代替@Document。這個注解表示對象是一個實體。它將存儲在關(guān)鍵字為 “包路徑+類名+ Idx”的數(shù)據(jù)庫中。

添加@Indexed注解的字段將被建立索引以供搜索。如果不指定此注釋,則這個字段將只是保存在數(shù)據(jù)庫中,而搜索該字段將返回空結(jié)果。所以,我們可以根據(jù)需要添加此注釋。數(shù)據(jù)庫中已存在的數(shù)據(jù)將被異步執(zhí)行建立索引。

接下來,創(chuàng)建一個java庫(repository),用于從數(shù)據(jù)庫中獲取數(shù)據(jù)。

Mysql,Java示例:

public interface DowntimeRepository extends JpaRepository<Downtime, String> {

}

Redis,Java示例:

public interface DowntimeRedisRepository extends RedisDocumentRepository<DowntimeDoc, String> {

}

以上Redis示例的不同之處在于它從RedisDocumentRepository接口擴展,這實現(xiàn)了Spring的標準CRUD接口。

Let's add a method to find the first downtime for the reason we specified.

接下來添加一個方法,通過cause(原因)查找第一個downtime。

Mysql,Java示例:

public interface DowntimeRepository extends JpaRepository<Downtime, String> {

    Downtime findFirstByCauseIdOrderByBeginDate(String causeId);
}

Redis,Java示例:

public interface DowntimeRedisRepository extends RedisDocumentRepository<DowntimeDoc, String> {

    DowntimeDoc findTopByCause_IdOrderByBeginDateAsc(String causeId);

}

 我們注意到,如果通過抽象來編寫數(shù)據(jù)庫操作的Java代碼,幾乎沒有什么差異。此外,Redis OM Spring允許我們使用@Query注解自定義查詢語句,實現(xiàn)起來就像Spring Data JPA中的那樣。

下面是一個HQL查詢的示例:

Mysql,Java示例:

@Query("SELECT d FROM Downtime d" +
        " JOIN FETCH d.area " +
        " JOIN FETCH d.cause" +
        " JOIN FETCH d.fixer" +
        " JOIN FETCH d.area.level " +
        " WHERE d.area IN ?1 AND (d.beginDate BETWEEN ?2 AND ?3 OR d.cause IN ?4) ")
List<Downtime> findAllByParams(List<Place> workPlace, LocalDateTime start, LocalDateTime end, List<Cause> causes);

Redis,Java示例: 

@Query("(@area_id:{$areas} ) & (@beginDate:[$start $end] | @cause_id:{$causes})")
Page<DowntimeDoc> findByParams(@Param("areas") List<String> areas,
                               @Param("start") long start,
                               @Param("end") long end,
                               @Param("causes") List<String> causes, Pageable pageable);

在Redis的例子中,我們只是簡單地指定了“WHERE”部分的條件。無需指出需要附加哪些字段,這是因為它總是從指定的Redis庫中提取數(shù)據(jù)。但是,我們不能調(diào)出所有字段,而是通過“returnFields”參數(shù)指定我們需要哪些字段,還可以指定排序、Limit和Offset。在HQL中并沒有這些功能的。在這個例子中,還傳遞了一個Pageable參數(shù),這個參數(shù)將在數(shù)據(jù)庫級別執(zhí)行,使得數(shù)據(jù)庫不用將所有數(shù)據(jù)拉入應用程序。這一點和Hibernate不同,hibernate實在應用程序中進行修剪。

另外,Redis OM Spring 類似于Stream API,允許我們使用EntityStream編寫查詢。

下面是使用EntityStream查詢的示例。

…
entityStream
        .of(DowntimeDoc.class)
        .filter(DowntimeDoc$.AREA_ID.in(filter.getWorkPlace().toArray(String[]::new)))
        .filter(between + " | " + causes)
        .map(mapper::toEntity)
        .collect(Collectors.toList());

在這個例子中,我使用了元模型的過濾器,將字符串參數(shù)傳遞給第二個過濾器,以表示兩個過濾選項都有效。EntityStream接受一組中間操作,并在調(diào)用時執(zhí)行這一組操作。

使用Redis OM Spring的一些注意事項

無法使用UUID作為主鍵??梢詫UID作為字符串賦值給指定字段,并將其加入索引。但是在搜索時,你需要轉(zhuǎn)義空格

{2e5af82m\-02af\-553b\-7961\-168878aa521е}

另外,如果在RedisDocumentRepository中進行搜索,不會起作用,因為代碼中有這樣一個表達式:

String regex = "(\\$" + key + ")(\\W+|\\*|\\+)(.*)";

因此,為了通過這些字段進行搜索,您必須直接在RediSearch中編寫查詢。

在通過RedisDocumentRepository方法搜索時,如果希望返回一個集合,那么必須傳遞一個Pageable,指定行的大小或在@Query中指定大小;否則,最多返回10條記錄。

方法FT.SEARCH (@Query)只支持一個排序。這可以通過編寫FT.AGGREGATE (@Aggregation)查詢來解決。

總之

以上是使用Redis存儲、搜索一個帶有嵌套對象的。通過Repository抽象來處理數(shù)據(jù),和Spring Data JPA沒有太大區(qū)別,特別是使用一些簡單的函數(shù),如:save、delete、findAllBy,以及通過方法名稱進行查詢等等。

責任編輯:趙寧寧 來源: andflow
相關(guān)推薦

2011-10-11 17:07:12

數(shù)據(jù)庫Internet文件數(shù)據(jù)庫

2023-01-06 08:00:00

關(guān)系數(shù)據(jù)庫數(shù)據(jù)庫機器學習

2024-06-26 19:14:53

2023-10-16 13:26:00

RDBMS關(guān)系數(shù)據(jù)庫

2009-07-10 09:28:41

NoSQL關(guān)系數(shù)據(jù)庫

2018-10-15 13:57:38

Hadoop數(shù)據(jù)庫MySQL

2020-03-14 16:37:09

數(shù)據(jù)庫IT技術(shù)

2018-04-12 12:45:02

數(shù)據(jù)庫MySQL構(gòu)建架構(gòu)

2010-09-15 14:09:01

GraphDataba

2011-07-18 09:54:47

云計算分片關(guān)系數(shù)據(jù)庫關(guān)系數(shù)據(jù)庫

2023-05-22 11:20:27

數(shù)據(jù)庫MySQL關(guān)系數(shù)據(jù)

2009-03-26 11:10:13

關(guān)系數(shù)據(jù)庫關(guān)系型數(shù)據(jù)庫數(shù)據(jù)庫

2011-03-15 14:54:08

NoSQL

2011-08-15 10:02:02

LEIDomino附件關(guān)系數(shù)據(jù)庫

2009-10-29 11:01:52

Amazon RDSMySQL關(guān)系數(shù)據(jù)庫

2011-09-27 13:41:09

數(shù)據(jù)庫

2009-03-03 09:54:41

云計算關(guān)系數(shù)據(jù)庫數(shù)據(jù)庫

2020-03-04 10:05:33

關(guān)系數(shù)據(jù)庫居住權(quán)

2009-08-25 09:09:33

關(guān)系數(shù)據(jù)庫數(shù)據(jù)庫革命RDBMS

2017-06-28 08:14:57

數(shù)據(jù)庫區(qū)塊鏈比特幣
點贊
收藏

51CTO技術(shù)棧公眾號