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

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

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

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

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

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

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

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

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

實(shí)現(xiàn)案例

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

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

Mysql ,Java對(duì)象:


@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對(duì)象:

@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。這個(gè)注解表示對(duì)象是一個(gè)實(shí)體。它將存儲(chǔ)在關(guān)鍵字為 “包路徑+類名+ Idx”的數(shù)據(jù)庫(kù)中。

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

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

 

Mysql,Java示例:

public interface DowntimeRepository extends JpaRepository<Downtime, String> {

}
 

Redis,Java示例:

public interface DowntimeRedisRepository extends RedisDocumentRepository<DowntimeDoc, String> {

}

以上Redis示例的不同之處在于它從RedisDocumentRepository接口擴(kuò)展,這實(shí)現(xiàn)了Spring的標(biāo)準(zhǔn)CRUD接口。

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

接下來(lái)添加一個(gè)方法,通過(guò)cause(原因)查找第一個(gè)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);

}

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

下面是一個(gè)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的例子中,我們只是簡(jiǎn)單地指定了“WHERE”部分的條件。無(wú)需指出需要附加哪些字段,這是因?yàn)樗偸菑闹付ǖ腞edis庫(kù)中提取數(shù)據(jù)。但是,我們不能調(diào)出所有字段,而是通過(guò)“returnFields”參數(shù)指定我們需要哪些字段,還可以指定排序、Limit和Offset。在HQL中并沒有這些功能的。在這個(gè)例子中,還傳遞了一個(gè)Pageable參數(shù),這個(gè)參數(shù)將在數(shù)據(jù)庫(kù)級(jí)別執(zhí)行,使得數(shù)據(jù)庫(kù)不用將所有數(shù)據(jù)拉入應(yīng)用程序。這一點(diǎn)和Hibernate不同,hibernate實(shí)在應(yīng)用程序中進(jìn)行修剪。

另外,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());

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

 

使用Redis OM Spring的一些注意事項(xiàng)

 

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

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

另外,如果在RedisDocumentRepository中進(jìn)行搜索,不會(huì)起作用,因?yàn)榇a中有這樣一個(gè)表達(dá)式:

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

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

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

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

 

總之

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

分享到:
標(biāo)簽:Redis
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定