0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

Spring Data JDBC - 如何使用自定義ID

「Spring」認證安全架構 ? 來源:「Spring」認證安全架構 ? 作者:「Spring」認證安全 ? 2022-06-28 16:18 ? 次閱讀

原標題:Spring認證|Spring Data JDBC-如何使用自定義ID生成

這是關于如何解決使用 Spring Data JDBC 時可能遇到的各種挑戰(zhàn)的系列文章的第一篇。

如果你不了解 Spring Data JDBC,你應該首先閱讀它的介紹和文章,它解釋了 Spring Data JDBC 上下文中的相關性。相信我,這很重要。

文章基于我在 2021 年春季一期上這篇文章的部分演講。

使用 ID - 特別是當您想要控制實體的 ID 并且不會選擇什么數(shù)據(jù)庫時,您的選擇是什么。

假設情況下,類型數(shù)據(jù)列JDBC假設的ID通過生成SERIAL或AUTOINCREMENT得到。 ,聚合根執(zhí)行插入操作。數(shù)據(jù)庫生成一個ID,這個ID由Spring Data JDBC在聚合根中設置。

考慮一個由單個簡單的類組成的簡單聚合:

類小黃人{

@ID

長ID;

字符串名稱;

Minion(字符串名稱){

this.name = 名稱;

}

}

進一步考慮默認CrudRepository。

接口 MinionRepository 擴展 CrudRepository {

}

存儲庫會自動連接到您的代碼中,如下所示:

@自動連線

MinionRepository 隨從;

以下工作正常:

Minion before = new Minion("Bob");

assertThat(before.id).isNull();

Minion after = minions.save(before);

assertThat(after.id).isNotNull();

但是下一點點:

Minion before = new Minion("Stuart");

before.id = 42L;

minions.save(before);

更新語句,Spring Data JDBC 嘗試執(zhí)行更新,因為 ID 已經(jīng)設置。但是,因為實際上是新的,更新語句影響零行 Spring Data JDBC 拋出異常。

有幾種方法可以解決這個問題。我已經(jīng)找到了你不同的解決方法,并且已經(jīng)找到了我認為最簡單的方法,因此可以找到適合的方法,你就可以停止閱讀。之后回來閱讀其他選項并提高您的 Spring Data 技能。

版本

將版本屬性添加到您的聚合屬性?!鞍姹緦傩浴笔侵赣聾Version。此類的主要目的是可以樂觀鎖定。但是,作為屬性,Spring Data JDBC 使用版本屬性來確定聚合根是否是新的。 只要版本是null 或0 原始類型,聚合就被認為是新的,即使id設置了。

使用這種方法,您必須更改實體和(當然)系統(tǒng),但別無其他。

此外,對于許多應用程序來說,樂觀的最初是很多。

我們把原來的Minion變成了一個VersionedMinion:

類 VersionedMinion {

@Id 長 ID;

字符串名稱;

@Version 整數(shù)版本;

VersionedMinion(長ID,字符串名稱){

this.id = id;

this.name = 名稱;

}

}

通過此更改,以下構造有效:

VersionedMinion before = new VersionedMinion(23L, "Bob");

assertThat(before.id).isNotNull();

versionedMinions.save(before);

VersionedMinion 重新加載 = versionedMinions.findById(before.id).get();

assertThat(reloaded.name).isEqualTo("Bob");

樣板

一種讓您的遺贈附帶 ID 的方法是自己另外插入物。您可以通過注入 JdbcAggregateTemplate 并調(diào)用 JdbcAggregateTemplate.insert(T)。這JdbAggregateTemplate是存儲庫下面的底層,因此您使用存儲庫用于插入的相同代碼,但您決定何時使用插入:

Minion before = new Minion("Stuart");

before.id = 42L;

模板.插入(之前);

Minion reloaded = minions.findById(42L).get();

assertThat(reloaded.name).isEqualTo("Stuart");

請注意,我們不使用存儲庫農(nóng)場使用模板,其中注入了以下內(nèi)容:

@自動連線

JdbcAggregateTemplate 模板;

事件監(jiān)聽器

模板方法非常適用于您已經(jīng)知道 ID 的情況 - 例如,當您從另一個系統(tǒng)導入數(shù)據(jù)并且您想要重用該系統(tǒng)的 ID 時。

如果您不知道 ID 并且不想在您的業(yè)務代碼中包含任何 ID 相關的內(nèi)容,那么使用 ID 可能是更好的選擇。

我們的目的正確的目的是在某些生命周期事件期間被調(diào)用的豆子。它返回修改潛在的聚合根,因此它也適用于不形成實體類。

在目標中,我們確定有問題的聚合根是否需要新 ID。 如果是這樣,我們將使用我們選擇的算法生成它。

我們使用另一種變體 Minion

類 StringIdMinion {

@ID

字符串標識;

字符串名稱;

StringIdMinion(字符串名稱){

this.name = 名稱;

}

}

但是,我們在配置中注冊了一個驚人的例子:

@豆角,扁豆

BeforeSaveCallback beforeSaveCallback() {

返回(minion,mutableAggregateChange)-> {

如果(minion.id == null){

minion.id = UUID.randomUUID().toString();

}

返回仆從;

};

}

保存實體的代碼現(xiàn)在看起來就像是由數(shù)據(jù)庫生成的:

StringIdMinion before = new StringIdMinion("Kevin");

stringions.save(before);

assertThat(before.id).isNotNull();

StringIdMinion reloaded = stringions.findById(before.id).get();

assertThat(reloaded.name).isEqualTo("Kevin");

持久的

一個選項是讓化根控制是否應該更新或插入。你可以實現(xiàn)持久化的方法(尤其是實現(xiàn)是新的)來實現(xiàn)這一點。您也想使用聚合根進行更新時,這會抓住。在這種情況下,您需要提出更靈活的策略。

我們需要 Minion 再次調(diào)整我們的:

類 PersistableMinion 實現(xiàn) Persistable {

@Id 長 ID;

字符串名稱;

PersistableMinion(長ID,字符串名稱){

this.id = id;

this.name = 名稱;

}

@覆蓋

公共長 getId() {

返回標識;

}

@覆蓋

公共布爾 isNew() {

// 這個實現(xiàn)肯定不適合生產(chǎn)使用

返回真;

}

}

保存一個的代碼 PersistableMinion 看起來是一樣的:

PersistableMinion before = new PersistableMinion(23L, "Dave");

persistableMinions.save(before);

PersistableMinion 重新加載 = persistableMinions.findById(before.id).get();

assertThat(reloaded.name).isEqualTo("Dave");

結論

Spring Data JDBC 提供了大量關于如何控制聚合 ID 的選項。雖然我在示例中使用了非常嚴重的邏輯,但基本沒有什么能阻止您實現(xiàn)您所考慮的任何邏輯,因為它們都歸結為 Java 代碼。

完整的示例代碼可在Spring中國教育管理中心(Spring認證)數(shù)據(jù)示例庫訪問!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • spring
    +關注

    關注

    0

    文章

    335

    瀏覽量

    14259
  • JDBC
    +關注

    關注

    0

    文章

    25

    瀏覽量

    13368
收藏 人收藏

    評論

    相關推薦

    創(chuàng)建自定義的基于閃存的引導加載程序(BSL)

    電子發(fā)燒友網(wǎng)站提供《創(chuàng)建自定義的基于閃存的引導加載程序(BSL).pdf》資料免費下載
    發(fā)表于 09-19 10:50 ?0次下載
    創(chuàng)建<b class='flag-5'>自定義</b>的基于閃存的引導加載程序(BSL)

    EtherCAT運動控制器PT/PVT實現(xiàn)用戶自定義軌跡規(guī)劃

    EtherCAT運動控制器PT/PVT實現(xiàn)用戶自定義軌跡規(guī)劃。
    的頭像 發(fā)表于 08-15 11:49 ?286次閱讀
    EtherCAT運動控制器PT/PVT實現(xiàn)用戶<b class='flag-5'>自定義</b>軌跡規(guī)劃

    NVIDIA NeMo加速并簡化自定義模型開發(fā)

    如果企業(yè)希望充分發(fā)揮出 AI 的力量,就需要根據(jù)其行業(yè)需求量身定制的自定義模型。
    的頭像 發(fā)表于 07-26 11:17 ?576次閱讀
    NVIDIA NeMo加速并簡化<b class='flag-5'>自定義</b>模型開發(fā)

    HarmonyOS開發(fā)案例:【 自定義彈窗】

    基于ArkTS的聲明式開發(fā)范式實現(xiàn)了三種不同的彈窗,第一種直接使用公共組件,后兩種使用CustomDialogController實現(xiàn)自定義彈窗
    的頭像 發(fā)表于 05-16 18:18 ?1060次閱讀
    HarmonyOS開發(fā)案例:【 <b class='flag-5'>自定義</b>彈窗】

    TSMaster 自定義 LIN 調(diào)度表編程指導

    LIN(LocalInterconnectNetwork)協(xié)議調(diào)度表是用于LIN總線通信中的消息調(diào)度的一種機制,我們收到越來越多來自不同用戶希望能夠通過接口實現(xiàn)自定義LIN調(diào)度表的需求。所以在
    的頭像 發(fā)表于 05-11 08:21 ?424次閱讀
    TSMaster <b class='flag-5'>自定義</b> LIN 調(diào)度表編程指導

    HarmonyOS開發(fā)案例:【UIAbility和自定義組件生命周期】

    本文檔主要描述了應用運行過程中UIAbility和自定義組件的生命周期。對于UIAbility,描述了Create、Foreground、Background、Destroy四種生命周期。對于頁面
    的頭像 發(fā)表于 05-10 15:31 ?902次閱讀
    HarmonyOS開發(fā)案例:【UIAbility和<b class='flag-5'>自定義</b>組件生命周期】

    HarmonyOS開發(fā)實例:【自定義Emitter】

    使用[Emitter]實現(xiàn)事件的訂閱和發(fā)布,使用[自定義彈窗]設置廣告信息。
    的頭像 發(fā)表于 04-14 11:37 ?880次閱讀
    HarmonyOS開發(fā)實例:【<b class='flag-5'>自定義</b>Emitter】

    鴻蒙ArkUI實例:【自定義組件】

    組件是 OpenHarmony 頁面最小顯示單元,一個頁面可由多個組件組合而成,也可只由一個組件組合而成,這些組件可以是ArkUI開發(fā)框架自帶系統(tǒng)組件,比如?`Text`?、?`Button`?等,也可以是自定義組件,本節(jié)筆者簡單介紹一下自定義組件的語法規(guī)范。
    的頭像 發(fā)表于 04-08 10:17 ?484次閱讀

    pSoC63的sflash_user_data能用作用戶自定義的flash嗎?

    給第一行寫了自定義的數(shù)據(jù),我發(fā)現(xiàn)可以寫入。 程序運行也沒發(fā)現(xiàn)啥問題。 我想請教一下這部分真的不能用作用戶自定義的flash嗎?我只想用1行,512字節(jié)寫點數(shù)據(jù)。 是否可以?謝謝!
    發(fā)表于 02-21 07:00

    基于YOLOv8實現(xiàn)自定義姿態(tài)評估模型訓練

    Hello大家好,今天給大家分享一下如何基于YOLOv8姿態(tài)評估模型,實現(xiàn)在自定義數(shù)據(jù)集上,完成自定義姿態(tài)評估模型的訓練與推理。
    的頭像 發(fā)表于 12-25 11:29 ?2418次閱讀
    基于YOLOv8實現(xiàn)<b class='flag-5'>自定義</b>姿態(tài)評估模型訓練

    博途用戶自定義庫的使用

    博途官方提供了很多庫,比如:基本函數(shù)庫、通信庫、安全庫、驅(qū)動庫等等,用戶可以使用庫中的函數(shù)/函數(shù)塊來完成具體的控制任務。除了官方的庫,我們也可以創(chuàng)建自己的庫(用戶自定義庫)。比如,把項目
    的頭像 發(fā)表于 12-25 10:08 ?664次閱讀
    博途用戶<b class='flag-5'>自定義</b>庫的使用

    如何在Matlab中自定義Message

    自定義Message 當我們的 message 消息比較復雜時,通常要用到自定義的 message 消息,MATLAB 2020b以上的版本自帶了ROS Toolbox Interface
    的頭像 發(fā)表于 11-15 18:12 ?1037次閱讀
    如何在Matlab中<b class='flag-5'>自定義</b>Message

    Android端自定義鈴聲 MobPush對安卓端自定義鈴聲的教程

    如何為APP推送設置獨特的通知鈴聲呢?本次帶來的是MobPush對安卓端自定義鈴聲的教程,快來看看吧~
    的頭像 發(fā)表于 10-21 15:34 ?1020次閱讀
    Android端<b class='flag-5'>自定義</b>鈴聲 MobPush對安卓端<b class='flag-5'>自定義</b>鈴聲的教程

    單片機自定義協(xié)議FIFO高效發(fā)送數(shù)據(jù)方法

    單片機自定義協(xié)議FIFO高效發(fā)送數(shù)據(jù)方法
    的頭像 發(fā)表于 09-28 17:32 ?666次閱讀
    單片機<b class='flag-5'>自定義</b>協(xié)議FIFO高效發(fā)送數(shù)據(jù)方法

    OpenHarmony自定義組件介紹

    一、創(chuàng)建自定義組件 在ArkUI中,UI顯示的內(nèi)容均為組件,由框架直接提供的稱為系統(tǒng)組件,由開發(fā)者定義的稱為自定義組件。在進行 UI 界面開發(fā)時,通常不是簡單的將系統(tǒng)組件進行組合使用,而是需要考慮
    發(fā)表于 09-25 15:36