超前一步
VMware 提供培训和认证,助您快速提升。
了解更多在 Spring Data JDBC 2.0 中,我们不得不引入一些破坏性更改。本文旨在帮助进行迁移。
对自定义列名和表名使用默认的大小写,或者在生成表时精确地引用注解中使用的名称。
使用 AbstractJdbcConfiguration
进行应用程序上下文的自定义配置。
审查事件处理代码,确保您尝试使用的数据不是 null
。
Spring Data JDBC 1.x 大多数情况下不会改变表名和列名。当您使用 SQL 关键字作为属性或实体名,或者尝试在列名中使用某些特殊字符时,这会引发问题。
因此,Spring Data JDBC 2.0 默认引用所有标识符。这使得名称区分大小写,至少对于大多数数据库而言是这样。由于我们默认还会将生成的名称转换为数据库使用的默认大小写格式,所以如果您在 CREATE TABLE
语句中没有使用引号(大多数人都是如此),这应该不会造成任何问题。
例如,考虑如下的 Student
实体
class Student {
@Id
Long id;
String name;
}
H2 数据库中匹配的表可能看起来像这样
CREATE TABLE STUDENT
(
ID SERIAL PRIMARY KEY,
NAME VARCHAR(30)
);
这个示例与 Spring Data JDBC 的先前版本相同。当您使用 @Column
、@Table
或 @MappedCollection
明确指定列名或表名时,情况就有所不同了。在这种情况下,我们假定您指定的名称正是您想要使用的名称,因此表定义必须使用带引号的标识符,或者名称必须使用数据库的默认大小写格式,如下面修改后的学生示例所示
@Table("student")
class Student {
@Id
Long id;
@Column("LAST_NAME")
String name;
}
H2 数据库中匹配的表可能看起来像这样
CREATE TABLE "student" -- (1)
(
ID SERIAL PRIMARY KEY,
LAST_NAME VARCHAR(30) -- (2)
);
表名必须带引号,因为它以小写字母给出,但 H2 默认将不带引号的 SQL 标识符转换为大写。
LAST_NAME
不需要带引号,因为它已经使用了默认的大小写格式。
如果您确实想禁用强制引用,请参见下文。
如果您需要对 ApplicationContext
进行自定义配置,最简单的方法可能是继承 org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration
。其他名称相似且目的相同的类已被移除。
在继承自 AbstractJdbcConfiguration
的配置中,您可以如下所示覆盖 jdbcMappingContext
,以禁用 SQL 标识符的强制引用。
@Bean
@Override
public JdbcMappingContext jdbcMappingContext(Optional<NamingStrategy> namingStrategy, JdbcCustomConversions customConversions) {
JdbcMappingContext mappingContext = super.jdbcMappingContext(namingStrategy, customConversions);
mappingContext.setForceQuote(false);
return mappingContext;
}
AggregateChange
和 DbAction
不可变您可能在事件处理器或回调方法中遇到过这些对象。它们过去是可变的,但这几乎无法以有意义的方式使用。此外,实际上也无法稳定地支持它。因此,它已被移除且没有替代品。
如果您有一个实际更改过这些实例的用例,请在我们的问题跟踪器中创建一个 issue。
Spring Data JDBC 现在有一个 Dialect
接口,并且为完全支持的数据库提供了相应的实现。
支持的数据库包括
DB2
HSQLDB
H2
MySQL 和 MariaDB
Postgres
SQL Server
Oracle 支持目前正在 进行中。
如果您使用不同的数据库,您的应用程序将无法启动。在这种情况下,您需要
实现自己的 Dialect
。
实现一个返回该 Dialect
的 JdbcDialectProvider
。
通过将文件 spring.factories
放入类路径的 META-INF
文件夹中并添加行 org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=<您的 JdbcDialectProvider 的完全限定名>
来注册该提供者。
在我们发表本文之前,已经有人在 Stack Overflow 上写了一个很棒的回答,说明如何做到这一点。
事件仅在没有可用实体时(例如,删除事件)提供实体的 ID。如果在事件中有可用实体,则不按 ID 提供,以避免查找之后可能不会使用的值。之前使用 Optional
值的事件现在使用可为空的值。因此,您应该仔细审查您的事件监听器。