xbatis-ddl-auto 1.0.1:不用 JPA,也能从 xbatis 实体自动建表

2026-07-03 35 预计阅读时间: 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.

预计阅读时间:8 分钟

xbatis-ddl-auto 1.0.1 的核心变化很直接:它把 xbatis 实体上的表、字段、主键等元数据拿来生成并执行数据库 DDL,让使用 xbatis 的项目获得接近 JPA ddl-auto=create/update 的体验,但不需要引入 JPA 或 Hibernate 这一整套运行时。

这类工具解决的是一个很具体的问题:业务代码里的实体类已经写了 @Table@TableId@TableField@ColumnDefinition,数据库表结构却还要手写 SQL、维护迁移脚本、同步字段变更。xbatis-ddl-auto 试图把这段重复劳动自动化,尤其适合开发环境、测试环境、原型系统和内部工具。

它复用的是 xbatis 的实体元数据

从摘要看,xbatis-ddl-auto 并不是另起一套注解体系,而是复用 xbatis 已有的实体注解解析结果。

这点很重要。开发者不需要同时维护两套模型:

  • @Table 描述实体对应的表;
  • @TableId 描述主键字段;
  • @TableField 描述普通字段;
  • @ColumnDefinition 描述更细的列定义。

换句话说,实体类既服务于 ORM 映射,也可以作为 DDL 生成的输入。对于已经采用 xbatis 的项目,迁移成本会比引入 Hibernate 的 schema generation 低得多。

一个典型实体可以这样组织,下面示例用于说明实践方式,具体包名和注解属性请以项目实际依赖版本为准:

package com.example.demo.entity;

import cn.xbatis.db.annotations.Table;
import cn.xbatis.db.annotations.TableField;
import cn.xbatis.db.annotations.TableId;
import cn.xbatis.db.annotations.ColumnDefinition;

import java.time.LocalDateTime;

@Table("sys_user")
public class UserEntity {

    @TableId
    @ColumnDefinition("bigint primary key")
    private Long id;

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

    @TableField("email")
    @ColumnDefinition("varchar(128)")
    private String email;

    @TableField("created_at")
    @ColumnDefinition("datetime 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 LocalDateTime getCreatedAt() {
        return createdAt;
    }

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

需要改造的地方通常集中在实体类:表名、列名、主键、列类型、是否允许为空、默认值等信息要表达清楚。否则自动 DDL 工具只能根据 Java 类型做推断,而推断往往不如显式定义可靠。

create/update 的体验,不等于生产环境随便跑

摘要提到它提供接近 ddl-auto=create/update 的体验。这个定位很清晰:

  • create 更适合临时库、测试库、CI 环境;
  • update 更适合开发阶段的增量字段同步;
  • 生产环境仍然应该保留审核、备份、回滚和变更记录。

自动 DDL 最容易被低估的风险,是“它确实能跑”。一旦它具备执行权限,错误的实体注解、误删字段、类型收窄、默认值变化,都可能变成真实的数据库结构变更。

更稳妥的做法是把自动执行限制在非生产 profile 中。可以这样实践:

# application-dev.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo_dev?useSSL=false&serverTimezone=UTC
    username: root
    password: root

xbatis:
  ddl-auto:
    enabled: true
    mode: update
    entity-packages:
      - com.example.demo.entity
# application-prod.yml
xbatis:
  ddl-auto:
    enabled: false

上面的配置是“可以这样实践”的示意,具体配置项名称需要按 xbatis-ddl-auto 1.0.1 的实际文档调整。原则是固定的:开发环境可以自动建表,生产环境默认关闭。

一个最小可改造的 Spring Boot 接入示例

如果你的项目已经是 Spring Boot + xbatis,可以按下面方式搭一个最小验证工程。依赖坐标请替换为你实际使用的 xbatis 与 xbatis-ddl-auto 版本。

<!-- pom.xml 片段:请按实际发布坐标调整 groupId/artifactId/version -->
<dependencies>
    <dependency>
        <groupId>cn.xbatis</groupId>
        <artifactId>xbatis-spring-boot-starter</artifactId>
        <version>请替换为项目使用版本</version>
    </dependency>

    <dependency>
        <groupId>cn.xbatis</groupId>
        <artifactId>xbatis-ddl-auto</artifactId>
        <version>1.0.1</version>
    </dependency>

    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

本地用 Docker 起一个 MySQL,便于反复验证建表结果:

docker run --name xbatis-ddl-demo \
  -e MYSQL_ROOT_PASSWORD=root \
  -e MYSQL_DATABASE=demo_dev \
  -p 3306:3306 \
  -d mysql:8.0

# 查看容器是否启动
docker ps --filter name=xbatis-ddl-demo

应用启动后,可以检查表是否生成:

docker exec -it xbatis-ddl-demo mysql -uroot -proot demo_dev -e "show tables;"
docker exec -it xbatis-ddl-demo mysql -uroot -proot demo_dev -e "show create table sys_user\G"

如果你在实体里新增字段,例如增加 status

@TableField("status")
@ColumnDefinition("tinyint not null default 1")
private Integer status;

再次启动应用后,update 模式理论上应该尝试补齐数据库列。验证命令:

docker exec -it xbatis-ddl-demo mysql -uroot -proot demo_dev -e "desc sys_user;"

这套验证流程的价值在于:你可以在接入前明确看到实体注解如何影响真实 DDL,而不是只相信启动日志。

适合放在哪里用

xbatis-ddl-auto 的边界应该划清楚。它适合让开发者快速从实体得到表结构,也适合让测试环境自动准备 schema。它不适合替代所有数据库变更管理。

建议采用时做一个小清单:

  • 只在 devtestci 等环境开启自动执行;
  • 实体字段尽量使用 @ColumnDefinition 明确数据库类型;
  • 每次升级 xbatis-ddl-auto 前,在临时库跑一遍 DDL 验证;
  • 对生产库继续使用 Flyway、Liquibase 或人工审核 SQL;
  • 对删除字段、修改字段类型、索引变化保持人工确认。

如果团队已经在用 xbatis,这个工具的吸引力在于“顺手”:它利用现有实体元数据,把建表这件事从手工 SQL 推向自动化。但自动化 DDL 的权限很重,越接近生产环境,越要把开关、日志、审核和回滚路径准备好。


相关推荐