Mybatis-Plus 适配不同数据库的 TableId 自增主键
在业务需求中,有时候需要一套前台适配两个不同的数据库(如 Oracle 和 MySQL),实现相同的功能。为此,后端代码需要能够同时兼容这两种数据库,通过配置文件的切换来实现数据库的切换。注意,这不是多数据源的问题,而是同一套代码适应不同数据库的问题。
问题背景
Oracle 和 MySQL 的语法有区别,因此使用 Mybatis-Plus 框架来处理。在这种情况下,主键生成策略是一个需要解决的首要问题。
实体类的异同
在建表时,尽量保持两个数据库的表名和字段一致,所以可以使用相同的@TableName注解。然而,由于 Oracle 和 MySQL 的主键生成策略不一致,在使用 @TableId 注解时会有问题。
Oracle 数据库
Oracle 没有主键自增功能,如果要实现自增,只能通过序列来实现。在实体类中,通过@KeySequence注解设置序列,然后在主键上通过@TableId(value = "id", type = IdType.INPUT)来实现。
MySQL 数据库
MySQL 可以直接在创建表时设置主键自增,然后在实体类的主键上添加@TableId(value = "id", type = IdType.AUTO)注解即可。
产生的问题
在一套代码中如何兼容两个数据库呢?因为主键是在编译过程中就已经确定了,所以很难通过判断来自动改变注解中 type 的类型。
解决方案
前面提到可以通过切换配置文件来实现数据库的切换,那么同样也可以通过配置文件来实现主键自增策略的切换。在application.properties中进行全局配置:
# MySQL
mybatis-plus.global-config.db-config.id-type=auto
# Oracle
mybatis-plus.global-config.db-config.id-type=input
这样就可以在全局配置后,主键中的 type 去掉即可。但是这也带来了新的问题,如果某个表没有自增主键,只有业务主键,全局配置的自增策略会影响到保存。
具体实现
当表没有自增主键时,可以在实体类注解@TableId(value = "id", type = IdType.INPUT)中设置type为INPUT,这样可以用局部覆盖全局配置。
解释 IdType 的各个类型
- AUTO: 数据库 ID 自增
- INPUT: 用户输入 ID
- ID_WORKER: 全局唯一 ID (使用 Twitter 的 Snowflake 算法)
- UUID: 全局唯一 ID (使用 UUID)
- NONE: 该类型为未设置主键类型
总结
如果不是必要情况,最好使用业务主键,这样在后续迁移代码或迁移数据库时会相对方便。
通过上述方法,可以有效地解决 Mybatis-Plus 在不同数据库中主键生成策略的适配问题,使得同一套代码能够兼容 Oracle 和 MySQL 数据库,实现数据库的切换。

浙公网安备 33010602011771号