抢先一步
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,因此它们不参与依赖注入。因此,您无法将您可能想要使用的其他资源注入到它们中。
现在,您可以指定对实现了 RowMapper
或 ResultSetExtractor
的 Bean 的引用,但分别使用 @Query
中的 rowMapperRef
或 resultSetExtractorRef
属性。
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 Framework 提供的任何操作。
Spring Data JDBC 实体可以通过构造函数、setter 或(在不可变实体的情况下)通过 with-method 设置其属性。但是,如果一个属性已经通过构造函数设置,则不应通过 setter 或(可能更糟)with-method 设置。这避免了方法调用的成本以及可能的实例创建。但是,为此,Spring Data JDBC 过去会检查每个属性,看看它是否具有匹配的构造函数参数。此测试非常昂贵,可以通过检查一次是否存在全参数构造函数来避免。在这种情况下,根本不需要调用任何 setter。在最新版本中,Spring Data JDBC 正是这样做的,从而提高了具有全参数构造函数的实体的性能。因此,一个新的性能技巧是提供全参数构造函数。
Spring Data JDBC 从一开始就支持时间类型。但是,当我们添加对 Oracle 的官方支持时,我们发现 Oracle 确实为时间类型返回了一种特殊的专有类型,而 Spring Data JDBC 无法将其转换为普通的时间类型(例如 java.time.Instant
或类似类型)。
在此版本中,我们添加了对转换的支持。使用时间数据类型不应比使用任何其他数据库给 Oracle 带来更多问题。它们仍然可能通过时区和夏令时的力量引起麻烦,但这不是我们要解决的问题。
在我们致力于下一个版本的同时,享受新功能。