领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多作为 Spring Data 2020.0.0 版本的一部分,我们发布了 Spring Data JDBC 2.1。本文介绍了此版本中四个最有趣的更改。
#在实体构造函数参数上使用 @Value
在某些情况下,并非所有进入实体的数据都来自查询的ResultSet
。您现在可以使用带有 SpEL 表达式的@Value
注解,该表达式会被求值,其结果会在实体构造时作为参数传递。
class WithAtValue {
private final @Id Long id;
private final @Transient String computed;
WithAtValue(Long id,
@Value("#root.first_name") String computed) {
this.id = id;
this.computed = computed;
}
}
此示例访问ResultSet
中的first_name
列,但 SpEL 上下文也可以访问完整的应用程序上下文。因此,您可以灵活地自定义实体的实例化。
当您使用@Query
指定要为存储库方法执行的查询时,您可以选择提供RowMapper
或ResultSetExtractor
实现的类型。但是,由于从这些类型创建的实例不是 Spring Bean,因此它们不参与依赖注入。因此,您无法将可能想要使用的其他资源注入其中。
您现在可以使用@Query
中的rowMapperRef
或resultSetExtractorRef
属性分别指定实现RowMapper
或ResultSetExtractor
的 Bean 的引用。
interface CarRepository extends CrudRepository<Car, Long> {
@Query(value = "select * from car", resultSetExtractorRef = "carResultSetExtractorBean")
List<Car> findByNameWithResultSetExtractor();
@Query(value = "select model from car", rowMapperRef = "customRowMapperBean")
List<String> findByNameWithRowMapperBean();
}
Spring Data JDBC 按名称在应用程序上下文中查找 Bean。由于它们是普通的 Spring Bean,您可以自由地注入其他 Bean,或者使用 Spring Framework 提供的任何功能。
Spring Data JDBC 实体可以通过构造函数、setter 方法或(对于不可变实体)通过 with 方法来设置其属性。但是,如果属性已由构造函数设置,则不应通过 setter 方法或(可能更糟糕的)with 方法来设置它。这避免了方法调用和可能实例创建的成本。但是,为此,Spring Data JDBC 过去会检查每个属性以查看它是否具有匹配的构造函数参数。此测试非常昂贵,可以通过一次检查是否存在全参数构造函数来避免。在这种情况下,根本不需要调用任何 setter 方法。使用最新版本,Spring Data JDBC 正是这样做的,从而提高了具有全参数构造函数的实体的性能。因此,一个新的性能技巧是提供全参数构造函数。
Spring Data JDBC 从一开始就支持时间类型。但是,当我们添加对 Oracle 的官方支持时,我们发现 Oracle 返回了一种特殊专有的时间类型,Spring Data JDBC 无法将其转换为普通时间类型(例如java.time.Instant
或类似类型)。
在此版本中,我们添加了对转换的支持。使用时间数据类型不应该比使用任何其他数据库对 Oracle 造成更多问题。它们仍然可能由于时区和夏令时的强大功能而导致问题,但这并不是我们要解决的问题。
在我们将下一个版本发布时,尽情享受这些新功能吧。