Clojure数据库交互 - 应用程序设计/方法

时间:2022-01-30 22:46:52

I hope this question isn't too general or doesn't make sense.

我希望这个问题不是太笼统或没有意义。

I'm currently developing a basic application that talks to an SQLite database, so naturally I'm using the clojure.java.jdbc library (link) to interact with the DB.

我正在开发一个与SQLite数据库对话的基本应用程序,所以我自然而然地使用clojure.java.jdbc库(链接)与数据库进行交互。

The trouble is, as far as I can tell, the way you insert data into the DB using this library is by simply passing a map (e.g. {:id 1 :name "*"} and a table name (e.g. :website)

问题是,据我所知,使用此库将数据插入数据库的方法是简单地传递一个地图(例如{:id 1:name“*”}和一个表名(例如:website)

The thing that that I'm concerned about is how can I make this more robust in the wider context of my application? What I mean by this is when I write data to the database and retrieve it, I want to use the same formatted map EVERYWHERE in the application, so from the data access layer (returning or passing in maps) all the way up to the application layer where it works on the data and passes it back down again.

我关心的是如何在更广泛的应用环境中使其更加强大?我的意思是当我将数据写入数据库并检索它时,我想在应用程序中使用相同格式的地图,所以从数据访问层(返回或传入地图)一直到应用程序它对数据起作用的层并再次将其传回。

What I'm trying to get at is, is there an 'idiomatic' clojure equivalent of JavaBeans?

我想要的是,是否有一个与JavaBeans相当的'惯用'clojure?

The problem I'm having right now is having to repeat myself by defining maps manually with column names etc - but if I change the structure of my table in the DB, my whole application has to be changed.

我现在遇到的问题是不得不通过使用列名等手动定义映射来重复自己 - 但是如果我在DB中更改表的结构,则必须更改整个应用程序。

2 个解决方案

#1


4  

As far as I know, there really isn't such a library. There are various systems that make it easier to write queries, but not AFAIK, anything that "fixes" your data objects.

据我所知,确实没有这样的图书馆。有各种系统可以更容易地编写查询,但不是AFAIK,任何“修复”数据对象的东西。

I've messed around trying to write something like you propose myself but I abandoned the project since it became very obvious very quickly that this is not at all the right thing to do in a clojure system (and actually, I tend to think now that the approach has only very limited use even in languages that have really "fixed" data structures).

我一直在试图写出像你自己提出的东西,但我放弃了这个项目,因为它很快就变得非常明显,这在clojure系统中根本不是正确的事情(实际上,我倾向于认为现在即使在具有真正“固定”数据结构的语言中,该方法的使用也非常有限。

Issues with the clojure collection system:

clojure收集系统的问题:

  • All the map access/alteration functions are really functional. That means that alterations on a map always return a new object, so it's nearly impossible to create a forcibly fixed map type that's also easy to use in idiomatic clojure.
  • 所有地图访问/更改功能都非常实用。这意味着地图上的更改总是返回一个新对象,因此几乎不可能创建一个强制修复的地图类型,这也很容易在惯用语中使用。

General conceptual issues:

一般概念问题:

  • Your assumption that you can "use the same formatted map EVERYWHERE in the application, so from the data access layer (returning or passing in maps) all the way up to the application layer where it works on the data and passes it back down again" is wrong if your system is even slightly complex. At best, you can use the map from the DB up to the UI in some simple cases, but the other way around is pretty much always the wrong approach.

    您假设您可以“在应用程序中使用相同的格式化地图,因此从数据访问层(返回或传入地图)一直到应用程序层,它处理数据并再次将其传回”如果您的系统稍微复杂,那就错了。最好的情况是,在一些简单的情况下,您可以使用从数据库到UI的映射,但另一种方法几乎总是错误的方法。

  • Almost every query will have its own result row "type"; you're probably not going to be able to re-use these "types" across queries even in related code.

    几乎每个查询都有自己的结果行“type”;即使在相关代码中,您也可能无法在查询中重复使用这些“类型”。

  • Also, forcing these types on the rest of the program is probably binding your application more strictly to the DB schema. If your business logic functions are sane and well written, they should only access as much data as they need and no more; they should probably not use the same data format everywhere.

    此外,在程序的其余部分强制使用这些类型可能会更严格地将应用程序绑定到数据库模式。如果您的业务逻辑功能理智且写得很好,那么它们应该只访问所需的数据,而不是更多;他们可能不应该在任何地方使用相同的数据格式。

My serious answer is; don't bother. Write your DB access functions for the kinds of queries you want to run, and let those functions check the values moving in and out of the DB as much detail as you find comforting. Do not try to forcefully keep the data coming from the DB "the same" in the rest of your application. Use assertions and pre/post conditions if you want to check your data format in the rest of the application.

我认真的回答是;不要打扰。为您想要运行的查询类型编写数据库访问函数,并让这些函数检查进出DB的值,尽可能详细。不要试图在应用程序的其余部分强制保持来自数据库的数据“相同”。如果要在应用程序的其余部分中检查数据格式,请使用断言和前/后条件。

#2


2  

Clojure favour the concept of Few data structure and lots of functions to work on these few data structures. There are few ways to create new data structure (which I guess internally uses the basic data structures) like defrecord etc. But again if you are able to use them that won't really solve the problem that DB schema changes should effect the code less as you will eventually have to go through layers to remove/add the effects of the schema changes, because anywhere you are reading/creating that data that needs to be changed

Clojure支持很少的数据结构和许多函数的概念来处理这些少数数据结构。有几种方法可以创建新的数据结构(我猜在内部使用基本的数据结构),如defrecord等。但是,如果你能够使用它们,那将无法真正解决DB模式更改应该减少代码的问题因为您最终必须通过图层来删除/添加架构更改的效果,因为您正在读取/创建需要更改的数据的任何位置

#1


4  

As far as I know, there really isn't such a library. There are various systems that make it easier to write queries, but not AFAIK, anything that "fixes" your data objects.

据我所知,确实没有这样的图书馆。有各种系统可以更容易地编写查询,但不是AFAIK,任何“修复”数据对象的东西。

I've messed around trying to write something like you propose myself but I abandoned the project since it became very obvious very quickly that this is not at all the right thing to do in a clojure system (and actually, I tend to think now that the approach has only very limited use even in languages that have really "fixed" data structures).

我一直在试图写出像你自己提出的东西,但我放弃了这个项目,因为它很快就变得非常明显,这在clojure系统中根本不是正确的事情(实际上,我倾向于认为现在即使在具有真正“固定”数据结构的语言中,该方法的使用也非常有限。

Issues with the clojure collection system:

clojure收集系统的问题:

  • All the map access/alteration functions are really functional. That means that alterations on a map always return a new object, so it's nearly impossible to create a forcibly fixed map type that's also easy to use in idiomatic clojure.
  • 所有地图访问/更改功能都非常实用。这意味着地图上的更改总是返回一个新对象,因此几乎不可能创建一个强制修复的地图类型,这也很容易在惯用语中使用。

General conceptual issues:

一般概念问题:

  • Your assumption that you can "use the same formatted map EVERYWHERE in the application, so from the data access layer (returning or passing in maps) all the way up to the application layer where it works on the data and passes it back down again" is wrong if your system is even slightly complex. At best, you can use the map from the DB up to the UI in some simple cases, but the other way around is pretty much always the wrong approach.

    您假设您可以“在应用程序中使用相同的格式化地图,因此从数据访问层(返回或传入地图)一直到应用程序层,它处理数据并再次将其传回”如果您的系统稍微复杂,那就错了。最好的情况是,在一些简单的情况下,您可以使用从数据库到UI的映射,但另一种方法几乎总是错误的方法。

  • Almost every query will have its own result row "type"; you're probably not going to be able to re-use these "types" across queries even in related code.

    几乎每个查询都有自己的结果行“type”;即使在相关代码中,您也可能无法在查询中重复使用这些“类型”。

  • Also, forcing these types on the rest of the program is probably binding your application more strictly to the DB schema. If your business logic functions are sane and well written, they should only access as much data as they need and no more; they should probably not use the same data format everywhere.

    此外,在程序的其余部分强制使用这些类型可能会更严格地将应用程序绑定到数据库模式。如果您的业务逻辑功能理智且写得很好,那么它们应该只访问所需的数据,而不是更多;他们可能不应该在任何地方使用相同的数据格式。

My serious answer is; don't bother. Write your DB access functions for the kinds of queries you want to run, and let those functions check the values moving in and out of the DB as much detail as you find comforting. Do not try to forcefully keep the data coming from the DB "the same" in the rest of your application. Use assertions and pre/post conditions if you want to check your data format in the rest of the application.

我认真的回答是;不要打扰。为您想要运行的查询类型编写数据库访问函数,并让这些函数检查进出DB的值,尽可能详细。不要试图在应用程序的其余部分强制保持来自数据库的数据“相同”。如果要在应用程序的其余部分中检查数据格式,请使用断言和前/后条件。

#2


2  

Clojure favour the concept of Few data structure and lots of functions to work on these few data structures. There are few ways to create new data structure (which I guess internally uses the basic data structures) like defrecord etc. But again if you are able to use them that won't really solve the problem that DB schema changes should effect the code less as you will eventually have to go through layers to remove/add the effects of the schema changes, because anywhere you are reading/creating that data that needs to be changed

Clojure支持很少的数据结构和许多函数的概念来处理这些少数数据结构。有几种方法可以创建新的数据结构(我猜在内部使用基本的数据结构),如defrecord等。但是,如果你能够使用它们,那将无法真正解决DB模式更改应该减少代码的问题因为您最终必须通过图层来删除/添加架构更改的效果,因为您正在读取/创建需要更改的数据的任何位置