1

在处理现有/遗留数据库时,似乎有一个共识,即 ORM 与普通 SQL/SQL 映射器相比并不是一个好的选择。例如,查看此处此处

我刚刚开始在针对遗留数据库的业务密集型应用程序上使用 MyBatis,但由于缺乏 ORM 功能(例如更改跟踪),我开始在我的存储库中编写更新函数,这些函数将尝试更新域实体及其直接关联。但这使得更新语句显着变慢!

因此,我们现在正在考虑为以下每种情况实现功能的新策略:更新实体的直接属性(例如:employeesRepository.update(employee)),更新实体的关联(例如:employeesRepository.updateEmployeeDepartment(employee))或更新实体的集合(例如:userRepository.updateUserRoles(user))。通过遵循此策略,每次更改业务逻辑时,都需要确保保留更改。

这里的主要问题是:在使用普通 SQL 或 MyBatis 等 SQL 映射器时,您可以在多大程度上实现对持久性的无知?实施变更跟踪机制以实现优化更新和清理存储库是否值得?

我还想知道是否有更好的策略将我的域模型映射到遗留数据库?

==============================

更新

为什么坚持无知?出于所有充分的理由。查看:持久无知有什么好处?例如。可测试性和可重用性是首先想到的事情。有关持久性无知及其好处的更多信息:msdn.microsoft.com/en-us/magazine/dd882510.aspx。

基本上我的代码目前看起来像这样:

public assignProfessorAsDean(int academicId) 
{
    UnitOfWork uow = UnitOfWorkFactory.create();
    FacultyRepository facultyRepository = new FacultyRepository(uow);
    FacultyMember prof = facultyRepository.getById(academicId);
    /*promoteToDean updates the set roles posessed by the professor by adding a DeanRole*/
    prof.promoteToDean();
    /*now instead of saying facultyRepository.save(prof),*/
    facultyRepository.updateRoles(prof);
    uow.commit();
}

如您所见,尽管数据访问逻辑和业务逻辑似乎是分开的,但我的数据访问逻辑知道我的域对象的状态究竟发生了什么变化。假设我需要在同一个promoteToDean函数中将员工的前缀更新为“Dean”,然后,除了facultyRepository.updateRoles(prof);我还必须添加类似:facultyRepository.updateTitle(prof);等等。然而,这些都是简单的场景,想象一下代码会如何看起来像复杂的用例。

http://msdn.microsoft.com/en-us/magazine/dd882510.aspx

4

1 回答 1

1

哦,我的看起来就像你在里面的泡菜。但不要害怕。还有希望。(希望 9 个月后,你不会处于同样的境地)。但对于未来的读者。

您想要做的是让您的存储库和工作单元为您的域对象提供代理。代理将具有持久性逻辑,您不想使用更改跟踪等来玷污您的对象。然后,当您调用 uow.commit() 时,它只会检查对象的更改并根据需要执行适当的 sql。(这有点接近普通的 ORM 解决方案所能提供的。

关于这一点,您确定 O/RM 不是最适合您的路径吗?我知道你提到没有代理键之类的东西,但只要有键并且保证它们是唯一的,你仍然可以使用它。例如,Entity Framework(DB2 支持)可以使用Fluent Mappings将非标准键映射到您的域对象,甚至支持不是由服务器生成的键。

于 2014-09-06T14:50:13.443 回答