7.1.1. 创建数据库架构

在应用程序开发过程中,需要创建和维护与模型实体对应的数据库架构。平台提供了一种基于数据库创建和更新脚本的方法来完成此任务。下面介绍使用这种方法的实际步骤。

创建和维护数据库架构的任务包括两部分:创建脚本和执行脚本。

可以手动创建脚本,也可以使用 Studio 创建脚本。下面介绍在 Studio 中创建脚本的过程。在 CUBA 主菜单或者 Data Model 右键菜单中运行 Generate Database Scripts 命令。这时,Studio 会连接到 Project Properties 窗口中定义的数据库,并将可用的 DB 架构与当前数据模型进行比较。

如果数据库不存在或没有 SYS_DB_CHANGELOGSEC_USER 表,则系统仅生成数据库初始化脚本。否则,也会创建更新脚本。脚本生成后,会打开含有生成脚本的窗口。

更新脚本显示在 Updates 标签页上。状态是 new 的脚本反映数据模型的当前状态与 DB 架构之间的差异。对每个新表或修改的表会创建单独的脚本。某些脚本还包含一组参照完整性约束。单击 Save and close 关闭界面时,脚本将保存在 core 模块的 db/update/{db_type} 目录中。

项目中存在并且已应用到 DB 的脚本将显示为 applied 状态。这种脚本不能被修改或删除。

Updates 标签页还会显示出 to be deleted 状态的脚本。这些脚本是项目中有效脚本,但没有应用到 DB。单击 Save and close 关闭界面时,这些脚本会被删除。如果脚本由之前的脚本生成过程创建,但没有通过调用 Update Database 将脚本应用到 DB,这是标准行为。在这种情况下,不再需要这些脚本,因为当前数据库架构和数据模型之间的差异反映在最新生成的脚本中。但是,如果脚本由其它开发人员编写并从版本控制系统获取,则应取消保存并先应用这些脚本到数据库,然后再生成新脚本。

Init TablesInit ConstraintsInit Data 标签页中显示位于 core 模块的 db/init/{db_type} 目录中的 DB 创建脚本。

Init Tables 标签页显示用于创建表的 10.create-db.sql 脚本。同一个表相关的代码由 begin {table_name} ... end {table_name} 注释包围起来。当模型中的实体发生更改时,Studio 仅替换注释之间(begin …​ end 之间)的相应表的代码,而保留其余代码。这样,如果这个文件中有手工编写的代码,也不会被覆盖。因此,请勿在手工编辑代码时删除这些注释,否则 Studio 将无法将更改正确地应用到现有文件。

Init Constraints 标签页显示用于创建完整性约束的 20.create-db.sql 脚本。同样,它也有不应被删除的用于分隔表的注释。

Init Data 标签页显示 30.create-db.sql 脚本,该脚本用于在初始化 DB 时提供额外信息。这些额外的信息可以是函数、触发器、DML 操作或必要的数据库初始数据。如有必要,可手工创建此脚本的内容。

在应用程序开发的初始阶段,数据模型更改比较频繁,建议仅使用 DB 创建脚本(位于 Init TablesInit ConstraintsInit Data 标签页中)并在调用 Generate DB scripts 命令后立即移除 Updats 标签页中的更新脚本。这是使数据库保持最新状态的最简单可靠的方法。当然,它有一个明显的缺点,那就是应用这些脚本会从头开始重新创建数据库,所有数据都会丢失。在开发阶段可以通过向 Init Data 脚本添加命令(填充数据的脚本)从一定程度上弥补这一缺陷,该脚本可以在初始化时填充一些基本的数据。

更新脚本会成为后期开发和维护数据库的方便又必要的工具,当数据模型相对稳定时,开发和生产数据库中的数据不会因为从头开始重新创建数据库而丢失。

使用Gradle 任务执行数据库脚本来应用脚本:调用 CUBA > Create Database 重新创建数据库,调用 CUBA > Update Database 应用脚本;Data Model 的右键菜单也有同样的命令。请注意,只有应用程序服务停止时,这些操作才可用。当然,也可以随时从命令行调用相应的 Gradle 任务( createDbupdateDb),但如果数据库或其任何数据库对象被锁定,脚本执行可能会失败。