2024年Clojure调查中分享你的想法!

欢迎!请参阅关于页面以了解更多关于该如何使用的信息。

+4
工具
编辑

大家好!

最近我决定在Clojure中创建一个中等规模项目的副本(该项目用Java编写,使用Spring Boot和Hibernate),我想知道如何以习惯的方式在Clojure中对数据进行建模、模型和关系建模?

我认为这不必一定是对象或ORM,但我想在代码中应该有一种反映数据库或数据规范的模式(这样开发人员就可以知道从数据库中进行查询的内容以及可以期待从该查询中得到什么)。

所以,我的选择有哪些?

编辑:目前数据库是PostgreSQL

谢谢!

编辑2:感谢大家的答案,它们非常有帮助,我肯定能够解决这个问题了!

6 个答案

+4

选择
 
最佳答案

您将使用哪个数据库?

如果您可以自己选择,那么正如Adrian所提到的,请认真考虑使用Datomic,因为它的数据模型简单且高度灵活。

如果您必须使用SQL,最直接的方式是使用next-jdbc,它将查询结果返回为字典列表。如果您不需要对数据进行任何复杂的转换, simplest 方式是简单使用Clojure丰富的函数来访问和操作数据。不必过于担心创建“领域对象”。《Clojure Applied》提供了一些关于如何结构化领域数据的实用建议。

如果您需要做复杂的转换,一个常见的技巧是进行‘归一化’,即创建一个大字典,其中以‘领域模型名称’作为第一级键,每个记录的id作为第二级键,然后以字典列表的形式表示模型/表行。这使您能快速获取到不同的数据。此技术通常也用于客户端,如果您需要编写单页应用(请参考re-framefulcro)。

DataScript是一个类似Datomic的内存数据库,足够轻量级以在客户端和服务器端使用。您定义一个模式,添加数据,然后可以在其上进行datalog查询和提取,利用其简单灵活的数据模型。因此,即使您使用SQL数据库,您也可以查询一些数据,将结果加载到DataScript中,并在内存中进一步操作和查询,然后写入结果。

您也可以考虑使用specter,这是一个进行数据转换的领域特定语言,尽管在我看来,它创建的复杂度是DataScript等工具所避免的。选择适合您的方案。

by
我想补充一点,我们经常使用clojure.spec来描述代码中的数据库模式,以便我们有1)文档2)验证代码3)一种生成用于测试的随机符合规范数据的方法(这样我们就不需要模拟数据库)4)一个“记录系统”,从中可以推导出列等的列表——我们使用宏从规范生成CRUD函数。
by
强烈推荐归一化。然而,我认为在re-frame的人中并不是常见的做法。它在re-frame的wiki中简要提到了,但似乎没有人真正使用它https://github.com/Day8/re-frame/blob/master/docs/FAQs/DB_Normalisation.md
相比之下,归一化是om.next/fulcro的核心部分。
+4

我目前正在使用手机,所以无法详细解释。
但请查看https://docs.datomic.com/on-prem/schema.html

+1

首先,就像其他人提到的那样,学习一些Datomic或Datascript。这会改变你对数据库的看法。

有一个受到Datomic pull api heavily受影响的SQL库http://walkable.gitlab.io
它可以帮助你快速构建API。它提供了一种表达的方式,描述表格之间的关系,这样你在添加更多表格到系统中时,就不会因为忘记实现细节而感到痛苦。

顺便说一句,我认为编写Clojure代码的最新习惯性方法是数据驱动。

0

我认为这个问题没有一个单一的答案,但我建议你考虑以下建议......你选择了关系型数据库(我认为这完全没问题!)......所以有人可能会争辩说,首先,你的问题与ER建模等密切相关......而不是真正与Clojure相关。:-)

......我的意思是,你已经在提到ORM了。自从你做Java以来,“阻抗/范型不匹配”在关系型和OO世界之间,很多时候会导致大量的混乱/头疼等等。

好了,但是你会付出巨大的代价(我认为),当使用ORM时。例如,如果你不小心,hibernate等将产生最奇怪的事情/查询。例如,在无序地获取某种树结构时,生成的SQL可能会非常愚蠢。现在显然hibernate非常强大。你可以整合非常复杂的缓存等。等。然而,要做好hibernate,我认为并不那么容易/直接。

所以,即使在做Java时,我仍然建议首先考虑Spring JDBC数据访问......因为,就像我说的那样,JPA确实增加了很多复杂性......(..所以问问自己你是否真的需要JPA... )

...无论如何,我想说的是这个......关系数据库很棒...SQL很棒...PostgreSQL很棒!!!...许多编程语言的麻烦在于与关系技术交互往往非常痛苦...因此您开始构建各种工具,如ORM等,以使您的生活更容易忍受....( ...所以我们谈论的是治疗方法,而不是治疗方法.... )

...现在我想论证,与Clojure相比,整个不匹配问题要严重得多,因为Clojure并不是围绕Person等类构建,而是一个少数强大的集合,您就可以出发了 :-).....

...所以让我们更具体一点...我使用Clojure(script)构建了这个闪卡SAP...

...现在...有很多我不太满意的事情......例如,我真的很想从Bootstrap切换到Bulma等等......这是我做的第一个非平凡大小的Clojure项目......所以很明显,我犯了很多错误......我将继续尽快重构/改进事物......然而,最主要的是,我最担心的是PostgreSQL / RDBMS部分...

....我使用luminus模板来设置PostgreSQL项目...此设置包括hugsql(一个拥抱SQL的Clojure库)....然后你可以做ddl / schema的事情...你的PostgreSQL查询...存储过程...等等等等....以一种完全独立于任何应用程序编程语言的方式...只需使用你的PostgreSQL工具/知识...这有多棒!!!.....另外,比如说,我想从clojure切换到java / node whatever...我的整个数据库/持久化层东西可以基本保持不变...因为 tienes with hugsql,你实际上只是在做什么sql......加上非常少的元配置东西,你把它们放在注释里面...从那些注释中,你可以得到可以用来运行查询的Clojure函数.....你可以以map的形式向这些预处理语句传递参数...并以map的形式得到单个记录的输出,或n个记录的序列映射...没有记录返回nil......我想......

....进行转换等,您拥有一切基本但强大的Clojure函数,使映射和seqs的处理变得容易.....另外,当你从PostgreSQL到java......从java到js等进行类型转换时,总是会有一点点...但如果使用luminus,你将获得这些辅助工具开箱即用...所以,例如,在我的闪卡应用程序中,我有很多时间戳......( ...你在某个卡片上回答正确时的确切时间...你留下评论时的确切时间等等等等...)...数据类型一直很复杂......java.sql、java.util、joda等等......但在做这个应用程序时,我根本不需要担心任何这些东西...luminus为你处理这一切......另外,使用clj(script)的出色时间库....( https://github.com/dm3/clojure.java-time / https://github.com/andrewmcveigh/cljs-time )....你可以编写与时间相关的代码...并且它会在中间件以及前端上工作..."...有轻微的例外...")……...(...luminus还提供必要的transit-adapter工具?(不确定是否真的这么叫)也提供了!!!)

...无论如何,我采用了基于KISS原则的策略,并且对此感到相当满意......你对此有什么看法都可以...... :-)

0

我最近将一个13年的Java/hibernate/MySQL设计迁移到了Clojure/Datomic。

我编写了一个库,它读取MySQL表架构,创建一个抽象表规范,然后使用该规范创建Datomic架构,并将所有数据迁移到Datomic。您不妨查看它以获取灵感(我尝试写得更通用一些,但它的关注点相对较为具体)。
https://github.com/thosmos/mysql-to-datomic

然而重点是我创建了自己的抽象数据规范来描述表、列和外键,这样我不仅有了生成Datomic架构的一切所需,而且还可以从这一抽象规范自动生成GraphQL和EQL API和前端CRUD数据输入表单,包括带链接的子表单和数据验证。我试图将这个模型定义规范的精髓提取成一个最小的库。
https://github.com/thosmos/domain-spec

它再次紧密服务于我的用例,但也许它能够激发您在Clojure中可以轻松且更具影响力地做自己事情的意识,而不必过分依赖库和依赖。

0

现在已经有了一段时间,鉴于您提出的问题不断涌现,我认为我可以向您提出,您最终做出了什么决定。事情进展如何?您学到了哪些最重要的经验教训?如果您再这样做,有什么不同之处?

...