用 xbatis-ddl-auto 1.0.1 从实体元数据自动生成数据库表

2026-08-01 37 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

在 MyBatis 项目里,实体类和数据库表结构通常由两套流程维护:开发者修改 Java 字段,再手工编写建表或变更 SQL。xbatis-ddl-auto 1.0.1 提供了另一种选择:复用 xbatis 已经解析好的实体元数据,根据 @Table@TableId@TableField@ColumnDefinition 等注解生成并执行 DDL。

它试图提供接近 JPA ddl-auto=create/update 的开发体验,但不要求项目引入 JPA 或 Hibernate。对于已经使用 xbatis 的应用,这意味着实体映射和自动建表可以基于同一套元数据,减少重复声明。

为什么复用实体元数据很重要

自动建表工具最容易出现的问题,不是不会生成 CREATE TABLE,而是它对实体类的理解与 ORM 不一致。

例如,ORM 将 createdAt 映射到 created_at,DDL 工具却创建了 createdAt;或者 ORM 忽略了某个临时字段,DDL 工具仍然为它创建列。这样的偏差会让应用启动成功,却在第一次读写时失败。

xbatis-ddl-auto 的关键思路是复用 xbatis 的注解解析结果:

  • @Table 确定实体对应的表。
  • @TableId 标识主键字段。
  • @TableField 描述普通字段及其列映射。
  • @ColumnDefinition 补充列类型、长度或数据库约束等定义。

因此,自动 DDL 不需要再维护一份独立的实体扫描规则。字段重命名、主键声明和列定义仍然集中在实体类中。

create 与 update 解决的是不同问题

接近 JPA ddl-auto 的体验,并不意味着所有环境都应该开启同一种策略。

create 更适合一次性测试库、集成测试和可随时重建的本地数据库。它的核心价值是快速得到与当前实体匹配的全新结构,但也通常意味着已有表或数据可能被重建。启用前必须确认具体版本的执行行为。

update 更适合保留现有结构并补充变化的开发环境。不过,“更新结构”并不等于“可以无风险地完成任意数据库迁移”。增加可空列相对直接,删除列、缩短字符串长度、修改字段类型、增加非空约束则可能导致数据丢失或启动失败。

生产环境还需要考虑:

  • 多个应用实例是否会同时执行 DDL。
  • 数据库账号是否应拥有 CREATEALTERDROP 权限。
  • 大表执行 ALTER TABLE 是否会持锁或阻塞业务请求。
  • 自动推断的变更是否经过审计并具备回滚方案。

因此,更稳妥的边界是:在开发和测试环境使用自动 DDL 提高迭代速度,在生产环境使用 Flyway、Liquibase 或经过评审的 SQL 迁移脚本。

可以这样组织实体定义

下面是一个可改造的 xbatis 实体示例。注解包名和 @ColumnDefinition 的具体参数形式需要按照项目使用的 xbatis 版本补齐,但字段设计展示了自动 DDL 所需的核心元数据。

package com.example.account;

import java.time.LocalDateTime;

// 请由 IDE 根据项目中的 xbatis 版本补齐注解 import。
@Table("app_user")
public class UserEntity {

    @TableId
    private Long id;

    @TableField("username")
    @ColumnDefinition("varchar(64) not null")
    private String username;

    @TableField("email")
    @ColumnDefinition("varchar(255) not null")
    private String email;

    @TableField("enabled")
    @ColumnDefinition("boolean not null")
    private Boolean enabled;

    @TableField("created_at")
    @ColumnDefinition("timestamp not null")
    private LocalDateTime createdAt;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public LocalDateTime getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }
}

这类实体大致表达了以下数据库结构,但实际 SQL 会受到数据库方言、主键策略和 xbatis-ddl-auto 解析规则影响:

CREATE TABLE app_user (
    id BIGINT NOT NULL,
    username VARCHAR(64) NOT NULL,
    email VARCHAR(255) NOT NULL,
    enabled BOOLEAN NOT NULL,
    created_at TIMESTAMP NOT NULL,
    PRIMARY KEY (id)
);

接入 1.0.1 时,应使用该版本文档提供的依赖坐标和配置项,不要直接套用其他 ORM 的 ddl-auto 配置键。一个合理的环境策略可以抽象为:

# 配置名称是接入模板,请替换成 xbatis-ddl-auto 1.0.1 的实际属性名。
ddl-auto:
  enabled: true
  mode: update
# 生产环境策略:关闭应用启动时自动修改表结构。
ddl-auto:
  enabled: false

重点不在配置键长什么样,而在于通过环境配置明确控制 DDL 是否执行,避免把开发环境的自动建表行为直接带入生产。

启用前先做一次结构基线

即使只在测试环境使用 update,也建议在首次启用前导出结构。以 MySQL 为例,可以复制并修改下面的命令:

export DB_HOST=127.0.0.1
export DB_PORT=3306
export DB_NAME=demo
export DB_USER=demo_user

mysqldump \
  --host="$DB_HOST" \
  --port="$DB_PORT" \
  --user="$DB_USER" \
  --password \
  --no-data \
  --routines \
  --triggers \
  "$DB_NAME" > schema-before-ddl-auto.sql

应用启动后,再导出一次结构并比较:

mysqldump \
  --host="$DB_HOST" \
  --port="$DB_PORT" \
  --user="$DB_USER" \
  --password \
  --no-data \
  --routines \
  --triggers \
  "$DB_NAME" > schema-after-ddl-auto.sql

diff -u schema-before-ddl-auto.sql schema-after-ddl-auto.sql

这一步可以快速发现意外的列类型变化、默认值变化或表结构重建。若工具支持只生成 SQL、不立即执行,也应优先在 CI 中审查生成结果。

落地时检查这几件事

引入 xbatis-ddl-auto 1.0.1 前,可以按下面的清单控制风险:

  • 确认所有实体都使用一致的 @Table 和字段映射规则。
  • 检查主键生成方式是否与目标数据库兼容。
  • 为字符串长度、非空约束和默认值提供明确的列定义。
  • 在空数据库上验证 create 结果,并运行完整集成测试。
  • 在带有真实结构副本的数据库上验证 update,检查生成的 DDL。
  • 避免让多个应用实例在同一时间执行结构更新。
  • 生产数据库使用低权限应用账号,并关闭启动时自动 DDL。
  • 对删除列、字段改名和类型收窄继续使用显式迁移脚本。

xbatis-ddl-auto 的价值在于消除开发阶段重复维护表结构的机械工作,而不是替代所有数据库变更管理。把它用于可重建环境,并为生产变更保留审查、备份和回滚流程,才能同时获得开发效率与结构安全。


相关推荐