数据访问对象 (DAO) 如何允许同时更新列的子集?

How Can a Data Access Object (DAO) Allow Simultaneous Updates to a Subset of Columns?

如果我误用了任何 OOP 术语,请原谅我,因为我对这个主题还不太了解。

我一直在阅读面向对象编程 (OOP) - 特别是针对 Web 应用程序。我一直在研究数据访问对象 (DAO) 的概念。 DAO 负责 CRUD(创建、读取、更新和删除)方法并将应用程序的服务(业务逻辑)层连接到数据库。

我的问题具体涉及 DAO 中的 Update() 方法。在我读过的示例中,开发人员通常将一个 bean 对象作为其主要参数传递给 DAO update() 方法 updateCustomer(customerBean) 该方法然后执行一些 SQL 更新所有基于关于bean中的数据。

我看到的这个逻辑的问题是 update() 方法根据 bean 的数据更新数据库中的 ALL 列,理论上可能会导致它覆盖列另一个用户或系统可能需要同时更新。

一个简化的例子可能是:

我读过 乐观锁定悲观锁定 作为一次只允许一个更新的可能解决方案,但我认为在许多情况下,应用程序 需要 允许同时编辑记录的不同部分而不会锁定或引发错误。

例如,假设管理员正在更新客户的 lastName,同时客户登录网站,登录系统需要更新 dateLastLoggedIn 列,同时计划任务需要更新 lastPaymentReminderDate。在这个疯狂的例子中,如果您将一个 bean 对象传递给 update() 方法并每次都保存整个数据记录,那么无论哪个进程最后运行 update() 方法都可能会覆盖所有数据。

肯定有办法解决这个问题。根据我的研究,我提出了一些可能性,但我很想知道 proper/best 实现这一目标的方法。

可能的解决方案 1:DAO Update() 方法不接受 Bean 作为参数

如果 update() 方法接受一种数据结构,其中包含数据库中需要更新的所有列而不是 bean 对象,您可以使 SQL 语句足够智能,只更新传递给方法的字段。例如,参数可能如下所示:

{ customerID: 1, firstName: 'John' }

这基本上会告诉 update() 方法仅更新基于 customerID 的列 firstName,1. 这将使您的 DAO 非常灵活,并会给服务层与数据库动态交互的能力。我有一种直觉,这违反了 OOP 的某些 "golden rule",但我不确定是哪个。我也从来没有在网上看到任何 DAO 行为的例子。

可能的解决方案 2:向您的 DAO 添加额外的 update() 方法。

您还可以通过向 DAO 添加更具体的 update() 方法来解决此问题。例如,您可能有一个 dateLastLoggedIn()' and 'dateLastPaymentReminderDate()。这样,理论上每个需要更新记录的服务都可以同时进行。如果需要,可以为每个特定的更新方法进行任何锁定。

这种方法的主要缺点是您的 DAO 将开始因各种更新语句而变得非常混乱,而且我看到许多博客文章都在写 DAO 会很快变得多么混乱。

假设您需要允许同时更新记录数据的子集,您将如何使用 DAO 对象解决此类难题?您会坚持将 bean 传递给 DAO 还是有其他我没有考虑过的解决方案?

如果您对 returns 一个 bean 执行 DAO.read() 操作,然后使用用户的新值更新 bean,然后将该 bean 传递给 DAO.update(bean)方法,那么你应该不会有问题,除非两个用户操作发生在彼此的几毫秒内。您的问题暗示 bean 在传递给 update() 方法之前被存储在会话范围或类似范围内。如果那是您正在做的事情,请不要这样做,原因正是您所描述的。您不希望您的 bean 与数据库记录不同步。为了更好的安全性,围绕读取和更新操作包装一个事务,那么两个用户就不可能踩到对方的脚趾,即使用户 2 与用户 1 在同一时间提交他的更改。

Read()、设置值、update() 是我认为的方法。保持豆子新鲜。没有人想要陈旧的豆子。