orm - Clojure - 处理数据库持久性的惯用方法

标签 orm clojure persistence idioms

我是一位经验丰富的 Java 和 SQL 开发人员,正在考虑将 Clojure 用于我的下一个项目。我花了一些时间学习基础知识,但仍在努力理解如何轻松地处理与关系数据库更新交互的惯用方式。

我读过的大多数线程都集中在查询方面,这对我来说实际上不是问题,因为我对 SQL 非常满意,并且认为 jdbc.next 足以满足我的查询需求(可能由 Toucan 增强)如果需要,可提供水合作用支持)。

我主要关心的是如何处理持久性,例如如何自动将修改后的(嵌套)映射(?)保留回数据库,而无需自己跟踪状态。

顺便说一句,我对 Hibernate 本身和 JPA 都有足够的经验,但仍然觉得它们过于僵化和冗长。

我认为在这方面理想的工具是 https://www.sqlalchemy.org/我之前通过 jython 使用过,非常满意。

非常感谢您的所有投入。

根据以下一些评论/问题进行更新:

为了更清楚地设置上下文,假设一个 Web 应用程序购物车场景:一位新客户结账。需要为客户执行一次插入,可能为送货地址执行另一次插入,为订单执行另一次插入,并且这些需要以保留引用完整性的方式进行同步。手动执行所有步骤当然是一种选择,但场景越复杂,处理就越复杂。我的数据库是关系型的。

第二次更新

为了进一步澄清我的问题,我的问题不是如何发出“插入/更新/删除”语句,而是更多地跟踪根据当前状态必须发出哪些语句。

我希望“ORM”层能够跟踪我的“数据”中的哪些是新的、哪些已被修改、删除等,并以类似于 Hibernate 实体管理器的一致方式自动执行上面的代码片段(请看一下有关预期功能的示例,请参阅以下链接 https://www.sitepoint.com/hibernate-introduction-persisting-java-objects/ 在“对实体执行 CRUD 操作”部分中)。

或者,我希望能够识别数据的每个“片段”(休眠用语中的对象图)上发生了什么,然后通过遍历每个元素、“查询”其状态/状态并推断来执行您共享的片段发送回数据库的正确语句。

根据我对语言的理解,到目前为止,这个功能是 clojure 数据结构的 native (?) - 但我还无法具体了解它。

最佳答案

您说您正在使用 next.jdbc ——文档中有执行更新和插入、使用事务以确保一致性的示例,所以我不确定您真正在问什么在这里。

next.jdbc.sql 命名空间包含 update!insert! 函数。 next.jdbc 命名空间具有 with-transaction,用于围绕多个操作创建事务。

update! 返回更新的行数。 insert! 返回新插入的键(根据您使用的特定数据库驱动程序的工作方式尽可能地返回)。

在处理数据库的 Clojure 程序中,尝试将持久性代码与纯业务逻辑分开是很常见的,因此通常会得到如下内容:

(defn some-process [...]
  (let [data    (some-database-query ...)
        updates (perform-business-logic ...)]
    (with-transaction [tx ...]
      ...based on what is in updates...
      (update-something tx ...)
      (insert-something tx ...)
      (insert-more-stuff tx ...))))

如果后续插入/更新依赖于早期插入生成的键,您可以使用 let 捕获早期插入的结果,以便您可以在其他插入/更新中访问这些键.

重构上述内容是合理的,因此整个 with-transaction 表单位于 some-process 调用的单独函数中,并传入 updates 和连接/数据源。

如果这不能回答您的问题,您可以尝试澄清一下您真正要问的内容吗?

此外,如果您想与其他 Clojurians 就关系数据库持久性进行互动对话,请随时加入 Clojurians Slack 并在 #sql channel 中发布问题。

Clojure Slack:https://clojurians.slack.com

自行注册:http://clojurians.net (或者,如果您在自行注册时遇到问题,我可以在此处发布自定义邀请链接)

关于orm - Clojure - 处理数据库持久性的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64833369/

相关文章:

c# - linq2db 更新找不到 .Set 方法 MySQL 的定义

php - PhalconPHP Framework - 如何更新模型对象和相关对象

clojure - 如何在 Clojure 中访问表单的各个字段?

java - EclipseLink 错误 : Exception Description: Missing descriptor for class

java - Hibernate 中级/高级教程

java - 存储持久对象的正确位置是什么?

python - 如何使用SQLAlchemy设置和获取关系记录?

php - Propel2 与表连接,然后使用聚合函数进行分组

logging - 如何抑制继承的项目 logback.xml 文件(单个项目中有 2 个 logback.xml)?

java - 从 Clojure 调用 java 函数