通过代码生成器可以根据数据库中的实体生成对应的po、mapper、service、controller层代码,可以大大提高开发效率。代码生成器的核心是AutoGenerator类中的execute方法,文章将从AutoGenerator类讲起
核心类AutoGenerator.java
public class AutoGenerator {
private static final Logger logger = LoggerFactory.getLogger(AutoGenerator.class);
protected ConfigBuilder config;
protected InjectionConfig injectionConfig;
private DataSourceConfig dataSource;
private StrategyConfig strategy;
private PackageConfig packageInfo;
private TemplateConfig template;
private GlobalConfig globalConfig;
private AbstractTemplateEngine templateEngine;
public void execute() {
logger.debug("==========================准备生成文件...==========================");
if (null == this.config) {
this.config = new ConfigBuilder(this.packageInfo, this.dataSource, this.strategy, this.template, this.globalConfig);
if (null != this.injectionConfig) {
this.injectionConfig.setConfig(this.config);
}
}
if (null == this.templateEngine) {
this.templateEngine = new VelocityTemplateEngine();
}
this.templateEngine.init(this.pretreatmentConfigBuilder(this.config)).mkdirs().batchOutput().open();
logger.debug("==========================文件生成完成!!!==========================");
}
}
查看AutoGenerator
类源码发现,自动生成代码的核心就是创建DataSourceConfig
,InjectionConfig
,StrategyConfig
,PackageConfig
,TemplateConfig
, GlobalConfig
配置类,在execute
方法中将根据这些配置为我们生成代码
创建DataSourceConfig类
private static DataSourceConfig buildDataSourceConfig() {
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(URL);
// dsc.setSchemaName("public");
dsc.setDriverName(DRIVER_NAME);
dsc.setUsername(USERNAME);
dsc.setPassword(PASSWORD);
dsc.setTypeConvert(new MySqlTypeConvert() {
@Override
public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
//将数据库中timestamp转换成date
if ( fieldType.toLowerCase().contains( "timestamp" ) ) {
return DbColumnType.DATE;
}
return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
}
});
return dsc;
}
创建StrategyConfig类
private static StrategyConfig buildStrategyConfig() {
StrategyConfig strategy = new StrategyConfig();
// 命名规则
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// 默认生成的po类不继承,手动修改继承
//strategy.setSuperEntityClass((String) null);
// 实体是否使用Lombok插件
strategy.setEntityLombokModel(false);
// 自定义 service 父类
strategy.setSuperServiceClass("com.h2t.study.BaseService");
// 自定义 service 实现类父类
strategy.setSuperServiceImplClass("com.h2t.study.BaseServiceImpl");
// 控制层是否使用Rest风格
strategy.setRestControllerStyle(true);
return strategy;
}
这里自定义Service以及serviceImpl的父类,BaseServiceImpl
对原有的父类进行了封装,封装目的:
- 不需要在每个业务实现类中都创建Wrapper,代码更通用
- 可以对业务层进行一个统一的校验拦截,可以通过拦截
BaseServiceImpl
做一个通用的拦截校验
创建PackageConfig类
private static PackageConfig buildPackageConfig() {
PackageConfig pc = new PackageConfig();
//pc.setModuleName(scanner("模块名"));
pc.setParent(PACKAGE_NAME);
pc.setEntity("po");
pc.setXml("mapper");
pc.setController("controller");
pc.setService("service");
return pc;
}
创建GlobalConfig类
private static GlobalConfig buildGlobalConfig() {
// 全局配置
GlobalConfig gc = new GlobalConfig();
//项目所在地址
gc.setOutputDir(OUTPUT_DIR);
//注释作者
gc.setAuthor(AUTHOR);
//生成文件不打开
gc.setOpen(false);
gc.setFileOverride(true);
gc.setActiveRecord(true);
// XML 二级缓存
gc.setEnableCache(false);
//生成result map
// XML ResultMap
gc.setBaseResultMap(true);
//生成java mysql字段映射
// XML columList
gc.setBaseColumnList(true);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
// 自定义文件命名,注意 %s 会自动填充表实体属性!
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");
return gc;
}
创建InjectionConfig类
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
TemplateConfig
TemplateConfig templateConfig = new TemplateConfig();
完整代码生成器代码
public class MpGenerator {
/**
* 包名
*/
private static final String PACKAGE_NAME = "com.h2t.study";
/**
* 代码生成路径
*/
private static final String OUTPUT_DIR = "C:\\Users\\hetiantian\\Desktop\\test";
/**
* 代码注释作者
*/
private static final String AUTHOR = "hetiantian";
private static final String DRIVER_NAME = "com.mysql.cj.jdbc.Driver";
private static final String HOST = "localhost";
private static final String PORT = "3306";
/**
* 数据库信息
*/
private static final String DATABASE = "test";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
private static final String URL = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE
+ "?characterEncoding=UTF8&serverTimezone=UTC";
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
mpg.setGlobalConfig(buildGlobalConfig());
// 数据源配置
mpg.setDataSource(buildDataSourceConfig());
// 包配置
mpg.setPackageInfo(buildPackageConfig());
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
//不生成mapper xml文件
//templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
mpg.setStrategy(buildStrategyConfig());
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
/**
* 全局构造配置类
*
* @return
* */
private static GlobalConfig buildGlobalConfig() {
// 全局配置
GlobalConfig gc = new GlobalConfig();
//项目所在地址
gc.setOutputDir(OUTPUT_DIR);
//注释作者
gc.setAuthor(AUTHOR);
//生成文件不打开
gc.setOpen(false);
gc.setFileOverride(true);
gc.setActiveRecord(true);
// XML 二级缓存
gc.setEnableCache(false);
//生成result map
// XML ResultMap
gc.setBaseResultMap(true);
//生成java mysql字段映射
// XML columList
gc.setBaseColumnList(true);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
// 自定义文件命名,注意 %s 会自动填充表实体属性!
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");
return gc;
}
/**
* 数据库配置信息
*
* @return
* */
private static DataSourceConfig buildDataSourceConfig() {
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(URL);
// dsc.setSchemaName("public");
dsc.setDriverName(DRIVER_NAME);
dsc.setUsername(USERNAME);
dsc.setPassword(PASSWORD);
dsc.setTypeConvert(new MySqlTypeConvert() {
@Override
public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
//将数据库中timestamp转换成date
if ( fieldType.toLowerCase().contains( "timestamp" ) ) {
return DbColumnType.DATE;
}
return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
}
});
return dsc;
}
private static PackageConfig buildPackageConfig() {
PackageConfig pc = new PackageConfig();
//pc.setModuleName(scanner("模块名"));
pc.setParent(PACKAGE_NAME);
pc.setEntity("po");
pc.setXml("mapper");
pc.setController("controller");
pc.setService("service");
return pc;
}
private static StrategyConfig buildStrategyConfig() {
StrategyConfig strategy = new StrategyConfig();
// 命名规则
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// 默认生成的po类不继承,手动修改继承
//strategy.setSuperEntityClass((String) null);
// 实体是否使用Lombok插件
strategy.setEntityLombokModel(false);
// 自定义 service 父类
strategy.setSuperServiceClass("com.h2t.study.BaseService");
// 自定义 service 实现类父类
strategy.setSuperServiceImplClass("com.h2t.study.BaseServiceImpl");
// 控制层是否使用Rest风格
strategy.setRestControllerStyle(true);
return strategy;
}
}
所需依赖
com.baomidou
mybatis-plus-boot-starter
3.0.7
com.baomidou
mybatis-plus-generator
3.1.2
mysql
mysql-connector-java
6.0.6
org.freemarker
freemarker
2.3.23
目前代码生成器的不足
- 生成的po自动会继承Model类
- 生成的po类缺少
@TableName
、@TableField
等注解与数据库字段进行映射
这些不足需要手动进行修改。聪明的网友如果知道如果修改,请一定要告诉我!!!
最后附:完整项目地址