1. Overview
1.概述
When creating a persistence layer, we need to match our SQL database schema with the object model that we created in our code. This can be a lot of work to do manually.
在创建持久层时,我们需要将我们的SQL数据库模式与我们在代码中创建的对象模型相匹配。这可能是一个大量的手工工作。
In this tutorial, we’ll learn how to generate and export our database schema based on the entity models from our code.
在本教程中,我们将学习如何根据我们代码中的实体模型生成和导出我们的数据库模式。
First, we’ll cover the JPA configuration properties for schema generation. Then we’ll explore how to use these properties in Spring Data JPA.
首先,我们将介绍用于模式生成的JPA配置属性。然后我们将探讨如何在Spring Data JPA中使用这些属性。
Finally, we’ll discuss an alternative for DDL generation using Hibernate’s native API.
最后,我们将讨论使用Hibernate的本地API生成DDL的替代方案。
2. JPA Schema Generation
2.JPA模式的生成
JPA 2.1 introduced a standard for database schema generation. Thus, starting with this release, we can control how to generate and export our database schema through a set of predefined configuration properties.
JPA 2.1为数据库模式的生成引入了一个标准。因此,从这个版本开始,我们可以通过一组预定义的配置属性来控制如何生成和导出我们的数据库模式。
2.1. The Script action
2.1.脚本动作
To control which DDL commands we’ll generate, JPA introduces the script action configuration option:
为了控制我们将生成哪些DDL命令,JPA引入了脚本action配置选项。
javax.persistence.schema-generation.scripts.action
We can choose from four different options:
我们可以从四个不同的选项中进行选择。
- none – doesn’t generate any DDL commands
- create – generates only database create commands
- drop – generates only database drop commands
- drop-and-create – generates database drop commands followed by create commands
2.2. The Script target
2.2.脚本target
For each specified script action, we’ll need to define the corresponding target configuration:
对于每个指定的脚本action,我们需要定义相应的target配置。
javax.persistence.schema-generation.scripts.create-target
javax.persistence.schema-generation.scripts.drop-target
In essence, the script target defines the location of the file that contains the schema create or drop commands. So, for instance, if we choose drop-and-create as the script action, we’ll need to specify both targets.
从本质上讲,脚本的target 定义了包含模式创建或删除命令的文件的位置。因此,例如,如果我们选择drop-and-create作为脚本的action,我们就需要指定两个targets。
2.3. The Schema Source
2.3.模式源
Finally, to generate the schema DDL commands from our entity models, we should include the schema source configurations with the metadata option selected:
最后,为了从我们的实体模型生成模式DDL命令,我们应该包括模式source配置,并选择metadata选项。
javax.persistence.schema-generation.create-source=metadata
javax.persistence.schema-generation.drop-source=metadata
In the next section, we’ll see how we can use Spring Data JPA to automatically generate our database schema with the standard JPA properties.
在下一节中,我们将看到如何使用Spring Data JPA来自动生成具有标准JPA属性的数据库模式。
3. Schema Generation With Spring Data JPA
3.用Spring Data JPA生成模式
3.1. The Models
3.1.模型
Let’s imagine we’re implementing a user-account system with an entity called Account:
让我们设想一下,我们正在实现一个用户-账户系统,该系统有一个实体,名为Account。
@Entity
@Table(name = "accounts")
public class Account {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false, length = 100)
private String name;
@Column(name = "email_address")
private String emailAddress;
@OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
private List<AccountSettings> accountSettings = new ArrayList<>();
// getters and setters
}
Each account can have multiple account settings, so here we’ll have a one-to-many mapping:
每个账户可以有多个账户设置,所以这里我们将有一个one-to-many映射。
@Entity
@Table(name = "account_settings")
public class AccountSetting {
@Id
@GeneratedValue
private Long id;
@Column(name = "name", nullable = false)
private String settingName;
@Column(name = "value", nullable = false)
private String settingValue;
@ManyToOne
@JoinColumn(name ="account_id", nullable = false)
private Account account;
// getters and setters
}
3.2. Spring Data JPA Configuration
3.2.Spring Data JPA配置
To generate the database schema, we’ll need to pass the schema generation properties to the persistence provider in use. To do this, we’ll set the native JPA properties in our configuration file under the spring.jpa.properties prefix:
为了生成数据库模式,我们需要将模式生成属性传递给正在使用的持久化提供者。为了做到这一点,我们将在配置文件中的spring.jpa.properties前缀下设置本地JPA属性。
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata
Then Spring Data JPA passes these properties to the persistence provider when it creates the EntityManagerFactory bean.
然后Spring Data JPA在创建EntityManagerFactorybean时将这些属性传递给持久化提供者。
3.3. The create.sql File
3.3.create.sql文件
As a result, on the application startup, the above configuration will generate the database creation commands based on the entity mapping metadata. Furthermore, the DDL commands are exported into the create.sql file, which is created in our main project folder:
因此,在应用程序启动时,上述配置将根据实体映射元数据生成数据库创建命令。此外,DDL命令被导出到create.sql文件中,该文件在我们的主项目文件夹中创建。
create table account_settings (
id bigint not null,
name varchar(255) not null,
value varchar(255) not null,
account_id bigint not null,
primary key (id)
)
create table accounts (
id bigint not null,
email_address varchar(255),
name varchar(100) not null,
primary key (id)
)
alter table account_settings
add constraint FK54uo82jnot7ye32pyc8dcj2eh
foreign key (account_id)
references accounts (id)
4. Schema Generation With the Hibernate API
4.用Hibernate API生成模式
If we’re using Hibernate, we can use its native API, SchemaExport, to generate our schema DDL commands. Likewise, the Hibernate API uses our application entity models to generate and export the database schema.
如果我们使用Hibernate,我们可以使用其本地API,SchemaExport,来生成我们的模式DDL命令。同样地,Hibernate API使用我们的应用程序实体模型来生成和导出数据库模式。
With Hibernate’s SchemaExport, we can use the drop, createOnly, and create methods explicitly:
通过Hibernate的SchemaExport,我们可以明确地使用drop、createOnly,和create方法。
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
metadataSources.addAnnotatedClass(Account.class);
metadataSources.addAnnotatedClass(AccountSettings.class);
Metadata metadata = metadataSources.buildMetadata();
SchemaExport schemaExport = new SchemaExport();
schemaExport.setFormat(true);
schemaExport.setOutputFile("create.sql");
schemaExport.createOnly(EnumSet.of(TargetType.SCRIPT), metadata);
When we run this code, our database creation commands are exported into the create.sql file in our main project folder.
当我们运行这段代码时,我们的数据库创建命令被导出到主项目文件夹中的create.sql文件。
The SchemaExport is part of the Hibernate Bootstrapping API.
SchemaExport是Hibernate Bootstrapping API的一部分。
5. Schema Generation Options
方案生成选项
Even though schema generation can save us time during development, we should only use it for basic scenarios.
即使模式生成可以在开发过程中为我们节省时间,我们也应该只在基本场景中使用它。
For instance, we could use it to quickly spin up development or testing databases.
例如,我们可以用它来快速启动开发或测试数据库。
In contrast, for more complex scenarios like database migration, we should use more refined tooling, like Liquibase or Flyway.
相比之下,对于像数据库迁移这样更复杂的场景,我们应该使用更精细的工具,比如Liquibase或者Flyway。
6. Conclusion
6.结论
In this article, we learned how to generate and export our database schema with the help of the JPA schema-generation properties. Then we discussed how to achieve the same result using Hibernate’s native API, SchemaExport.
在这篇文章中,我们学习了如何在JPA schema-generation属性的帮助下生成和导出我们的数据库模式。然后我们讨论了如何使用Hibernate的本地API,SchemaExport来实现同样的结果。
As always, the example code for this article is available over on GitHub.
像往常一样,本文的示例代码可在GitHub上获得。