在 MyBatis 技术栈中,实体类与数据库表结构通常由开发者分别维护。字段一多,新增列、调整类型、补索引就容易出现不同步。xbatis-ddl-auto 复用 xbatis 已经解析出的实体元数据,根据实体类生成并执行 DDL,让项目获得接近 JPA ddl-auto=create/update 的体验,同时不需要引入 JPA 或 Hibernate。
1.0.2 延续了这一定位。现有更新摘要只显示“增加 SYN...”的截断信息,因此具体新增能力和兼容范围应以该版本发布说明为准,不宜仅凭缩写推断。
核心价值不是少写 SQL,而是复用同一份元数据
xbatis 实体已经通过 @Table、@TableId、@TableField、@ColumnDefinition 等注解描述表名、主键、字段及列定义。自动建表组件直接复用这些解析结果,可以减少两套映射规则之间的偏差:
- Java 属性改了名称,DDL 仍使用旧列名;
- 字段长度在实体注解和迁移脚本中不一致;
- 新增实体后忘记创建对应数据表;
- 测试环境需要人工执行一批初始化 SQL。
它更适合解决开发、测试和临时环境的结构初始化问题。对生产数据库而言,“能自动执行”并不等于“应该无审核执行”,尤其是字段缩短、类型转换、删除列和大表加索引等操作。
从实体定义到建表的实践方式
下面是一个示意实体。由于不同 xbatis 版本的包名、注解参数和主键策略可能不同,运行前需要按照项目当前依赖调整 import 和注解参数;示例重点是展示元数据应如何集中表达。
package com.example.account;
// 请替换为项目实际使用的 xbatis 注解包。
import com.example.xbatis.Table;
import com.example.xbatis.TableId;
import com.example.xbatis.TableField;
import com.example.xbatis.ColumnDefinition;
@Table(name = "app_user")
public class UserEntity {
@TableId
@ColumnDefinition("BIGINT NOT NULL")
private Long id;
@TableField(name = "email")
@ColumnDefinition("VARCHAR(255) NOT NULL")
private String email;
@TableField(name = "display_name")
@ColumnDefinition("VARCHAR(100) NOT NULL")
private String displayName;
@TableField(name = "created_at")
@ColumnDefinition("TIMESTAMP NOT NULL")
private java.time.LocalDateTime createdAt;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public java.time.LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(java.time.LocalDateTime createdAt) {
this.createdAt = createdAt;
}
}
依赖版本建议集中在 Maven 属性中,避免多个模块引用不同版本。下面的坐标和配置键是接入模板,具体 artifactId、最新版本号及启用参数需要替换为项目采用的官方定义。
<properties>
<xbatis.version>项目当前的-xbatis-版本</xbatis.version>
<xbatis-ddl-auto.version>1.0.2</xbatis-ddl-auto.version>
</properties>
<dependencies>
<dependency>
<groupId>请替换为官方-groupId</groupId>
<artifactId>xbatis-ddl-auto</artifactId>
<version>${xbatis-ddl-auto.version}</version>
</dependency>
</dependencies>
配置策略可以按环境拆分。以下 YAML 只表达推荐的控制方式,并不代表 1.0.2 的真实配置键;接入时应映射到该组件实际提供的配置项。
# application-dev.yml:开发库允许根据实体更新结构
app:
ddl-auto:
enabled: true
mode: update
---
# application-prod.yml:生产默认禁用自动执行
spring:
config:
activate:
on-profile: prod
app:
ddl-auto:
enabled: false
mode: validate
如果组件没有 validate 或“只生成不执行”模式,也可以在 CI 中启动一个临时数据库,执行自动建表后导出结构,再对结果进行评审。
用临时数据库验证生成结果
以 MySQL 8 为例,可以先启动一次性数据库,让应用对隔离环境执行 DDL。下面的命令可直接运行,前提是本机已经安装 Docker:
docker run --rm -d \
--name xbatis-ddl-test \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=demo \
-p 3307:3306 \
mysql:8.0
until docker exec xbatis-ddl-test \
mysqladmin ping -uroot -proot --silent; do
sleep 2
done
mysql -h127.0.0.1 -P3307 -uroot -proot \
-e "SHOW TABLES FROM demo;"
将应用的数据源指向 jdbc:mysql://127.0.0.1:3307/demo,启动应用并等待自动 DDL 完成,然后导出结构:
mysqldump -h127.0.0.1 -P3307 -uroot -proot \
--no-data --skip-comments demo > generated-schema.sql
git diff --no-index expected-schema.sql generated-schema.sql || true
这个流程适合放进 CI:每次修改实体后都重新生成 schema,并与仓库中经过审核的基线比较。这样既利用自动 DDL 提高反馈速度,又保留结构变更的可见性。
上生产前需要划清边界
自动建表最稳妥的使用范围是本地开发、集成测试、演示环境和可随时重建的数据库。生产环境建议至少落实以下检查:
- 固定 xbatis 与
xbatis-ddl-auto的版本,不使用浮动版本; - 在与生产相同类型和主版本的临时数据库上验证 DDL;
- 确认组件对已有列、默认值、索引和约束的比较规则;
- 对字段删除、字段缩短和类型转换进行人工审核;
- 大表执行
ALTER TABLE前评估锁表时间和磁盘空间; - 保留 schema 备份、迁移记录和明确的回滚方案;
- 升级到 1.0.2 前核对完整变更日志,特别确认摘要中被截断的 “SYN...” 功能及其数据库兼容性。
xbatis-ddl-auto 的合理定位不是取代所有数据库迁移工具,而是把实体元数据转化为更快的结构反馈。开发环境可以使用 create/update 式体验,生产环境则应继续保留审计、备份和发布审批。这样才能同时获得自动化效率与数据库变更的可控性。