我想你忘了看“功能关系映射”。
总结一下:
- 如果您想专注于数据结构,请使用ORM,如JPA / Hibernate。
- 如果您想突出治疗效果,请查看FRM库:QueryDSL或Jooq。
- 如果您需要针对特定数据库调整SQL请求,请使用JDBC和本机SQL请求。
各种“关系映射”技术的优势在于可移植性:您确保应用程序将在大多数ACID数据库上运行。否则,当您手动编写SQL请求时,您将应对不同SQL方言之间的差异。
当然,您可以限制自己使用SQL92标准(然后进行一些函数式编程),或者您可以重新使用ORM框架的一些概念。
ORM的优点是建立在会话对象上的,该对象可以作为瓶颈:
- 它在底层数据库事务正在运行时管理对象的生命周期。
- 它维护Java对象与数据库行之间的一对一映射(并使用内部缓存以避免重复对象)。
- 它自动检测关联更新和要删除的孤立对象。
- 它处理乐观或悲观锁的并发问题。
然而,它的优点也是它的缺点:
- 会话必须能够比较对象,因此您需要实现equals / hashCode方法,但对象的相等性必须基于“业务键”,而不是数据库ID(新的瞬态对象没有数据库ID!)。
- 会话必须监视关系更改,但其映射规则推动使用不适合业务算法的集合。有时,您希望使用HashMap,但ORM将要求键是另一个“富域对象”,而不是另一个轻量级对象...然后您必须在扮演键的富域对象上实现对象相等性...但您不能,因为此对象在业务世界中没有对应物。所以你回到一个简单的列表上,你必须迭代它(并且性能问题会导致)。
- ORM API有时不适用于现实世界的使用。例如,真实的Web应用程序通过在获取数据时添加一些“WHERE”子句来强制执行会话隔离...然后“Session.get(id)”不足够,您需要转向更复杂的DSL(HSQL,Criteria API)或返回本机SQL。
- 数据库对象与其他框架专用的其他对象冲突(例如OXM框架=对象/ XML映射)。例如,如果您的REST服务使用Jackson库将业务对象序列化。但这个Jackson恰好映射到Hibernate One。然后,您可以合并两者,并出现API和数据库之间的强耦合,或者您必须实现翻译,ORM节省的所有代码都会在那里丢失...
另外一方面,FRM是“对象关系映射”(ORM)和本地SQL查询(使用JDBC)之间的权衡。
解释FRM与ORM之间的差异的最好方法是采用DDD方法。
- 对象关系映射支持使用"丰富领域对象",这些Java类在数据库事务期间的状态是可变的
- 函数关系映射依赖于"贫穷领域对象",它们是不可变的(非常之多,你必须每次想要更改其内容时克隆一个新的)
它释放了对ORM会话的约束,并大多依赖于DSL而非SQL(因此可移植性不重要)。但另一方面,您必须查看事务细节和并发问题。
List<Person> persons = queryFactory.selectFrom(person)
.where(
person.firstName.eq("John"),
person.lastName.eq("Doe"))
.fetch()