本文包含两种方式的代码自动生成方法:
一种是通过配置文件xml来配置完成,即mybatis-generator
的方式,这种方式可以单独写一个代码生成的项目也可以集成在当前要生成代码的项目中,如果仅通过配置文件的话生成的代码不包含controller和service,需要另外添加代码来配置生成;
另一种是通过Mybatis-Plus
代码生成器来实现,AutoGenerator是Mybatis-Plus的代码生成器,通过AutoGenerator可以快速生成Entity、Mapper、Mapper XML、Service、Controller等各个模块的代码,极大的提升了开发效率。
一、MyBatis的代码生成器工具(mybatis-generator)
1、创建SpringBoot工程项目,并创建controller、entity、mapper、service目录
2、添加pom.xml配置文件,并修改pom.xml文件
<!-- 添加依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>cn.ipokerface</groupId>
<artifactId>mybatis</artifactId>
<version>1.6.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--修改build结构,完成mybatis-generator配置 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>mybatis generator</id>
<phase>package</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<!--允许移动生成的文件-->
<verbose>true</verbose>
<overwrite>false</overwrite>
<configurationFile>
src/main/resources/mybatis-generator.xml
</configurationFile>
</configuration>
</plugin>
</plugins>
</build>
3、配置application.properties文件,添加数据源配置
4、src/main/resources文件夹下添加配置文件mybatis-generator.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 引入配置文件 -->
<properties resource="application.properties"/>
<!-- 指定数据库连接驱动jar地址 -->
<classPathEntry
location="C:\Users\yangjia\.m2\repository\mysql\mysql-connector-java\8.0.21\mysql-connector-java-8.0.21.jar /" />
<!-- 一个数据库一个context -->
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 生成的pojo,将implements Serializable -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
<!-- 注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true" /><!-- 是否取消注释 -->
<property name="suppressDate" value="true" /> <!-- 是否生成注释代时间戳 -->
</commentGenerator>
<!-- 数据库链接URL、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/database"
userId="root"
password="long321">
<property name="serverTimezone" value="UTC"/>
</jdbcConnection>
<!-- 类型转换 -->
<javaTypeResolver>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer true,把JDBC DECIMAL
和 NUMERIC 类型解析为java.math.BigDecimal -->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 生成model模型,对应的包路径,以及文件存放路径(targetProject),targetProject可以指定具体的路径,如./src/main/java,
也可以使用“MAVEN”来自动生成,这样生成的代码会在target/generatord-source目录下 -->
<javaModelGenerator targetPackage="com.debt.rmp.entity"
targetProject="src/main/java">
<!--是否对model添加构造函数-->
<property name="constructorBased" value="false" />
<!-- 是否允许子包 -->
<property name="enableSubPackages" value="false" />
<!-- 建立的model对象是否不可变,即没有setter方法-->
<property name="immutable" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--对应的mapper.xml文件 -->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 对应的Mapper接口类文件 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.debt.rmp.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 列出要生成代码的所有表,这里配置的是不生成Example文件 -->
<!-- schema即为数据库名 tableName为对应的数据库表 domainObjectName是要生成的实体类 enable*ByExample
是否生成 example类 -->
<table tableName="task_plan" domainObjectName="TaskPlan"
schema="database"
enableCountByExample="false" selectByExampleQueryId="false"
enableUpdateByExample="true" enableUpdateByPrimaryKey="true"
enableDeleteByExample="false" enableDeleteByPrimaryKey="false"
enableSelectByExample="true" enableInsert="true">
<!-- 忽略列,不生成bean 字段
<ignoreColumn column="FRED" />-->
<!-- 指定列的java数据类型
<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> -->
<!-- 用于指定生成实体类时是否使用实际的列名作为实体类的属性名。false是 Camel Case风格-->
<property name="useActualColumnNames" value="false" />
</table>
</context>
</generatorConfiguration>
二、Mybatis-Plus代码生成器配置
mybatis-generator仅通过配置文件无法自定义生成controller、service的代码,所以使用Mybatis-Plus来完成。AutoGenerator是Mybatis-Plus的代码生成器,通过AutoGenerator可以快速生成Entity、Mapper、Mapper XML、Service、Controller等各个模块的代码,极大的提升了开发效率。
1、添加依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!-- mybatis plus 代码生成器依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.1.0</version>
</dependency>
<!-- 代码生成器模板 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
2、修改application.yml配置文件并添加数据源信息
mybatis-plus:
global-config:
db-config:
id-type: auto
field-strategy: not_empty
table-underline: true
db-type: mysql
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath:/mapper/*.xml
3、添加MyBatisPlusConfig.java
此文件可以添加Mybasit-Plus的自带插件,如分页插件等
@Configuration
@Slf4j
@MapperScan(basePackages = "com.debt.rmp.mapper", sqlSessionTemplateRef = "ds1SqlSessionTemplate")
public class MyBatisPlusConfig {
/**
* @description: 配置分页插件
* @return: com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
log.debug("注册分页插件");
return new PaginationInterceptor();
}
/**
* @description: SQL执行效率插件
* @return: com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor
*/
@Bean
@Profile({
"test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
/**
* 逻辑删除用,3.1.1之后的版本可不需要配置该bean,但项目这里用的是3.1.0的
* @return com.baomidou.mybatisplus.core.injector.ISqlInjector
*/
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
}
4、编写代码生成器类
public class MysqlGenerator {
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
// TODO 设置用户名
gc.setAuthor("yangjia");
gc.setOpen(true);
// service 命名方式
gc.setServiceName("%sService");
// service impl 命名方式
gc.setServiceImplName("%sServiceImpl");
// 自定义文件命名,注意 %s 会自动填充表实体属性!
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
gc.setFileOverride(false);
gc.setActiveRecord(true);
// XML 二级缓存
gc.setEnableCache(false);
// XML ResultMap
gc.setBaseResultMap(true);
// XML columList
gc.setBaseColumnList(false);
mpg.setGlobalConfig(gc);
// TODO 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/database?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("long321");
mpg.setDataSource(dsc);
// TODO 包配置
PackageConfig pc = new PackageConfig();
//pc.setModuleName(scanner("模块名"));
pc.setParent("com.debt.rmp");
pc.setEntity("entity");
pc.setService("service");
pc.setServiceImpl("service.impl");
mpg.setPackageInfo(pc);
// 自定义需要填充的字段
List<TableFill> tableFillList = new ArrayList<>();
//如 每张表都有一个创建时间、修改时间
//而且这基本上就是通用的了,新增时,创建时间和修改时间同时修改
//修改时,修改时间会修改,
//虽然像Mysql数据库有自动更新,但像ORACLE的数据库就没有了,
//使用公共字段填充功能,就可以实现,自动按场景更新了。
//如下是配置
//TableFill createField = new TableFill("gmt_create", FieldFill.INSERT);
//TableFill modifiedField = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
//tableFillList.add(createField);
//tableFillList.add(modifiedField);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输入文件名称
return projectPath + "/src/main/resources/mapper/"
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.setTemplate(new TemplateConfig().setXml(null));
// 策略配置
StrategyConfig strategy = new StrategyConfig();
// 表名生成策略
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
// 排除生成的表
//strategy.setExclude(new String[]{"test"});
// 设置逻辑删除键
strategy.setLogicDeleteFieldName("deleted");
// TODO 指定生成的bean的数据库表名
strategy.setInclude("task_plan");
//strategy.setInclude(new String[] {"task_plan" });
//strategy.setSuperEntityColumns("id");
// 驼峰转连字符
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute();
}
5、可以通过自定义controller、service、mapper及xml文件模板实现代码生成定制。如自定义mapper文件的代码格式在可以在src/main/resources/templates 下创建 Mapper XML的生成模板mapper.xml.vm,以下为示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
#if(${
enableCache})
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
#end
#if(${
baseResultMap})
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
#foreach($field in ${
table.fields})
#if(${
field.keyFlag})##生成主键排在第一位
<id column="${field.name}" property="${field.propertyName}" />
#end
#end
#foreach($field in ${
table.commonFields})##生成公共字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#foreach($field in ${
table.fields})
#if(!${
field.keyFlag})##生成普通字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#end
</resultMap>
#end
#if(${
baseColumnList})
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
#foreach($field in ${
table.commonFields})
${
field.name},
#end
${
table.fieldNames}
</sql>
#end
</mapper>