更上一层楼
VMware 提供培训和认证,以加速您的进步。
了解更多在 Spring Experience 举办之前,我一直很忙,但我注意到 Rod 在博客方面非常活跃。所以今天我在机场和飞机上的一些空闲时间里,我决定写一篇博客。
我们在 Spring 社区中面临的最大平衡之一是确保我们在保持向后兼容性的同时,仍然进行创新。这种创新的一部分是利用 Java 5 等更高版本 Java 中的新特性和构造。自从 1.2.x 分支以来,我们已经看到了一些这样的情况,例如 @Transactional 注解和基于 @ManagedResource 注解的 JMX 自动检测。最终,这些都是很棒的功能,并且大大简化了开发(至少对我来说是这样),但它们实际上是将元数据移动到代码中。我们还没有看到的是 API 的实际简化。
随着 Spring 2.0 的发布,情况发生了变化。我们看到某些 API 利用了除注解之外的其他特性。事实上,有一个很好的例子,几乎使用了 Java 5 的每个新语言特性(自动装箱、可变参数、泛型),那就是 SimpleJdbcTemplate。SimpleJdbcTemplate 并不是标准 JdbcTemplate 的完全替代品,而是使用 Java 5 来简化某些常见任务。
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
new Object[] { new Double(value), new Integer(type) });
}
... 您不再需要这样做了。
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
new Object[] { value, type });
}
在这个简单的例子中,它并没有太大的区别,但您可以想象在一个包含多个绑定变量的复杂 SQL 查询中,装箱会占用相当多的空间。
所以如果我们从原始例子开始...
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
new Object[] { new Double(value), new Integer(type) });
}
... 并结合自动装箱和可变参数,事情真的开始变得更短了。
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
value, type);
}
public Account getAccount(long id) {
return (Account) getJdbcTemplate().queryForObject(
"select * from accounts where id = ?",
new Object[] { new Long(id) }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
String accountNumber = rs.getString("account_number");
int balance = rs.getInt("balance");
return new Account(accountNumber, balance);
}
});
}
在 Spring 2.0 中,我们发布了 SimpleJdbcTemplate 的配套组件 ParameterizedRowMapper。当两者一起使用时,它实际上创建了一个非常好的小系统,根本不需要类型转换,并且可以让您的 IDE 和编译器进行强类型检查。
public Account getAccount(long id) {
return getSimpleJdbcTemplate().queryForObject(
"select * from accounts where id = ?",
new ParameterizedRowMapper<Account>() {
public Account mapRow(ResultSet rs, int rowNum)
throws SQLException {
String accountNumber = rs.getString("account_number");
int balance = rs.getInt("balance");
return new Account(accountNumber, balance);
}
}, id);
}
需要记住的重要一点是,SimpleJdbcTemplate 并不具备 JdbcTemplate 的所有方法。它甚至没有扩展 JdbcTemplate,而是可以提供对 JdbcTemplate 的引用。SimpleJdbcTemplate 的目标是简化某些常见行为的使用,同时利用 Java 5。
最终,这并不是什么革命性的东西。就像 Rod 之前的帖子一样,这只是一种语法糖。但它是 Spring 正在拥抱 Java 5 及更高版本中新特性的一个例子。