Using NamedParameterJdbcTemplate

    NamedParameterJdbcTemplate 类增加了对使用命名参数的 JDBC 语句编程的支持,而不是只使用传统的占位符(?)参数的 JDBC 语句编程。NamedParameterJdbcTemplate 类包装了一个 JdbcTemplate,并委托被包装的 JdbcTemplate 完成其大部分工作。本节只描述NamedParameterJdbcTemplate 类中与 JdbcTemplate 本身不同的地方 — 即通过使用命名参数来编程 JDBC 语句。下面的例子展示了如何使用 NamedParameterJdbcTemplate:

    1. // some JDBC-backed DAO class...
    2. private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    3. public void setDataSource(DataSource dataSource) {
    4. this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    5. }
    6. public int countOfActorsByFirstName(String firstName) {
    7. String sql = "select count(*) from T_ACTOR where first_name = :first_name";
    8. SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
    9. return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
    10. }

    注意在分配给 sql 变量的值中使用了命名参数符号,而相应的值被插入到 namedParameters 变量(MapSqlParameterSource 类型)。

    另外,你可以通过使用基于 Map 的风格,将命名的参数和它们相应的值传递给 NamedParameterJdbcTemplate 实例。NamedParameterJdbcOperations 暴露的、由 NamedParameterJdbcTemplate 类实现的其余方法遵循类似的模式,这里不做介绍。

    下面的例子显示了基于 Map 的风格的使用:

    1. // some JDBC-backed DAO class...
    2. private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    3. public void setDataSource(DataSource dataSource) {
    4. this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    5. }
    6. public int countOfActorsByFirstName(String firstName) {
    7. String sql = "select count(*) from T_ACTOR where first_name = :first_name";
    8. Map<String, String> namedParameters = Collections.singletonMap("first_name", firstName);
    9. return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
    10. }

    与 NamedParameterJdbcTemplate 相关的一个很好的特性(存在于同一个 Java 包中)是 SqlParameterSource 接口。你已经在之前的一个代码片段中看到了这个接口的实现例子(MapSqlParameterSource 类)。SqlParameterSource 是 NamedParameterJdbcTemplate 的一个命名参数值的来源。MapSqlParameterSource 类是一个简单的实现,它是围绕 java.util.Map的一个适配器,其中的键是参数名,值是参数值。

    另一个 SqlParameterSource 的实现是 BeanPropertySqlParameterSource 类。这个类包装了一个任意的 JavaBean(也就是一个遵守 JavaBean 规范 的类的实例),并使用被包装的JavaBean的属性作为命名参数值的来源。

    下面的例子显示了一个典型的 JavaBean:

    1. public class Actor {
    2. private Long id;
    3. private String firstName;
    4. private String lastName;
    5. public String getFirstName() {
    6. return this.firstName;
    7. }
    8. public String getLastName() {
    9. return this.lastName;
    10. }
    11. public Long getId() {
    12. return this.id;
    13. }
    14. // setters omitted...
    15. }

    下面的例子使用 NamedParameterJdbcTemplate 来返回前面例子中所示类的成员数:

    1. // some JDBC-backed DAO class...
    2. private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    3. public void setDataSource(DataSource dataSource) {
    4. this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    5. }
    6. public int countOfActors(Actor exampleActor) {
    7. // 注意命名的参数是如何与上述 Actor 类的属性相匹配的
    8. String sql = "select count(*) from T_ACTOR where first_name = :firstName and last_name = :lastName";
    9. SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(exampleActor);
    10. return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
    11. }

    记住,NamedParameterJdbcTemplate 类包装了一个经典的 JdbcTemplate 模板。如果你需要访问被包裹的 JdbcTemplate 实例来访问只存在于 JdbcTemplate 类中的功能,你可以使用 getJdbcOperations()方法来通过 JdbcOperations 接口访问被包裹的 JdbcTemplate。

    关于在应用程序中使用 NamedParameterJdbcTemplate 类的指南,请参见 JdbcTemplate 最佳实践