Liquibase - 使用 uuid 插入行

Liquibase - insert rows with uuid

我有两个表声明如下:

<changeSet author="istvan" id="country-table-changelog">
    <createTable tableName="country">
        <column name="id" type="uuid">
            <constraints nullable="false" unique="true" />
        </column>
        <column name="name" type="varchar">
            <constraints nullable="false" unique="true" />
        </column>
    </createTable>
</changeSet>

<changeSet author="istvan" id="region-table-changelog">
    <createTable tableName="region">
        <column name="id" type="uuid" >
            <constraints nullable="false" unique="true" />
        </column>
        <column name="country_id" type="uuid">
            <constraints nullable="false" />
        </column>
        <column name="name" type="varchar">
            <constraints nullable="false" unique="true" />
        </column>
    </createTable>
</changeSet>

<changeSet author="istvan" id="region-country-foreign-key-constraint">
    <addForeignKeyConstraint 
        baseTableName="region"
        baseColumnNames="country_id"
        referencedTableName="country"
        referencedColumnNames="id"
        constraintName="fk_region_country"
        onDelete="CASCADE" 
        onUpdate="RESTRICT"/>
</changeSet>

我想用 liquibase 更新日志文件中的一些值填充两个表,例如:

INSERT INTO country VALUES('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'HUNGARY');
INSERT INTO region VALUES('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'Baranya');

在示例中,我使用 aaaa 和 bbbb 只是为了简单起见。我想通过 DBMS 生成这些 UUID。

最好的方法是什么?我必须在我的更新日志文件中使用 SQL 还是可以使用 XML?我更喜欢 DBMS 独立解决方案,例如 XML 或 JSON.

我的第二个问题是如何声明一个带有 UUID 的列,该列在插入时创建 UUID。类似于:

<column name="id" type="uuid" value="??? GENERATE UUID ???">
    <constraints nullable="false" unique="true" />
</column>

感谢您的宝贵时间!

一些数据库支持 UUID 列:

我认为 Liquibase 没有嵌入 UUID 生成器,请查看 defaultValueComputed/valueComputed 属性 列 (http://www.liquibase.org/documentation/column.html) + DB 函数生成 UUID

您可以使用根据当前 DBMS 定义的属性来执行此操作。

<property name="uuid_type" value="uuid" dbms="postgresql"/>
<property name="uuid_type" value="uniqueidentifier" dbms="mssql"/>
<property name="uuid_type" value="RAW(16)" dbms="oracle"/>

<property name="uuid_function" value="uid.uuid_generate_v4()" dbms="postgresql"/>
<property name="uuid_function" value="NEWID()" dbms="mssql"/>
<property name="uuid_function" value="sys_guid()" dbms="oracle"/>

然后在定义 table 时使用这些属性:

<column name="id" type="${uuid_type}" defaultValueComputed="${uuid_function}">
    <constraints nullable="false" unique="true" />
</column>

注意需要使用defaultValueComputed,不是value

如果列定义了默认值,只需在插入语句中将其保留,然后数据库将在插入时生成 UUID。

对于 MySQL,将您的 属性 放在 changeSet 标记之前:

    <property name="u_id" value="uuid()" dbms="mysql"/>

然后

    <column name="ID" type="varchar(255)" valueComputed="${u_id}"/>

注意:这里用的是valueComputed,不是defaultValueComputed

正如 Rammgarot 指出的那样,由于我们正在处理需要具有唯一值的列,因此我们应该使用 valueComputed 而不是 defaultValueComputed

任何提供的答案都没有帮助我 在 MySQL 的情况下,但我能够使用另一种方法解决它 - 使用触发器。

<changeSet author="nberezovski" id="1">
        <createTable tableName="test">
            <column name="id" type="varchar(255)">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="description" type="varchar(255)">
            ...
        </createTable>
</changeSet>

<changeSet author="nberezovski" id="2">
        <sql splitStatements="false">
            CREATE TRIGGER insert_test
            BEFORE INSERT ON test
            FOR EACH ROW
            BEGIN
            IF (NEW.id IS NULL) THEN
            SET NEW.id = UUID();
            END IF;
            END;
        </sql>
</changeSet>

之后,每次手动插入 description MySQL 的值都会自动为我生成一个 id。例如:

insert into test(description) values('some description');

该方法还有助于使用 loadData

加载数据