持久性设计一般问题

Posted

技术标签:

【中文标题】持久性设计一般问题【英文标题】:Persistence Design General Questions 【发布时间】:2011-11-30 17:32:13 【问题描述】:

我尝试自学,但很快就开始意识到,在读完没完没了的书之后,我将了解所有 @Entity 等低级内容,而无需了解***。


所以我的理解是:

    我们通常声明 DAO 接口,在其中定义要在域模型上执行的所有方法。 其次,我们编写域模型来表示数据库中的实体。 我们编写了 DAO 实现类,它可以使用 Hibernate、JPA、JDBC 或我们现有的任何奇迹并实现我们的 DAO 接口。

(与 Spring 完全连接)


我的问题是指以上几点:


我们为每个领域模型编写单个 DAO 接口?如果我们有参与涉及多个领域模型的交叉行为,我们声明新的对 DAO 接口实现并相应地调用它?例如:“客户从 Stock 订购,Stock 会检查商品是否可用 -> 确认是否可用”那会去哪里?


Hibernate 如何与 MVC 交互?有什么重要的方面需要注意吗?

在我注意到的一本书中:

覆盖等于和哈希码

“在简单的场景中,Hibernate 能够保持实体等价,而不需要对域对象本身进行任何特殊更改。但是,如果您的应用程序需要您将实体添加到 Java 集合中,例如 java.util.Set,或者您计划使用分离的实体,您可能需要覆盖域对象的默认 equals() 和 hashCode() 方法"

也许我不是很了解,什么是分离的实体?那些是我们从 Hibernate 上下文中取出的——实际上只是类的集合?

我想要的是安全地完成 Hibernate 的工作,然后返回一个模型,我将把它提供给 Servlet 并将它委托给适当的视图。我们通过 DAOimpl 类方法的简单返回来提取该模型,还是有点棘手?


如果我要在没有 ORM 框架的情况下做持久层,只使用普通的 JDBC,我的问题是什么?我听说 Hibernate 有一些处理并发请求的智能会话,那么 JDBC 会发生什么?


业务逻辑驻留在哪里?它是 DAOimpl 类吗?


如果我的一些问题是不幸的,我很抱歉,我感谢任何批评和纠正。

谢谢。

【问题讨论】:

【参考方案1】:

我们为每个领域模型编写单个 DAO 接口?如果我们有 参与涉及多人的交叉行为 领域模型我们声明新的对 DAO 接口实现和调用 相应地呢?例如:“来自库存的客户订单,库存检查 Item 是否可用 -> 确认是否可用”那会去哪里?

你可以这样做。一种可能更简单的方法是让服务管理 DAO 调用。如果你使用 Spring,你可以在服务方法上定义你的事务边界,这样所有的 DAO 方法都将参与同一个事务。所以你的 DAO 保持特定于它们各自的模型,理论上更简单。请记住,当任何 DAO 刷新会话时,所有更改都会被推送到数据库。因此,如果您有一个 User 和一个 Profile 模型,并且它们在 hibernate 中被适当地映射,如果您为每个模型创建一个实例并调用刷新会话,它们都将被保存。

这种方法很有吸引力,因为 DAO 应该做一件事——执行持久性操作。如果您开始制作复杂的 DAO,您可能会将应用程序的业务需求封装在持久层中,而您不想这样做。服务是订购持久性操作以实现业务需求的地方。

Hibernate 如何与 MVC 交互?有没有什么重要的方面 知道吗?

MVC 是一种范式。模型视图控制器。目的是在您的应用程序中定义明确的关注点,以便各个组件可以专注于一件事。例如,模型对象不应该告诉视图如何呈现自己。 Hibernate 是一个 ORM 持久化实现。 Hibernate 代码是保存模型对象的一种方法。 MVC 和 hibernate 之间几乎没有什么关系,你可以在一个应用中拥有 MVC 而没有 Hibernate,或者在一个应用中拥有 Hibernate 而没有 MVC。

也许我不是很了解,什么是分离的实体? 那些是我们从 Hibernate 上下文中取出的那个 - 有效地 只是类的集合?

来自documentation“Detached - 一个分离的实例是一个已经持久化的对象,但是它的 Session 已经关闭了。”

分离的实例以后仍然可以保存,但它们需要与会话重新关联。

如果我要在没有 ORM 框架的情况下做持久层,只需简单 JDBC,我有什么问题?我听说 Hibernate 有一些智能 处理并发请求的会话,那么会发生什么 JDBC?

主要缺点是,如果您的应用程序使用对象来表示实体,您需要将 jdbc 结果转换为对象。您还需要编写sql。使用 jdbc 并不是一个坏主意。 ORM 是一个选项。 JDBC 是另一种选择。您也可以混合搭配,但这可能很复杂。对应用程序的并发请求不应成为持久层的关注点。只要确保你的 DAO 不保存任何状态(即使用静态变量)就可以了。

业务逻辑驻留在哪里?是 DAOimpl 类吗?

它是您的域模型和您的服务的组合。如前所述,如果您需要按顺序保存内容,则可以使用服务。如果您要求某些字段应限制为某些值,则可能在模型本身中。它不在 DAO 中——那些应该只处理持久性。

【讨论】:

非常感谢,我可以使用这个对象将它作为模型传递给视图,它只是一个实例吗? Cat fritz = (Cat) sess.load(Cat.class, generatedId); @茄子我不懂 :-) 我刚刚问了具体问题,如何从 Hibernate Session 中检索实体到一个简单的类实例中。猫弗里茨 = (Cat) sess.load(Cat.class, generatedId);猫弗里茨不是持久的,可以用于服务和作为模型是吗?对不起:-) 如果你这样做,你会加载一个 Cat 实例。你可以在任何你想要的地方使用它。如果您更改任何值,那么当您刷新会话时,猫将被保存。如果 Cat 因会话关闭而分离,则需要重新连接。 我想在用户进行更改时这样做,但是当我只想检索(即只是阅读)一只猫并传递给用户查看时,我真的不认为这是一个好想法,因为如果我想对实例进行一些调整(即如何显示它),我真的不想意外地对数据库实体发生同样的事情。我可以将它从 Hibernate 上下文中取出,使其严格意义上的 java 类实例没有额外的行为吗?【参考方案2】:

我已经从我的 spring/hibernate web 应用程序中删除了 dao 层 - 对我来说似乎没有必要。事实上,我无法想象他们现在会包括什么。但这似乎是somewhatdebatable。

对于用 hibernate 覆盖 equals 和 hashcode,我通常使用 db 生成的自动 id,这有点像 debatable。只要你知道 id 只有在第一次持久化到 db 后才存在,就没有问题。

业务逻辑在哪里?

在您的域对象/休眠实体上 - this 小于 controversial。

【讨论】:

以上是关于持久性设计一般问题的主要内容,如果未能解决你的问题,请参考以下文章

Java CRUD DAO持久性设计

设计具有数据持久性的 Web 应用程序的更好方法

Redis的高并发持久化高可用架构设计

DDD - 持久性模型和领域模型

通用持久层如何设计

WebSocket 是什么原理?为什么可以实现持久连接