Springboot+mybatis-plus+ACTable实现自动创建表结构
本文主要介绍mybatis如何实现想hibernate一样自动创建表,以及记录下自己踩过的坑,发表于2021年12月,部分内容仅供参考,很有可能项目作者已经修复了那些问题。
Springboot+Mybatis-plus没什么好说的,重头戏在ACTable,他是一个开源依赖,仓库地址:https://gitee.com/sunchenbin/mybatis-enhance,当然也有github的,就是利用他来实现自动创建表结构
ACTable的官方文档:https://www.yuque.com/sunchenbin/actable/nfz097
使用方法
导入依赖
最新依赖请查看maven仓库:https://mvnrepository.com/artifact/com.gitee.sunchenbin.mybatis.actable/mybatis-enhance-actable
依赖基于Springboot,请先导入springboot依赖,下面的写法是按照官方文档整合Springboot来写的,
注意 :只适用于Springboot+mybatis-plus,如果使用mybatis或者springmvc的话,请查看官方文档来配置。
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.gitee.sunchenbin.mybatis.actable/mybatis-enhance-actable -->
<dependency>
<groupId>com.gitee.sunchenbin.mybatis.actable</groupId>
<artifactId>mybatis-enhance-actable</artifactId>
<version>1.5.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
</exclusion>
</exclusions>
</dependency>
配置文件
actable:
table:
#可选:update/none/create/add
auto: update
model:
#使用逗号隔开
pack: com.oldwu.entity,com.oldwu.genshin.entity,com.security.domain
database:
type: mysql
index:
#自己定义的索引前缀#该配置项不设置默认使用actable_idx_
prefix: INDEX_
unique:
#自己定义的唯一约束前缀#该配置项不设置默认使用actable_uni_
prefix: INDEX_UNIQUE_
注释都在上边了,应该一看就懂,这是官方对配置的解释:
以及,加上mybatis-plus的配置,下面这个路径是写死的,不要改:
mybatis-plus:
mapper-locations: classpath*:com/gitee/sunchenbin/mybatis/actable/mapping/*/*.xml
启动类注解
@MapperScan({"com.gitee.sunchenbin.mybatis.actable.dao.*"})
@ComponentScan(basePackages = {"com.gitee.sunchenbin.mybatis.actable.manager.*"})
此处是官方给出的配置,这边有一个坑,下面会讲到
启动项目测试
至此,配置都完成了,你需要启动项目来测试一下是否有报错
自动创建表
这个依赖利用注解的形式来完成自动创建表,类似于hibernate,非常方便,官方的注解说明在这里,我也不一一列出:https://www.yuque.com/sunchenbin/actable/ca4vsf,这边只写几个重要的东西
@Table("表名")
public class SystemLog implements Serializable {
//主键
@IsKey
//自动递增
@IsAutoIncrement
//后续不会更新这个字段,正常的使用方法请看官方文档,后面也会讲到一个坑
@IgnoreUpdate
private Long id;
//type为字段类型,name为字段名,length为字段长度,
//default为默认值,更多见官方文档
//常用的应该就这几个,如果都不需要,括号里不填就行了
@Column(type = MySqlTypeConstant.TEXT)
//不为空
@IsNotNull
//建立唯一约束
@Unique
private String receiveText;
//创建日期类型的示例,并且默认值为当前时间
@Column(type = MySqlTypeConstant.DATETIME,defaultValue = "CURRENT_TIMESTAMP")
private Date date;
}
然后启动项目测试,第一次创建表时会有中文日志输出,如果创建失败的话,项目会启动失败并且报错。这个时候就需要检查报错信息了。
关于这个自动建表依赖
目前这个依赖不支持外键的添加,所以如果要加外键,请手动添加
一些坑的记录
每种错误都不止一种原因,以下只是我碰到的
报错Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.gitee.sunchenbin.mybatis.actable.dao.system.CreateMysqlTablesMapper.findTableCountByTableName
这个错误有很多种原因,大概率是因为配置文件的问题,来说说我自己碰到的错误:
官方文档给出的配置文件是properties格式的,我自己用的时候是yml格式的,然后我把最后一行mybatis-plus.mapper-locations=classpath*:com/gitee/sunchenbin/mybatis/actable/mapping/*/*.xml
复制过去的时候,idea自动格式化,然后mybatis-plus就成了actable的子项,独立出来就好了
'com.gitee.sunchenbin.mybatis.actable.dao.common.BaseMysqlCRUDMapper'报错
有可能是因为启动类注解配置问题,你需要按照官方文档配置启动类之后再次尝试
报错Invalid bound statement (not found) NULL 空指针
类似于这样,具体记不清了,我的是因为yml配置文件中,model配置写为了数组格式:
#此为错误示范!!!
actable:
model:
- pack: com.oldwu.entity
- pack: com.security.domain
正确应该为逗号或分号分隔:
actable:
model:
pack: com.oldwu.entity,com.oldwu.genshin.entity,com.security.domain
spring包扫描的一个坑
这也是我上面启动类配置中说的一个坑,官方给出的启动类注解为:
@MapperScan("com.gitee.sunchenbin.mybatis.actable.dao.*")
@ComponentScan(basePackages = {"com.gitee.sunchenbin.mybatis.actable.manager.*"})
问题就出在@ComponentScan
上,这是包扫描的注解,稍微用过点springboot的人应该都知道,正常情况下,启动类都会放在最外层的包中,启动时,spring会去依次扫描同一级的所有子包。
如果你原来用的就是@ComponentScan
来进行包扫描,并且没有出任何问题的话,正常情况仅需在你原来的基础上加上这个要扫描的包即可。
但是,如果你原来用的是@SpringBootApplication
注解来启动的话,就会导致别的bean全都无法正常注入,也就是spring只扫描了你配置的那个包,别的类,统统没有注入,有些人访问不了自定义的controller就是这个问题。
当然解决办法也很简单,有两种,一种需要你自己配置需要扫描的包,还有一种就是:我们可以发现官方给出的包扫描路径在com
下,也就是说,如果你的启动类也在com
包下的话,spring会默认去扫描,所以,直接去掉@ComponentScan
这一行就可以了
Unique索引建立的一个bug
没有测试过index索引会不会出这个bug,就是当你的字段名为一些mysql关键字时,建索引就会sql错误,查看输出发现是建索引语句没有加反引号导致的,但是建表的时候没有任何问题,尝试在列名配置中加了反引号,但是没有用,所以目前最好不要使用关键字作为列名。
mysql8.0.24每次启动项目时都会提示正在更新表
更新的字段都和Long
和INTEGER
有关系,gitee中也有人提问了,这个问题只会在新版本的mysql中出现,如果不爽的话,就在那个列上加上注释@IgnoreUpdate
就好了
如果还有别的问题,可以去github或者gitee上的Issues
中查找有没有别人问过
分别是哔哩哔哩序号35,小米运动序号2,米友社序号13,这个是同一个账号下运行的任务