亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

redis可以用作關系數據庫嗎?

如何使用Redis作為關系數據庫

相信大多數人在使用Redis時都把它作為服務的緩存。而在JAVA + Spring中使用Redis有卻可以實現關系數據庫的功能。

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

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

下面是一個Spring應用程序小案例,分別使用MySQL和Redis作為數據庫。在數據庫中存儲的是一個包含內部聯接的關系數據庫對象。

實現案例

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

關系數據庫的實體:

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。這個注解表示對象是一個實體。它將存儲在關鍵字為 “包路徑+類名+ Idx”的數據庫中。

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

接下來,創建一個java庫(repository),用于從數據庫中獲取數據。

 

Mysql,Java示例:

public interface DowntimeRepository extends JpaRepository<Downtime, String> {

}
 

Redis,Java示例:

public interface DowntimeRedisRepository extends RedisDocumentRepository<DowntimeDoc, String> {

}

以上Redis示例的不同之處在于它從RedisDocumentRepository接口擴展,這實現了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);

}

 我們注意到,如果通過抽象來編寫數據庫操作的Java代碼,幾乎沒有什么差異。此外,Redis OM Spring允許我們使用@Query注解自定義查詢語句,實現起來就像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庫中提取數據。但是,我們不能調出所有字段,而是通過“returnFields”參數指定我們需要哪些字段,還可以指定排序、Limit和Offset。在HQL中并沒有這些功能的。在這個例子中,還傳遞了一個Pageable參數,這個參數將在數據庫級別執行,使得數據庫不用將所有數據拉入應用程序。這一點和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());

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

 

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

 

無法使用UUID作為主鍵。可以將UUID作為字符串賦值給指定字段,并將其加入索引。但是在搜索時,你需要轉義空格

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

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

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

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

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

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

 

總之

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

分享到:
標簽:Redis
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定