第 11 章 使用对象-关系映射持久化数据

本章内容:

  • 使用 Spring 和 Hibernate

  • 借助上下文 Session,编写不依赖于 Spring 的 Repository

  • 通过 Spring 使用 JPA

  • 借助 Spring Data 实现自动化的 JPA Repository

小时候,骑自行车是一件很有趣的事情,对吧?在清晨,我们骑车上学。放学后,我们游逛到朋友家。当天色渐晚之时,在父母的呼喊声中,我们骑车回家。那些日子真的很有意思!

后来,随着慢慢长大,现在我们所需要的不仅仅是一辆自行车了。有时,我们需要走很远的路去上班或需要装载一些生活用品,还有可能接送孩子去上足球课。如果生活在得克萨斯州的话,我们还必须需要一台空调。我们的需求超出了自行车的功能范围。

在数据持久化的世界中,JDBC 就像自行车。对于份内的工作,它能很好地完成并且在一些特定的场景下表现出色。但随着应用程序变得越来越复杂,对持久化的需求也变得更复杂。我们需要将对象的属性映射到数据库的列上,并且需要自动生成语句和查询,这样我们就能从无休止的问号字符串中解脱出来。此外,我们还需要一些更复杂的特性:

  • 延迟加载(Lazy loading):随着我们的对象关系变得越来越复杂,有时候我们并不希望立即获取完整的对象间关系。举一个典型的例子,假设我们在查询一组 PurchaseOrder 对象,而每个对象中都包含一个 LineItem 对象集合。如果我们只关心 PurchaseOrder 的属性,那查询出 LineItem 的数据就毫无意义。而且这可能是开销很大的操作。延迟加载允许我们只在需要的时候获取数据。

  • 预先抓取(Eager fetching):这与延迟加载是相对的。借助于预先抓取,我们可以使用一个查询获取完整的关联对象。如果我们需要 PurchaseOrder 及其关联的 LineItem 对象,预先抓取的功能可以在一个操作中将它们全部从数据库中取出来,节省了多次查询的成本。

  • 级联(Cascading):有时,更改数据库中的表会同时修改其他表。回到我们订购单的例子中,当删除 Order 对象时,我们希望同时在数据库中删除关联的 LineItem。

一些可用的框架提供了这样的服务,这些服务的通用名称是对象/关系映射(object-relational mapping,ORM)。在持久层使用 ORM 工 具,可以节省数千行的代码和大量的开发时间。ORM 工具能够把你的注意力从容易出错的 SQL 代码转向如何实现应用程序的真正需求。

Spring 对多个持久化框架都提供了支持,包括Hibernate、iBATIS、Java 数据对象(Java Data Objects,JDO)以及 Java 持久化 API(Java Persistence API,JPA)。与 Spring 对 JDBC 的支持那样,Spring 对 ORM 框架的支持提供了与这些框架的集成点以及一些附加的服务:

  • 支持集成 Spring 声明式事务;

  • 透明的异常处理;

  • 线程安全的、轻量级的模板类;

  • DAO 支持类;

  • 资源管理。

本章没有足够的篇幅介绍 Spring 支持的全部 ORM 框架。其实这并不会有什么问题,因为 Spring 对不同 ORM 解决方案的支持是很相似的。一旦掌握了 Spring 对某种 ORM 框架的支持后,你可以轻松地切换到另一个框架。

在本章中,我们将会看到 Spring 如何与最常用的两种 ORM 方案集成:Hibernate 和 JPA。同时还会通过 Spring Data JPA 了解一下 Spring Data 项目。借助这种方式,我们不仅可以学习到如何借助 Spring Data JPA 移除 JPA Repository 中的样板式代码,还能为下一章的如何将 Spring Data 用于无模式的存储打下基础。

让我们先来看看 Spring 是如何为 Hibernate 提供支持的。

Last updated