原文地址:http://mybatis.org/generator/philosophy.html

由于MyBatis Generator这个工具更加聚焦在数据库表而非领域模型,因此会导致一些设计理念上的质疑。我们将会花费一些段落来讨论下这种方式。

首先,这个工具做了它该做的东西。关于这个工具,我们没有对它应该/不应该实现什么做任何声明。总的来说,我们是富领域模型(rich domain models)的坚定倡导者,但是,创建一个富领域模型和回答模型应该如何持久化并不是同一件事情。

如果你的特定设计理念是领域模型驱动其他所有决策,并且数据库设计屈从于领域模型,那么这个工具(包括MyBatis本身)可能不太适合于你的应用。在这种情况下,我们建议你认真研究下Hibernate,它可能更符合你的应用设计与理念。

但是并非所有项目都符合这一范式。甚至于几乎没有企业级的应用完全符合这个范式。MyBatis对于数据库设计和领域模型设计同等重要的项目提供了很大的帮助。MyBatis不是一个对象关系映射器,并且不会尝试把对象持久过程透明化。因此,需要应用开发者来写SQL以便于与数据库交互。

在大型或企业级项目中,很多下面的这些因素会经常出现:

  • 数据库设计与面向对象的领域设计是分开的(单独管理)。
  • 数据库设计者没有面向对象的工具(比如继承),所以,他们不会用面向对象的术语来思考。
  • 应用设计者无法完全控制数据库表的最终形态。比如对于应用来说适合放到一个对象的数据可能会被拆成数据库里的多张表中。
  • 数据库的设计往往与面向对象的设计大相径庭,导致出现表和对象显著不匹配。

以上这些因素往往预示着MyBatis能够很好的适用于你的应用,这也是MyBatis Generator能够起到很好帮助作用的项目类型。那么在这种情况下应该如何使用MyBatis呢?

数据访问对象(DAO)模式仍然是主要的模式。MyBatis Generator可以为每张表生成一组对应的基本的对象。生成的代码是事务中性的,这意味着如果要在一个事务中操作多个表,那么很容易通过在生成的代码添加事务特性来扩展实现。或者你可以创建其他的更好的匹配领域模型持久化需求的DAO(或者服务方法),配合在同一个事务中使用一个或多个生成的对象。

作为一个例子,考虑一个典型的Order对象,典型的header/detail问题。在一些环境下,这种对象至少需要持久化到4个表里,两个key表,一个header表,一个detail表(再次声明,我们这里不是说这就是正确的设计,只是在描述事实)。你的应用应该仍然是与Order对象交互,可能在某些地方(比如OrderDAO或者service对象里)有个saveOrder(Order order)方法。这个方法会与为其中每个表生成的代码来交互。

在这个案例中代码生成给我们带来了什么?几个事情:

  • 重用。很可能一些表会从多个不同的DAOs或者service方法来访问。在应用中为每个表创建一个DAO提高了重用性和一致性。
  • 数据库抽象-定义应用持久化的服务层。这些方法可以很快的稳定下来。随着数据库设计的演化: 1、随着表结构的变更,代码可以随时重新生成 2、service方法可以按需修改 3、应用的上层逻辑可以保持不变。
  • 开发者效率。根据表生成DAO既快速,又可重复,并且无错误。开发者可以集中于对象的持久化,并在需要时把精力用在复杂的表连接查询上。
  • 更少的缺陷。因为应用中最繁琐最容易出错的部分(让SQL与对象匹配)已经自动化了。