跳至主要內容

数据初始化

码匠君大约 6 分钟

数据初始化

[一]知识铺垫

自动数据初始化,需要了解一定的 Spring Data JPA 知识,如果对此还不了解,请先阅读 Spring Data JPA 数据初始化机制

[二]操作步骤

Dante Cloud 数据库表创建和默认数据的初始化,就是使用 Spring Data JPA 自身的机制实现。

Dante Cloud 数据库表创建和默认数据的初始化过程中, 主要会进行以下几项操作。

  • 创建核心业务表
  • 扫描已运行服务中所有的RestController接口,将接口数据转换为权限数据,并汇总至用户中心服务统一存储和管理。
  • 系统默认数据,如用户,角色等数据的初始化。

注意

具体开始之前,一定要确保所有前序工作已经完成。参阅:数据库初始化前序工作

步骤一:创建数据表

  1. 进入 Nacos 管理界面。找到您所使用的对应 多环境 下的 dante-cloud-environment.yaml 配置文件。例如,您当前使用的是 development 环境,那么在 Nacos 后台管理中,找到 Groupdevelopmentdante-cloud-environment.yaml 配置。多环境配置,参阅:多环境配置

  2. 设置 dante-cloud-environment.yaml配置文件中属性 herodotus.switch.database.ddl-auto 的值为 createupdate

注意

  • 如果是初次部署,或者想将已有表重新创建,那么将 herodotus.switch.database.ddl-auto 的值设置为 create
  • 如果是已经开始使用系统了,想保留已有的数据,只做更新,那么将 herodotus.switch.database.ddl-auto 的值设置为 update
  1. 点击发布按钮,发布配置,让配置生效。

警告

  • 正式环境一定要提前做好数据备份

  • 如果是MySQL数据库的初次部署,那么最好将 herodotus.switch.database.ddl-auto 的值设置为 update,否则就会出错。

  • herodotus.switch.database.ddl-auto 的值设置为 update, 再次运行服务,由于 Hibernate 不同方言实现逻辑的不同,在有些数据库下运行,例如:PostgreSQL, 对于某些兼容性问题,只是输出告警;在某些数据库下运行,例如 MySQL,对于某些兼容性问题,会直接抛出 Exception。所以出现这种情况,只要服务继续在运行就不是系统 BUG;如果出错直接导致服务运行停止,那么请报 ISSUE。参阅:MySQL 常见问题

  1. 运行 UpmsApplication 服务。

UpmsApplication 服务第一次正常运行之后,所有核心业务表都已经创建,UpmsApplication 服务中所有接口都已经转换为权限数据存入sys_authority表中。

如果看到有数据库表创建,同时sys_authority表中有数据,证明数据库表创建成功。

  1. 运行 UaaApplication 服务。

UaaApplication 服务第一次正常运行之后,所有 OAuth2 认证相关表都已经创建。

如果看到有以oauth2_开头的数据表创建,证明数据库表创建成功。

  1. 运行 MessageApplication 服务。

MessageApplication 服务第一次正常运行之后,所有站内消息等相关表都已经创建。

如果看到有以msg_开头的数据表创建,证明数据库表创建成功。

为什么表结构的创建不提供脚本?

主要出于以下考虑:

  • 一方面系统默认使用 Spring Data JPA 已经支持了自动建表,数据表的创建和更新都很方便,仅有的问题对于 MySQL 方言支持的一般,会有错误提示,但是不影响整体初始化逻辑。
  • 另一方面微服务架构相比单体应用来说庞大得多,需要关注的内容也扩展了很多倍。提供数据库表结构的脚本,就意味随时要去关注这个 SQL 脚本的更新问题,一旦有遗漏就很容出错,会浪费很多时间和精力,得不偿失。

步骤二:初始默认数据

相关信息

系统提供自动初始化和手动初始化数据库两种方式。

自动化初始化数据库的机制完全由 Spring Data JPA 提供,使用习惯之后非常便捷。但是项目开源至今,发现很多人还是喜欢手动导数据,也提供了数据库初始化脚本。也正因为如此,也修改了本部分说明,主要说明手动导入数据,自动导入数据仅做说明供对此感兴趣的朋友参考。

方式一:手动初始化

  1. 设置 dante-cloud-environment.yaml 配置文件中属性 herodotus.switch.database.ddl-auto 的值为 updatenone

  2. 在工程${project_home}/platform/dante-cloud-message/resources/sqls目录下,可以找到对应数据库数据初始化脚本。可以用你喜欢的方式导入数据库。

方式二:自动初始化

  1. 停止MessageApplication服务

  2. 进入 Nacos 管理界面。找到您所使用的对应 多环境 下的 dante-cloud-environment.yaml 配置文件。

  3. 设置 dante-cloud-environment.yaml 配置文件中属性 herodotus.switch.database.ddl-auto 的值为 updatenone

  4. 设置 dante-cloud-environment.yaml 配置文件中属性 herodotus.switch.database.init-mode 的值为 always

  5. 点击发布按钮,发布配置,让配置生效。

  6. 如果默认使用的不是 PostgreSQL 数据库,需要修改${project_home}/platform/dante-cloud-message/resources/bootstrap.ymlspring.sql.init.data-locations 配置,放开您所使用数据库对应的 SQL 脚本。注释掉其它 SQL 脚本

  7. 再次运行 MessageApplication 服务。

MessageApplication 服务再一次正常运行之后,如果sys_user,sys_role,sys_role_permission等表中都都已经有数据了,证明数据初始化成功。

步骤三:回置配置

  1. 停止MessageApplication 服务

  2. 进入 Nacos 管理界面。找到您所使用的对应 多环境 下的 dante-cloud-environment.yaml 配置文件。

  3. 设置 dante-cloud-environment.yaml 配置文件中属性 herodotus.switch.database.init-mode 的值重置为 never

  4. 检查 dante-cloud-environment.yaml 配置文件中属性 herodotus.switch.database.ddl-auto 的值为 updatenone

  5. 点击发布按钮,发布配置,让配置生效。

为什么回置并再次检查?

  • 如果 herodotus.switch.database.ddl-auto 的值为 createcreate-drop,再次启动服务会重新建表,那么前面的工作就白做了。
  • 如果 herodotus.switch.database.init-mode 的值为 always,再次启动服务会再次执行 SQL 脚本,必定出现主键冲突问题导致失败。

总结

经过实际的使用,总体感受 Spring Data JPA 以及 Hibernate 的多数据库支持还是非常强大,在 PostgreSQL 等自身版本差异不大的数据库家族中,使用非常顺滑。而像MySQL 这种自身各个版本差异较大的数据库家族中,使用起来确实有点蹩脚。

配置参数对应关系

Dante Cloud 数据库操作设计配置参数与spring-boot-starter-data-jpa配置参数对应关系如下表:

配置对应
herodotus.database-information.driver-class-namespring.datasource.driver-class-name
herodotus.database-information.urlspring.datasource.url
herodotus.environment.database.usernamespring.datasource.username
herodotus.environment.database.passwordspring.datasource.password
herodotus.database-information.platformspring.jpa.database
spring.sql.init.platform
herodotus.environment.database.dialectspring.jpa.properties.hibernate.dialect
herodotus.switch.database.ddl-autospring.jpa.hibernate.ddl-auto
herodotus.switch.database.init-modespring.sql.init.mode