使用 NamedParameterJdbcTemplate
NamedParameterJdbcTemplate
类增加了对使用命名参数编程 JDBC 语句的支持,这与仅使用经典占位符('?'
)参数进行编程的 JDBC 相反。 NamedParameterJdbcTemplate
类包装JdbcTemplate
并委托包装的JdbcTemplate
完成其许多工作。本节仅描述NamedParameterJdbcTemplate
类的与JdbcTemplate
本身不同的区域,即使用命名参数对 JDBC 语句进行编程。以下示例显示了如何使用NamedParameterJdbcTemplate
:
// some JDBC-backed DAO class...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int countOfActorsByFirstName(String firstName) {
String sql = "select count(*) from T_ACTOR where first_name = :first_name";
SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
请注意,在分配给sql
变量的值和插入namedParameters
变量(类型MapSqlParameterSource
)的相应值中使用了命名参数符号。
或者,您可以使用基于Map
的样式将命名参数及其对应的值传递给NamedParameterJdbcTemplate
实例。NamedParameterJdbcOperations
公开并由NamedParameterJdbcTemplate
类实现的其余方法遵循类似的模式,此处不再赘述。
下面的示例说明基于Map
的样式的用法:
// some JDBC-backed DAO class...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int countOfActorsByFirstName(String firstName) {
String sql = "select count(*) from T_ACTOR where first_name = :first_name";
Map<String, String> namedParameters = Collections.singletonMap("first_name", firstName);
return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
与NamedParameterJdbcTemplate
相关联(并且存在于同一 Java 包中)的一项不错的功能是SqlParameterSource
接口。您已经在以前的代码片段之一(MapSqlParameterSource
类)中看到了此接口的实现示例。 SqlParameterSource
是NamedParameterJdbcTemplate
的命名参数值的来源。 MapSqlParameterSource
类是一个简单的实现,它是围绕java.util.Map
的适配器,其中键是参数名称,值是参数值。
另一个SqlParameterSource
实现是BeanPropertySqlParameterSource
类。此类包装任意 JavaBean(即,遵循JavaBean 约定的类的实例),并使用包装的 JavaBean 的属性作为命名参数值的源。
以下示例显示了典型的 JavaBean:
public class Actor {
private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public Long getId() {
return this.id;
}
// setters omitted...
}
下面的示例使用NamedParameterJdbcTemplate
返回上一示例中显示的类的成员数:
// some JDBC-backed DAO class...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int countOfActors(Actor exampleActor) {
// notice how the named parameters match the properties of the above 'Actor' class
String sql = "select count(*) from T_ACTOR where first_name = :firstName and last_name = :lastName";
SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(exampleActor);
return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
请记住,NamedParameterJdbcTemplate
类包装了经典的JdbcTemplate
模板。如果需要访问包装的JdbcTemplate
实例以访问仅在JdbcTemplate
类中提供的功能,则可以使用getJdbcOperations()
方法通过JdbcOperations
接口访问包装的JdbcTemplate
。
示例代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringNamedParameterJdbcTemplateTest {
@Autowired
private NamedParameterJdbcTemplate jdbcTemplate;
@Test
public void testFind(){
Map<String,Object> map = new HashMap<>();
map.put("id",1);
Account account = jdbcTemplate.queryForObject("select * from account where id = :id",map,new BeanPropertyRowMapper<Account>(Account.class));
System.out.println(account);
}
@Test
public void testSave(){
Account account = new Account();
account.setName("NamedParameterJdbcTemplate");
account.setMoney(12345d);
BeanMap beanMap = BeanMap.create(account);
jdbcTemplate.update("insert into account(name,money)values(:name,:money)",beanMap);
}
}