今天在一个博客看到的关于引入mybatis的插件actable实现自动创建或者更新表,然后我就照着他的博客做了,但还是踩了很多坑,因为很多东西他都没有说清楚。很无奈,下面贴上我自己的代码。这个插件目前只支持mysql。

首先需要引入三个依赖,第一个依赖是ACtable的依赖,其他两个是支持它的依赖(原博主只丢出了一个依赖,我在这踩了个坑,一直报错bean无法注入):

pom.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!--增加A.Ctable开源框架,仅限于mysql数据库-->
<dependency>
<groupId>com.gitee.sunchenbin.mybatis.actable</groupId>
<artifactId>mybatis-enhance-actable</artifactId>
<version>1.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>

在springboot的配置文件中加入ACtable的配置:

application.properties:
1
2
3
4
5
6
7
8
#当mybatis.table.auto=create时,系统启动后,会将所有的表删除掉,然后根据model中配置的结构重新建表,该操作会破坏原有数据。
#当mybatis.table.auto=update时,系统会自动判断哪些表是新建的,哪些字段要修改类型等,哪些字段要删除,哪些字段要新增,该操作不会破坏原有数据。
#当mybatis.table.auto=none时,系统不做任何处理。
mybatis.table.auto=update
#mybatis.model.pack这个配置是用来配置要扫描的用于创建表的对象的包名
mybatis.model.pack=com.xiangzhang.entity (实体类的包名)
#数据库为mysql
mybatis.database.type=mysql

然后就是在目录下创建两个config配置类,我的目录结构如下:
在这里插入图片描述
我们需要创建的类是,MybatisTableConfig类和MybatisMapperScannerConfig类,具体代码如下(原博主并没有贴出需要导入的类,我又在这踩了个坑)

MybatisTableConfig:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.xiangzhang.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration
@ComponentScan(basePackages = {"com.gitee.sunchenbin.mybatis.actable.manager.*"})
public class MybatisTableConfig {

@Value("${spring.datasource.driverClassName}")
private String driver;

@Value("${spring.datasource.url}")
private String url;

@Value("${spring.datasource.username}")
private String username;

@Value("${spring.datasource.password}")
private String password;

@Bean
public PropertiesFactoryBean configProperties() throws Exception{
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
propertiesFactoryBean.setLocations(resolver.getResources("classpath*:application.properties"));
return propertiesFactoryBean;
}

@Bean
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setMaxActive(30);
dataSource.setInitialSize(10);
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestOnBorrow(true);
return dataSource;
}

@Bean
public DataSourceTransactionManager dataSourceTransactionManager() {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource());
return dataSourceTransactionManager;
}

@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws Exception{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:com/gitee/sunchenbin/mybatis/actable/mapping/*/*.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.xiangzhang.entity.*");
return sqlSessionFactoryBean;
}

}
MybatisMapperScannerConfig:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.xiangzhang.config;

import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@AutoConfigureAfter(MybatisTableConfig.class)
public class MyBatisMapperScannerConfig {

@Bean
public MapperScannerConfigurer mapperScannerConfigurer() throws Exception{
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.xiangzhang.mapper.*;com.gitee.sunchenbin.mybatis.actable.dao.*");
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
return mapperScannerConfigurer;
}

}

com.xiangzhang.entity是实体类的包名, com.xiangzhang.mapper是实现注解方式的SQL接口
最后就是实体类啦,我在这里使用了lombok的Data注解,省去了getter和setter:

User:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.xiangzhang.entity;

import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
import com.gitee.sunchenbin.mybatis.actable.command.BaseModel;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant;
import lombok.Data;

@Data
@Table(name = "hero") //表名
public class User extends BaseModel {
/**
* 属性上的注解定义了创建表时的各个字段的属性
*/
@Column(name = "id",type = MySqlTypeConstant.INT,length = 11,isKey = true,isAutoIncrement = true)
private int id;

@Column(name = "name",type = MySqlTypeConstant.VARCHAR,length = 111)
private String name;

@Column(name = "hp",type = MySqlTypeConstant.DOUBLE,length = 16,decimalLength = 2)
private double hp;

@Column(name = "damage",type = MySqlTypeConstant.DOUBLE,length = 16,decimalLength = 2)
private double damage;
}