0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

「Spring」认证安全架构 来源:「Spring」认证安全架构 作者:「Spring」认证安全 2022-06-28 16:18 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

原标题:Spring认证|Spring Data JDBC-如何使用自定义ID生成

这是关于如何解决使用 Spring Data JDBC 时可能遇到的各种挑战的系列文章的第一篇。

如果你不了解 Spring Data JDBC,你应该首先阅读它的介绍和文章,它解释了 Spring Data JDBC 上下文中的相关性。相信我,这很重要。

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

使用 ID - 特别是当您想要控制实体的 ID 并且不会选择什么数据库时,您的选择是什么。

假设情况下,类型数据列JDBC假设的ID通过生成SERIAL或AUTOINCREMENT得到。 ,聚合根执行插入操作。数据库生成一个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 尝试执行更新,因为 ID 已经设置。但是,因为实际上是新的,更新语句影响零行 Spring Data JDBC 抛出异常。

有几种方法可以解决这个问题。我已经找到了你不同的解决方法,并且已经找到了我认为最简单的方法,因此可以找到适合的方法,你就可以停止阅读。之后回来阅读其他选项并提高您的 Spring Data 技能。

版本

将版本属性添加到您的聚合属性。“版本属性”是指用@Version。此类的主要目的是可以乐观锁定。但是,作为属性,Spring Data JDBC 使用版本属性来确定聚合根是否是新的。 只要版本是null 或0 原始类型,聚合就被认为是新的,即使id设置了。

使用这种方法,您必须更改实体和(当然)系统,但别无其他。

此外,对于许多应用程序来说,乐观的最初是很多。

我们把原来的Minion变成了一个VersionedMinion:

类 VersionedMinion {

@Id 长 ID;

字符串名称;

@Version 整数版本;

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 并调用 JdbcAggregateTemplate.insert(T)。这JdbAggregateTemplate是存储库下面的底层,因此您使用存储库用于插入的相同代码,但您决定何时使用插入:

Minion before = new Minion("Stuart");

before.id = 42L;

模板.插入(之前);

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

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

请注意,我们不使用存储库农场使用模板,其中注入了以下内容:

@自动连线

JdbcAggregateTemplate 模板;

事件监听器

模板方法非常适用于您已经知道 ID 的情况 - 例如,当您从另一个系统导入数据并且您想要重用该系统的 ID 时。

如果您不知道 ID 并且不想在您的业务代码中包含任何 ID 相关的内容,那么使用 ID 可能是更好的选择。

我们的目的正确的目的是在某些生命周期事件期间被调用的豆子。它返回修改潜在的聚合根,因此它也适用于不形成实体类。

在目标中,我们确定有问题的聚合根是否需要新 ID。 如果是这样,我们将使用我们选择的算法生成它。

我们使用另一种变体 Minion

类 StringIdMinion {

@ID

字符串标识;

字符串名称;

StringIdMinion(字符串名称){

this.name = 名称;

}

}

但是,我们在配置中注册了一个惊人的例子:

@豆角,扁豆

BeforeSaveCallback beforeSaveCallback() {

返回(minion,mutableAggregateChange)-> {

如果(minion.id == null){

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

}

返回仆从;

};

}

保存实体的代码现在看起来就像是由数据库生成的:

StringIdMinion before = new StringIdMinion("Kevin");

stringions.save(before);

assertThat(before.id).isNotNull();

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

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

持久的

一个选项是让化根控制是否应该更新或插入。你可以实现持久化的方法(尤其是实现是新的)来实现这一点。您也想使用聚合根进行更新时,这会抓住。在这种情况下,您需要提出更灵活的策略。

我们需要 Minion 再次调整我们的:

类 PersistableMinion 实现 Persistable {

@Id 长 ID;

字符串名称;

PersistableMinion(长ID,字符串名称){

this.id = id;

this.name = 名称;

}

@覆盖

公共长 getId() {

返回标识;

}

@覆盖

公共布尔 isNew() {

// 这个实现肯定不适合生产使用

返回真;

}

}

保存一个的代码 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 的选项。虽然我在示例中使用了非常严重的逻辑,但基本没有什么能阻止您实现您所考虑的任何逻辑,因为它们都归结为 Java 代码。

完整的示例代码可在Spring中国教育管理中心(Spring认证)数据示例库访问!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • spring
    +关注

    关注

    0

    文章

    345

    浏览量

    16088
  • JDBC
    +关注

    关注

    0

    文章

    25

    浏览量

    13895
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    使用Python/MyHDL创建自定义FPGA IP

    使用 Python/MyHDL 创建自定义 FPGA IP,与 Vivado 集成,并通过 PYNQ 进行控制——实现软件上的简单硬件设计。
    的头像 发表于 04-09 09:53 467次阅读
    使用Python/MyHDL创建<b class='flag-5'>自定义</b>FPGA IP

    MCUXpresso SDK创建自定义清单

    概述 MCUXpresso SDK 24.12 介绍塞德恩汉CED支持自定义清单,使开发人员能够精确定义其工作区中包含哪些组件、驱动程序、中间件和板支持包。此功能在极简主义、可重复性和 CI/CD
    发表于 04-07 07:11

    极海APM32F427如何实现自定义USB HID设备与PC进行通信

    最近需要使用到 APM32F427 枚举成Custom HID设备进行用户自定义通信,但是官方的例程只有提供的HID枚举为鼠标或者键盘类型的设备。这里记录一下,怎么使用Geehy官方的USB中间件,实现自定义的USB HID设备进行用户通信。
    的头像 发表于 03-30 09:30 2890次阅读
    极海APM32F427如何实现<b class='flag-5'>自定义</b>USB HID设备与PC进行通信

    如何为 Vision Five 2 编译自定义 Linux 内核?

    Vision Five 2 的 Debian 用户指南只提供了半页关于如何编译自己的内核的相当稀疏的内容。仅从该文档中,我无法制作我的自定义内核。那里的信息似乎相当不完整。如果有人能提供一些
    发表于 02-24 07:44

    电能质量监测装置可自定义监测时段吗?

    电能质量监测装置普遍支持自定义监测时段,现代中高端装置还具备分时差异化监测与灵活触发能力,可按时间、事件或混合策略定制采集与存储,兼顾精度、效率与存储成本。 一、自定义监测时段的核心实现方式 1.
    的头像 发表于 12-10 16:49 1212次阅读

    电能质量在线监测装置的自定义监测时段功能有哪些应用场景?

    电能质量在线监测装置的 自定义监测时段功能 ,核心价值是通过 “按需配置监测时间、采样频率和数据策略”,实现精准监测、资源优化与数据针对性分析,其应用场景覆盖工业生产、商业运营、电网运维、特殊保障等
    的头像 发表于 12-10 14:01 597次阅读
    电能质量在线监测装置的<b class='flag-5'>自定义</b>监测时段功能有哪些应用场景?

    电能质量在线监测装置可自定义监测时段吗?

    电能质量在线监测装置 完全支持自定义监测时段 ,并提供 精细化、差异化 的配置能力。核心通过 嵌入式任务调度系统 结合 本地 / 远程参数配置 实现,可灵活设定监测开始 / 结束时间、采样频率、数据
    的头像 发表于 12-10 13:58 525次阅读
    电能质量在线监测装置可<b class='flag-5'>自定义</b>监测时段吗?

    无图形界面模式下自定义检查工具的应用

    此前文章已介绍 ANSA 中的自定义检查工具。本文将探讨该功能在无图形界面(No-GUI)模式下的应用,旨在满足标准化工作流程的需求,适用于需要高度自动化的前处理场景。通过集成自定义检查,用户可实现工作流程的高效自动化运行。
    的头像 发表于 11-30 14:13 853次阅读
    无图形界面模式下<b class='flag-5'>自定义</b>检查工具的应用

    采用汇编指示符来使用自定义指令

    具体实现 1、采用.word .half .dword等汇编指示符直接插入自定义指令,这种方法需要自己指定寄存器。其中.word为插入一个字的数据即32位,.half为插入半字即16位
    发表于 10-28 06:02

    强实时运动控制内核MotionRT750(九):内置C语言的自定义机械手模型实现

    内置C语言的自定义机械手模型实现。
    的头像 发表于 10-27 14:14 1034次阅读
    强实时运动控制内核MotionRT750(九):内置C语言的<b class='flag-5'>自定义</b>机械手模型实现

    如何使用SDK进行自定义音频播放功能

    在上一篇文章安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】自定义音频替换失败过程中,简要概述了res_build_tool.py 文件, 其主要的作用就是将音频文件进行转换,从而使编译固件的时候能够将音频文件编译到BIN中,然后在各项事件触发的时候实现播放。
    的头像 发表于 09-25 15:52 4587次阅读
    如何使用SDK进行<b class='flag-5'>自定义</b>音频播放功能

    LOTO示波器自定义解码功能—CANFD解码

    /?spm_id_from=333.1365.list.card_archive.click 。 视频中仅对串口进行解码演示,正好我们从客户手中拿到了一块USB转CAN/CANFD模块,如下图所示, 本文借此对自定义解码功能
    的头像 发表于 07-11 10:34 1269次阅读
    LOTO示波器<b class='flag-5'>自定义</b>解码功能—CANFD解码

    大彩讲堂:VisualTFT软件如何自定义圆形进度条

    VisualTFT软件如何自定义圆形进度条
    的头像 发表于 07-07 17:10 2072次阅读
    大彩讲堂:VisualTFT软件如何<b class='flag-5'>自定义</b>圆形进度条

    KiCad 中的自定义规则(KiCon 演讲)

    “  Seth Hillbrand 在 KiCon US 2025 上为大家介绍了 KiCad 的规则系统,并详细讲解了自定义规则的设计与实例。  ”   演讲主要围绕 加强 KiCad 中的自定义
    的头像 发表于 06-16 11:17 2716次阅读
    KiCad 中的<b class='flag-5'>自定义</b>规则(KiCon 演讲)

    HarmonyOS应用自定义键盘解决方案

    自定义键盘是一种替换系统默认键盘的解决方案,可实现键盘个性化交互。允许用户结合业务需求与操作习惯,对按键布局进行可视化重构、设置多功能组合键位,使输入更加便捷和舒适。在安全防护层面,自定义键盘可以
    的头像 发表于 06-05 14:19 2743次阅读