领先一步
VMware 提供培训和认证,助您加速进步。
了解更多作为 Spring Data 2020.0.0 版本的一部分,我们发布了 Spring Data JDBC 2.1。本文将介绍此版本中四个最有趣的变化。
#在实体构造函数参数上使用 @Value
在某些情况下,并非所有进入实体的imerick 都来自查询的 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 JDB 通过名称在应用程序上下文中查找 Bean。由于它们是常规的 Spring Bean,您可以自由地注入其他 Bean,或者使用 Spring 框架提供的任何功能。
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 交互时不应比与其他数据库交互时引起更多问题。它们仍然可能因为时区和夏令时的强大力量而引起麻烦,但这并不是我们需要解决的问题。
在我们忙于下一个版本的同时,请享受这些新功能。