# 10.1.2　数据访问模板化

如果以前有搭乘飞机旅行的经历，你肯定会觉得旅行中很重要的一件事就是将行李从一个地方搬运到另一个地方。这个过程包含多个步骤。当你到达机场时，第一站是到柜台办理行李托运。然后保安人员对其进行安检以确保安全。之后行李将通过行李车转送到飞机上。如 果你需要中途转机，行李也要进行中转。当你到达目的地的时候，行李需要从飞机上取下来并放到传送带上。最后，你到行李认领区将其取回。

尽管在这个过程中包含多个步骤，但是涉及到旅客的只有几个。承运人负责推动整个流程。你只会在必要的时候进行参与，其余的过程不必关心。这反映了一个强大的设计模式：模板方法模式。

模板方法定义过程的主要框架。在我们的示例中，整个过程是将行李从出发地运送到目的地。过程本身是固定不变的。处理行李过程中的每个事件都会以同样的方式进行：托运检查、运送到飞机上等等。在这个过程中的某些步骤是固定的 —— 这些步骤每次都是一样的。比如当飞机到达目的地后，所有的行李被取下来并通过传送带运到取行李处。

在某些特定的步骤上，处理过程会将其工作委派给子类来完成一些特定实现的细节。这是过程中变化的部分。例如，处理行李是从乘客在柜台托运行李开始的。这部分的处理往往是在最开始的时候进行，所以它在处理过程中的顺序是固定的。由于每位乘客的行李登记都不一样，所以这个过程的实现是由旅客决定的。按照软件方面的术语来讲，模板方法将过程中与特定实现相关的部分委托给接口，而这个接 口的不同实现定义了过程中的具体行为。

这也是 Spring 在数据访问中所使用的模式。不管我们使用什么样的技术，都需要一些特定的数据访问步骤。例如，我们都需要获取一个到数据存储的连接并在处理完成后释放资源。这都是在数据访问处理过程中的固定步骤，但是每种数据访问方法又会有些不同，我们会查询不同的对象或以不同的方式更新数据，这都是数据访问过程中变化的 部分。

Spring 将数据访问过程中固定的和可变的部分明确划分为两个不同的类：模板（template）和回调（callback）。模板管理过程中固定的部分，而回调处理自定义的数据访问代码。图 10.2 展现了这两个类的职责。

![图 10.2　Spring 的数据访问模板类负责通用的数据访问功能。对于应用程序特定的任务，则会调用自定义的回调对象](https://3784153818-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LmcjU5gG__lBrRbUxBO%2F-LnL3IMGj512QTOXdnDm%2F-LnL3r4DDDoyJCebHXTD%2F10.2%20%E6%A8%A1%E6%9D%BF%E4%B8%8E%E5%9B%9E%E8%B0%83.jpg?alt=media\&token=ae5de4e8-3734-46aa-9e62-7166459e9f40)

如图所示，Spring 的模板类处理数据访问的固定部分 —— 事务控制、管理资源以及处理异常。同时，应用程序相关的数据访问 —— 语句、绑定参数以及整理结果集 —— 在回调的实现中处理。事实证明，这是一个优雅的架构，因为你只需关心自己的数据访问逻辑即可。

针对不同的持久化平台，Spring 提供了多个可选的模板。如果直接使用 JDBC，那你可以选择 JdbcTemplate。如果你希望使用对象关系映射框架，那 Hibernate-Template 或 JpaTemplate 可能会更适合你。表 10.2 列出了 Spring 所提供的所有数据访问模板及其用途。

| 模板类(org.springframework.\*)                     | 用途                                       |
| ----------------------------------------------- | ---------------------------------------- |
| jca.cci.core.CciTemplate                        | JCA CCI 连接                               |
| jdbc.core.JdbcTemplate                          | JDBC 连接                                  |
| jdbc.core.namedparam.NamedParameterJdbcTemplate | 支持命名参数的 JDBC 连接                          |
| jdbc.core.simple.SimpleJdbcTemplate             | 通过 Java 5 简化后的 JDBC 连接（Spring 3.1 中已经废弃） |
| orm.hibernate3.HibernateTemplate                | Hibernet 3.x 以上的 Session                 |
| orm.ibatis.SqlMapClientTemplate                 | iBATIS SqlMap 客户端                        |
| orm.jdo.JdoTemplate                             | Java 数据对象（Java Data Object）实现            |
| orm.jpa.JpaTemplate                             | Java 持久化 API 的实体管理器                      |

Spring 为多种持久化框架提供了支持，这里没有那么多的篇幅在本章对其进行一一介绍。因此，我会关注于我认为最为实用的持久化方案，这也是读者最可能用到的。

在本章中，我们将会从基础的 JDBC 访问开始，因为这是从数据库中读取和写入数据的最基本方式。在第 11 章中，我们将会了解 Hibernate 和 JPA，这是最流行的基于 POJO 的 ORM 方案。我们会在第 12 章结束 Spring 持久化的话题，在这一章中，将会看到 Spring Data 项目是如何让 Spring 支持无模式数据的。

但首先要说明的是 Spring 所支持的大多数持久化功能都依赖于数据源。因此，在声明模板和 Repository 之前，我们需要在 Spring 中配置一个数据源用来连接数据库。
