初始化数据库

初始化数据库有两种:

  1. 项目中的业务表,会有一个po与之对应

  2. 初始化数据或者框架自带的一些表

业务表

业务表在框架中都有一个po类与之对应,底层用到了hibernate的orm全映射技术,会根据po自动生成表。

有一点需要注意,当po改变时,也就是表结构需要改变的时候,只会增加字段,不会修改字段,即不会自动修改字段的长度和类型。只有添加的时候会生效,减少或者改变的时候是不会生效的,这也正好符合线上的逻辑。

  • 如果产品已近上线,已近有真实的数据了,这个时候我们不会删除字段,也不可能修改字段的类型

  • 如果产品还没有上线,删除字段或者修改字段的类型,我们可以将数据库中的原表删除,启动项目的时候会根据最新的po映射一张新表出来

spring:
  jpa:
    show-sql: true
    generate-ddl: true
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

初始化数据或者框架表

对于一些初始化数据,或者框架自带功能需要用到的一些表,我们可以使用 SpringBoot 提供的功能帮我们完成

由于项目会多次发布,或者多次重启,要做到初始化脚本的幂等性,也就是多次操作执行的相同的结果,结果不会累加,需要有几个细节注意:

  1. 对于schema脚本,可以使用CREATE TABLE IF NOT EXISTS QRTZ_JOB_DETAILSIF NOT EXISTS帮助我们避免多次执行ddl

  2. 对于初始化数据,我们可以使用主键的唯一性或者在ddl中定义唯一索引,来保证数据的唯一性,这样多次执行就会报错,我们在后续设置的continue-on-error: true可以保证项目正常启动同时数据不会被多次插入。似乎continue-on-error: true的设计就是为了帮助我们这样做的。实现幂等性的关键就是continue-on-error: true,其实我们在ddl中即使不定义IF NOT EXISTS,有continue-on-error: true给我们保证幂等性也是没有问题的。

  3. data: classpath:sql/data-${univer_company}.sql可以在配置文件中引用环境变量,保证不同的环境有不同的初始化数据

  4. 即使这样,也不可能做到一劳永逸,如果在新版本发布的时候,修改了初始化数据的一些字段数据,避免不了累计递增的添加更新脚本,具体情况具体对待

执行顺序

按照一下顺序先后执行

  1. schema

  2. data

  3. hibernate-jpa-po

Last updated

Was this helpful?