项目中采用liquibase做项目初始化数据库操作,原本是只支持mysql库,所以很简单的实现了,后来考虑要支持H2、Oracle、SqlServer等一些常见的其他数据库,因此就出现了问题,初步尝试是根据不同库,在changelog.xml中根据preConditions,不同数据库写不同的changeSet,但是考虑到维护和扩展太麻烦,就是使用到了变量替换。
项目中用到了定时任务是使用的quartz2.3.2 最开始是通过在changelog.xml中创建表和约束的,后来发现quartz自己的jar中存在不同库的sql文件,这就简单了许多,直接在liquibase的changelog.xml中通过sqlFile classpath 来直接执行jar中的SQL文件,简单操作,并且更具准确性。
变量替换
- 考虑通过不同库来替换需要变换的数据库字段,而不是通过preConditions
master.xml中配置
<property name="jsonType" value="JSON" dbms="mysql"/>
<property name="jsonType" value="VARCHAR(100)" dbms="h2"/>
changelog.xml中变量
<changeSet author="william (generated)" id="1608712978947-20">
<createTable remarks="菜单权限表" tableName="sys_menu">
<column autoIncrement="true" name="menu_id" remarks="菜单ID" type="BIGINT">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="i18n_name" remarks="国际化菜单名称" type="${jsonType}"/>
</createTable>
</changeSet>
使用quartz自带sql
- 将定时任务的相关创建语句去除,而使用quartz jar中自带的sql
quartz中自带sql位置:
org.quartz.impl.jdbcjobstore
<changeSet id="1.10" author="william (generated)" dbms="h2">
<sqlFile
encoding="utf8"
path="classpath:/org/quartz/impl/jdbcjobstore/tables_h2.sql"
relativeToChangelogFile="false"
splitStatements="true"
stripComments="true"/>
</changeSet>
<changeSet id="1.11" author="william (generated)" dbms="mysql">
<sqlFile
encoding="utf8"
path="classpath:/org/quartz/impl/jdbcjobstore/tables_mysql.sql"
relativeToChangelogFile="false"
splitStatements="true"
stripComments="true"/>
</changeSet>
非jar包,项目中SQL调用方式:
<changeSet id="18" author="naslami">
<sqlFile dbms="h2" path="src/main/resources/db/changelog/inserts.sql" />
</changeSet>
注意:第二个方法中引用jar中的sql,liquibase要求版本为4.0.0