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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

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

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

「Spring」認(rèn)證安全架構(gòu) ? 來(lái)源:「Spring」認(rèn)證安全架構(gòu) ? 作者:「Spring」認(rèn)證安全 ? 2022-06-28 16:18 ? 次閱讀

原標(biāo)題:Spring認(rèn)證|Spring Data JDBC-如何使用自定義ID生成

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

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

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

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

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

考慮一個(gè)由單個(gè)簡(jiǎn)單的類組成的簡(jiǎn)單聚合:

類小黃人{(lán)

@ID

長(zhǎng)ID;

字符串名稱;

Minion(字符串名稱){

this.name = 名稱;

}

}

進(jìn)一步考慮默認(rèn)CrudRepository。

接口 MinionRepository 擴(kuò)展 CrudRepository {

}

存儲(chǔ)庫(kù)會(huì)自動(dòng)連接到您的代碼中,如下所示:

@自動(dòng)連線

MinionRepository 隨從;

以下工作正常:

Minion before = new Minion("Bob");

assertThat(before.id).isNull();

Minion after = minions.save(before);

assertThat(after.id).isNotNull();

但是下一點(diǎn)點(diǎn):

Minion before = new Minion("Stuart");

before.id = 42L;

minions.save(before);

更新語(yǔ)句,Spring Data JDBC 嘗試執(zhí)行更新,因?yàn)?ID 已經(jīng)設(shè)置。但是,因?yàn)閷?shí)際上是新的,更新語(yǔ)句影響零行 Spring Data JDBC 拋出異常。

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

版本

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

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

此外,對(duì)于許多應(yīng)用程序來(lái)說(shuō),樂觀的最初是很多。

我們把原來(lái)的Minion變成了一個(gè)VersionedMinion:

類 VersionedMinion {

@Id 長(zhǎng) ID;

字符串名稱;

@Version 整數(shù)版本;

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

this.id = id;

this.name = 名稱;

}

}

通過(guò)此更改,以下構(gòu)造有效:

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

assertThat(before.id).isNotNull();

versionedMinions.save(before);

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

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

樣板

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

Minion before = new Minion("Stuart");

before.id = 42L;

模板.插入(之前);

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

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

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

@自動(dòng)連線

JdbcAggregateTemplate 模板;

事件監(jiān)聽器

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

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

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

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

我們使用另一種變體 Minion

類 StringIdMinion {

@ID

字符串標(biāo)識(shí);

字符串名稱;

StringIdMinion(字符串名稱){

this.name = 名稱;

}

}

但是,我們?cè)谂渲弥凶?cè)了一個(gè)驚人的例子:

@豆角,扁豆

BeforeSaveCallback beforeSaveCallback() {

返回(minion,mutableAggregateChange)-> {

如果(minion.id == null){

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

}

返回仆從;

};

}

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

StringIdMinion before = new StringIdMinion("Kevin");

stringions.save(before);

assertThat(before.id).isNotNull();

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

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

持久的

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

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

類 PersistableMinion 實(shí)現(xiàn) Persistable {

@Id 長(zhǎng) ID;

字符串名稱;

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

this.id = id;

this.name = 名稱;

}

@覆蓋

公共長(zhǎng) getId() {

返回標(biāo)識(shí);

}

@覆蓋

公共布爾 isNew() {

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

返回真;

}

}

保存一個(gè)的代碼 PersistableMinion 看起來(lái)是一樣的:

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

persistableMinions.save(before);

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

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

結(jié)論

Spring Data JDBC 提供了大量關(guān)于如何控制聚合 ID 的選項(xiàng)。雖然我在示例中使用了非常嚴(yán)重的邏輯,但基本沒有什么能阻止您實(shí)現(xiàn)您所考慮的任何邏輯,因?yàn)樗鼈兌細(xì)w結(jié)為 Java 代碼。

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

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

    關(guān)注

    0

    文章

    340

    瀏覽量

    14344
  • JDBC
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    13408
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    TPS659xx應(yīng)用程序自定義工具

    電子發(fā)燒友網(wǎng)站提供《TPS659xx應(yīng)用程序自定義工具.pdf》資料免費(fèi)下載
    發(fā)表于 11-06 10:02 ?0次下載
    TPS659xx應(yīng)用程序<b class='flag-5'>自定義</b>工具

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

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

    如何創(chuàng)建TestStand自定義步驟

    在之前的課程中簡(jiǎn)單地介紹過(guò)TestStand自帶的一些步驟類型,如測(cè)試、消息彈窗、賦值、標(biāo)簽等等,這些簡(jiǎn)單的步驟從TestStand的插入選版中就可以添加到序列中。那么在使用中如果碰到需要實(shí)現(xiàn)更加靈活、復(fù)雜的功能,使用自帶的一些步驟類型可能難以滿足,這時(shí)就需要使用到自定義步驟。
    的頭像 發(fā)表于 09-11 14:46 ?1108次閱讀
    如何創(chuàng)建TestStand<b class='flag-5'>自定義</b>步驟

    請(qǐng)問multisim怎么自定義元器件?

    為什么我在multisim中自定義元器件始終出不了想要的波形效果呢?同一個(gè)pspice模型我同學(xué)之前都定義正確了,現(xiàn)在我想再來(lái)試一下結(jié)果一直失敗
    發(fā)表于 09-10 06:16

    EtherCAT運(yùn)動(dòng)控制器PT/PVT實(shí)現(xiàn)用戶自定義軌跡規(guī)劃

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

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

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

    Chrome移動(dòng)版支持自定義菜單欄功能

    在先前版本中,用戶通過(guò)點(diǎn)擊瀏覽器右上角的三個(gè)點(diǎn)按鈕即可調(diào)出包含各類圖標(biāo)與操作的菜單。而此次更新后,Chrome新增了“自定義菜單”選項(xiàng),允許用戶自主控制該區(qū)域的展示內(nèi)容。
    的頭像 發(fā)表于 05-27 15:00 ?818次閱讀

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

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

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

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

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

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

    微軟Dev Home應(yīng)用提供自定義文件管理支持

    據(jù)悉,Microsoft 近期發(fā)布了 0.13 版 Dev Home 應(yīng)用程序,除修復(fù)多項(xiàng) BUG 外,還新增了自定義文件資源管理器功能。該應(yīng)用支持用戶在應(yīng)用內(nèi)創(chuàng)建虛擬機(jī),利用微軟旗下的 Hyper V 技術(shù)生成本地虛擬機(jī)。
    的頭像 發(fā)表于 04-26 11:15 ?466次閱讀

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

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

    鴻蒙ArkUI實(shí)例:【自定義組件】

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

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

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

    RK3568驅(qū)動(dòng)指南|驅(qū)動(dòng)基礎(chǔ)進(jìn)階篇-進(jìn)階5 自定義實(shí)現(xiàn)insmod命令實(shí)驗(yàn)

    RK3568驅(qū)動(dòng)指南|驅(qū)動(dòng)基礎(chǔ)進(jìn)階篇-進(jìn)階5 自定義實(shí)現(xiàn)insmod命令實(shí)驗(yàn)
    的頭像 發(fā)表于 02-20 14:10 ?709次閱讀
    RK3568驅(qū)動(dòng)指南|驅(qū)動(dòng)基礎(chǔ)進(jìn)階篇-進(jìn)階5 <b class='flag-5'>自定義</b>實(shí)現(xiàn)insmod命令實(shí)驗(yàn)