我是一位经验丰富的 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/