1.概念介绍
MyBatis-Plus 是一个 MyBatis 的增强工具,旨在简化开发、提高效率。它在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。MyBatis-Plus 提供了代码生成器功能,可以快速地根据数据库表结构生成 Entity(实体类)、Mapper(映射器接口)、Service(服务层接口及其实现)、Controller(控制层)等代码文件。
2.代码生成器原理
MyBatis-Plus 的代码生成器是基于 Java 的反射机制和模板引擎来实现的。它通过读取数据库中的表结构信息,然后根据预设的模板生成对应的 Java 代码文件。用户可以根据需要自定义模板,以便生成符合项目规范的代码。
3.配置Demo工程步骤
3.1 设置JDK,Maven等关联信息
我选择openjdk17,保证jdk8以上就行
3.2 重新加载maven项目
以上操作做完,基本是不会报错了,可以正常编译源代码。
3.基础配置
要使用 MyBatis-Plus 的代码生成器,首先需要引入 MyBatis-Plus 的依赖,并进行相应的配置。以下是使用 MyBatis-Plus 代码生成器的基础步骤:
-
添加依赖: 在 Maven 或 Gradle 项目的构建配置中添加 MyBatis-Plus 相关依赖。
-
数据库连接配置: 配置好数据源,确保能够正确连接到数据库。
-
创建代码生成器配置: 创建一个
AutoGenerator
对象,并设置其属性,如数据源配置、全局配置、包配置、策略配置等。 -
AutoGenerator源码:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package com.baomidou.mybatisplus.generator; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.Version; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.baomidou.mybatisplus.generator.config.PackageConfig; import com.baomidou.mybatisplus.generator.config.StrategyConfig; import com.baomidou.mybatisplus.generator.config.TemplateConfig; import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine; import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine; import java.io.Serializable; import java.util.Iterator; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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("==========================文件生成完成!!!=========================="); } protected List<TableInfo> getAllTableInfoList(ConfigBuilder config) { return config.getTableInfoList(); } protected ConfigBuilder pretreatmentConfigBuilder(ConfigBuilder config) { if (null != this.injectionConfig) { this.injectionConfig.initMap(); config.setInjectionConfig(this.injectionConfig); } List<TableInfo> tableList = this.getAllTableInfoList(config); Iterator var3 = tableList.iterator(); while(var3.hasNext()) { TableInfo tableInfo = (TableInfo)var3.next(); if (config.getGlobalConfig().isActiveRecord()) { tableInfo.setImportPackages(Model.class.getCanonicalName()); } if (tableInfo.isConvert()) { tableInfo.setImportPackages(TableName.class.getCanonicalName()); } if (config.getStrategyConfig().getLogicDeleteFieldName() != null && tableInfo.isLogicDelete(config.getStrategyConfig().getLogicDeleteFieldName())) { tableInfo.setImportPackages(TableLogic.class.getCanonicalName()); } if (StringUtils.isNotEmpty(config.getStrategyConfig().getVersionFieldName())) { tableInfo.setImportPackages(Version.class.getCanonicalName()); } boolean importSerializable = true; if (StringUtils.isNotEmpty(config.getSuperEntityClass())) { tableInfo.setImportPackages(config.getSuperEntityClass()); importSerializable = false; } if (config.getGlobalConfig().isActiveRecord()) { importSerializable = true; } if (importSerializable) { tableInfo.setImportPackages(Serializable.class.getCanonicalName()); } if (config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix()) { tableInfo.getFields().stream().filter((field) -> { return "boolean".equalsIgnoreCase(field.getPropertyType()); }).filter((field) -> { return field.getPropertyName().startsWith("is"); }).forEach((field) -> { field.setConvert(true); field.setPropertyName(StringUtils.removePrefixAfterPrefixToLower(field.getPropertyName(), 2)); }); } } return config.setTableInfoList(tableList); } public InjectionConfig getCfg() { return this.injectionConfig; } public AutoGenerator setCfg(InjectionConfig injectionConfig) { this.injectionConfig = injectionConfig; return this; } public AutoGenerator() { } public ConfigBuilder getConfig() { return this.config; } public DataSourceConfig getDataSource() { return this.dataSource; } public StrategyConfig getStrategy() { return this.strategy; } public PackageConfig getPackageInfo() { return this.packageInfo; } public TemplateConfig getTemplate() { return this.template; } public GlobalConfig getGlobalConfig() { return this.globalConfig; } public AbstractTemplateEngine getTemplateEngine() { return this.templateEngine; } public AutoGenerator setConfig(final ConfigBuilder config) { this.config = config; return this; } public AutoGenerator setDataSource(final DataSourceConfig dataSource) { this.dataSource = dataSource; return this; } public AutoGenerator setStrategy(final StrategyConfig strategy) { this.strategy = strategy; return this; } public AutoGenerator setPackageInfo(final PackageConfig packageInfo) { this.packageInfo = packageInfo; return this; } public AutoGenerator setTemplate(final TemplateConfig template) { this.template = template; return this; } public AutoGenerator setGlobalConfig(final GlobalConfig globalConfig) { this.globalConfig = globalConfig; return this; } public AutoGenerator setTemplateEngine(final AbstractTemplateEngine templateEngine) { this.templateEngine = templateEngine; return this; } public boolean equals(final Object o) { if (o == this) { return true; } else if (!(o instanceof AutoGenerator)) { return false; } else { AutoGenerator other = (AutoGenerator)o; if (!other.canEqual(this)) { return false; } else { label107: { Object this$config = this.getConfig(); Object other$config = other.getConfig(); if (this$config == null) { if (other$config == null) { break label107; } } else if (this$config.equals(other$config)) { break label107; } return false; } Object this$injectionConfig = this.injectionConfig; Object other$injectionConfig = other.injectionConfig; if (this$injectionConfig == null) { if (other$injectionConfig != null) { return false; } } else if (!this$injectionConfig.equals(other$injectionConfig)) { return false; } Object this$dataSource = this.getDataSource(); Object other$dataSource = other.getDataSource(); if (this$dataSource == null) { if (other$dataSource != null) { return false; } } else if (!this$dataSource.equals(other$dataSource)) { return false; } label86: { Object this$strategy = this.getStrategy(); Object other$strategy = other.getStrategy(); if (this$strategy == null) { if (other$strategy == null) { break label86; } } else if (this$strategy.equals(other$strategy)) { break label86; } return false; } label79: { Object this$packageInfo = this.getPackageInfo(); Object other$packageInfo = other.getPackageInfo(); if (this$packageInfo == null) { if (other$packageInfo == null) { break label79; } } else if (this$packageInfo.equals(other$packageInfo)) { break label79; } return false; } label72: { Object this$template = this.getTemplate(); Object other$template = other.getTemplate(); if (this$template == null) { if (other$template == null) { break label72; } } else if (this$template.equals(other$template)) { break label72; } return false; } Object this$globalConfig = this.getGlobalConfig(); Object other$globalConfig = other.getGlobalConfig(); if (this$globalConfig == null) { if (other$globalConfig != null) { return false; } } else if (!this$globalConfig.equals(other$globalConfig)) { return false; } Object this$templateEngine = this.getTemplateEngine(); Object other$templateEngine = other.getTemplateEngine(); if (this$templateEngine == null) { if (other$templateEngine != null) { return false; } } else if (!this$templateEngine.equals(other$templateEngine)) { return false; } return true; } } } protected boolean canEqual(final Object other) { return other instanceof AutoGenerator; } public int hashCode() { int PRIME = true; int result = 1; Object $config = this.getConfig(); result = result * 59 + ($config == null ? 43 : $config.hashCode()); Object $injectionConfig = this.injectionConfig; result = result * 59 + ($injectionConfig == null ? 43 : $injectionConfig.hashCode()); Object $dataSource = this.getDataSource(); result = result * 59 + ($dataSource == null ? 43 : $dataSource.hashCode()); Object $strategy = this.getStrategy(); result = result * 59 + ($strategy == null ? 43 : $strategy.hashCode()); Object $packageInfo = this.getPackageInfo(); result = result * 59 + ($packageInfo == null ? 43 : $packageInfo.hashCode()); Object $template = this.getTemplate(); result = result * 59 + ($template == null ? 43 : $template.hashCode()); Object $globalConfig = this.getGlobalConfig(); result = result * 59 + ($globalConfig == null ? 43 : $globalConfig.hashCode()); Object $templateEngine = this.getTemplateEngine(); result = result * 59 + ($templateEngine == null ? 43 : $templateEngine.hashCode()); return result; } public String toString() { return "AutoGenerator(config=" + this.getConfig() + ", injectionConfig=" + this.injectionConfig + ", dataSource=" + this.getDataSource() + ", strategy=" + this.getStrategy() + ", packageInfo=" + this.getPackageInfo() + ", template=" + this.getTemplate() + ", globalConfig=" + this.getGlobalConfig() + ", templateEngine=" + this.getTemplateEngine() + ")"; } }
4.快速生成代码示例
以下是一个简单的例子,展示如何配置并使用 MyBatis-Plus 代码生成器来生成实体类、Mapper 接口及 XML 文件:
package com.shanjupay.generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* <p>
* MyBatis Plus Generator 配置执行类示例
* </p>
*
* @author
* @since
*/
public class MyBatisPlusGenerator {
private static final Boolean IS_DTO = true;
/**
* <p>
* 读取控制台内容
* </p>
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator autoGenerator = new AutoGenerator();
// 全局配置
GlobalConfig globalConfig = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
//当前项目名
String projectName = "/generator";
globalConfig.setOutputDir(projectPath + projectName+"/src/main/java");
globalConfig.setAuthor("作者名字");
globalConfig.setOpen(true);
globalConfig.setIdType(IdType.ID_WORKER);
autoGenerator.setGlobalConfig(globalConfig);
// 数据源配置 需配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
// 商户服务
dataSourceConfig
.setUrl("jdbc:mysql://IP地址:端口号/mushroom_smt?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&userAffectedRows=true");
// dataSourceConfig.setSchemaName("public");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("密码");
autoGenerator.setDataSource(dataSourceConfig);
// 生成包配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("com.smt");
//如果需要手动输入模块名
packageConfig.setModuleName(scanner("模块名"));
autoGenerator.setPackageInfo(packageConfig);
// 自定义配置
InjectionConfig injectionConfig = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名
return projectPath + projectName+"/src/main/resources/mapper/" + packageConfig.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
injectionConfig.setFileOutConfigList(focList);
autoGenerator.setCfg(injectionConfig);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity-test.java");
// templateConfig.setService("templates/service.java");
// templateConfig.setController("templates/controller.java");
templateConfig.setXml(null);
autoGenerator.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setNaming(NamingStrategy.underline_to_camel);//表名映射到实体策略,带下划线的转成驼峰
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);//列名映射到类型属性策略,带下划线的转成驼峰
// strategyConfig.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
strategyConfig.setEntityLombokModel(true);//实体类使用lombok
// strategyConfig.setRestControllerStyle(true);
// strategyConfig.setSuperControllerClass("com.baomidou.ant.common.BaseController");
// 如果 setInclude() //设置表名不加参数, 会自动查找所有表
// 如需要制定单个表, 需填写参数如: strategyConfig.setInclude("user_info);
strategyConfig.setInclude("oms_order");
// strategyConfig.setSuperEntityColumns("id");
// strategyConfig.setControllerMappingHyphenStyle(true);
//自动将数据库中表名为 user_info 格式的转为 UserInfo 命名
strategyConfig.setTablePrefix(packageConfig.getModuleName() + "_");//表名映射到实体名称去掉前缀
strategyConfig.setEntityBooleanColumnRemoveIsPrefix(true);// Boolean类型字段是否移除is前缀处理
autoGenerator.setStrategy(strategyConfig);
autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
System.out.println("===================== MyBatis Plus Generator ==================");
//同时也生成dto
if (IS_DTO) {
globalConfig.setSwagger2(true);
globalConfig.setEntityName("%sDTO");
packageConfig.setEntity("dto");
}
autoGenerator.execute();
System.out.println("================= MyBatis Plus Generator Execute Complete ==================");
}
}
5.运行Main方法
对main方法中的数据库连接协议进行修改,更换成自己的ip和端口以及mysql的root账户密码
运行main方法,控制台等待输入,输入字符串“product”,会生成一个product的包名
6.运行结果分析
符合预期,没报错就行~
只是生成了太多没必要的表结构,整个数据库都被他拉出来遍历循环,生成的文件结构与自己正在开发包结构不一致,类文件缺少或者多余,接口层连个空的接口都没有,实现层也没有,控制层与自己正在开发的返回值类型也不一样,开始怀疑用代码生成器的必要性,效率太低了。确实如此,按照这个源码来做代码生成的工作,只会更累。
7.小结
我上面贴出来了两处代码,是本专栏要改的重点,先了解一下他的作用,从main方法中就可以看出来,MyBatisPlusGenerator.java类主要是提供了一些策略配置,比如包名的生成策略,数据库表的选择,是否打开文件夹,表名映射到实体策略,带下划线或者是驼峰命名策略,模板引擎选择,布尔类型是否使用Is开头(阿里巴巴规范中规定布尔类型的数据,无论是boolean还是Boolean都不准使用isXXX来命名,否则会引起RPC框架序列化异常),等等各种策略配置,com.baomidou.mybatisplus.generator.AutoGenerator.java类是负责与模板引擎FreeMarker交互并生成代码文件。
本篇介绍了如何导入demo工程到Idea中,以及如何解决编译环境的问题,简单介绍了MybatisPlus代码生成器工作原理,以及其中比较重要的两个类文件,介绍是后期在这个基础上进行修改,而不是重新开发。
标签:代码生成,return,com,other,Plus,MyBatis,import,null,config From: https://blog.csdn.net/Ta20220617/article/details/143714652