MyBatis plus generator automatically generates layer Dao
In the recent issue out of the package generated, you do not need to find a configuration yeah Mybatis plus a table, so there is tidings of it ha ha ha ~
The main steps:
1. Create a new Maven project based SpringBoot, introduced its dependencies
2. refer to the official document configuration information generation package, written generate generated package of primary classes
3. Creating a new template information (if you have your own special requirements, then you can not use the default)
4. The resulting test packetizing can then start to use it -
Overall project directory structure is as follows (marked in red file manually add content):
1. Create a new Maven project based SpringBoot, pom.xml as follows (I use the mysql8.x can change the database-driven package according to the actual situation of Kazakhstan)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.imodule.product</groupId> <artifactId>product</artifactId> <version>0.0.1-SNAPSHOT</version> <name>product</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <imodule-nexus.version>0.0.1-SNAPSHOT</imodule-nexus.version> <quartz.version>2.3.0</quartz.version> <org.slf4j-version>1.6.4</org.slf4j-version> </properties> <dependencies> <!-- spring-boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <the artifactId> Boot-Spring-Starter </ the artifactId> </dependency> <dependency> <the groupId> org.springframework.boot </ the groupId> <the artifactId> Starter-Spring-Boot-Test </ the artifactId> <scope> Test </ scope> < / dependency> ! <- mybatis-PLUS automatic maintenance of the mybatis and rely mybatis-spring, and can not appear in these three springboot, avoiding version conflicts, he said: jump into the pit too -> <dependency > <groupId> com.baomidou </ groupId> <artifactId> the mybatis-PLUS-the Boot-Starter </ artifactId> <Version> 3.0.1 </ Version> </ dependency> <- HTTPS:! // mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.17</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2. The main configuration class CodeGenerator.java
The entire build process is the most talked about of these, and here I connected TiDB database (similar to MySQL, you can directly drive the mysql)
Details are: policy configuration StrategyConfig specify which database tables need to generate Dao
String [] tablename = { "PRD_BASE", "PRD_PROPERTY"}; // represented by an array of multiple tables
strategy.setInclude (tablename); // contains those tables, excude exclusion tables which include a set of excude only (if not add this default configuration of all tables in the database to generate the corresponding Dao)
Details of the two: Since we are using TiDB database, this is not our original business database, so you need from other libraries to transfer data to TiDB, sub-ah DataPipeline transmitted through, found DataPipeline have automatic functions, when it finds synchronized no time table will automatically create a primary key column as the primary key _id this table, synchronized to TiDB specified library, which gives us a problem, after _id field generated by mybatis plus generator, a property named id, remove _ prefix, when we execute the query will not find the id field, id after manually comment out this field, data and normal friends. So we changed the template files added #if judgment, that is, when the field first iteration to determine the current field is not _id, if it does not do anything, this property is not added to the total target, if not executed properly.
#if(${field.name.equals("_id")})
Statement is as follows:
#foreach ($ {$ table.fields in Field}) #if ($ {field.name.equals ( "_ ID")}) #else ... Omitted original template code information ... Private $ {Field. }} $ {field.propertyName And the propertyType; #end #end
Details of the three: template configuration StrategyConfig of setTablePrefix way, I thought that you can manually add the table prefix, which is the result of the test was found to remove the prefix meaning.
Example:
Database table name is PRD_USER
Set StrategyConfig.setTablePrefix ( "PRD_");
The last generation of entity classes: User, removed PRD_ prefix (except the entity class Mapper Service Controller will be unified remove PRD_ prefix)
If not set, then tablePrefix then generated for the entity classes PrdUser (Mapper Service Controller is similar)
Details of the four: template configuration file template TemplateConfig specified result information generated (result file which syntax reference corresponding to the engine need to be included)
templateConfig.setEntity("templates/entity.java");
templateConfig.setMapper("templates/mapper.java"); templateConfig.setXml("templates/mapper.xml"); templateConfig.setService("templates/service.java"); templateConfig.setServiceImpl("templates/serviceImpl.java"); templateConfig.setController("templates/controller.java");
Here we use TiDB, intends to use the same set of data source, which contains more than one database (the same meaning is to create multiple databases inside a database server, similar to DBLINK), the system needs to have the function of cross-database query, words are not directly generate queries database other databases
Entity template increased the library name in front of the table name (There is no parameter can be set, so we changed the template file directly in the entity.java.vm article will provide changes since the last: So we did some small template on reform file)
The original is: @TableName ( "$ {table.name}")
After changing: @tablename (. "Prd_demo table.name $ {}") // here to fix the library name (if there is need to create multiple libraries, respectively, need to change the name of the database schema name before each generation)
package cozhelim.imodule.product; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; import com.baomidou.mybatisplus.generator.config.*; import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.List; SLF4J @ public class the CodeGenerator { public static void main (String [] args) { // code generator AutoGenerator AutoGenerator new new MPG = (); // global configuration globalconfig new new globalconfig GC = (); String ProjectPath the System.getProperty = ( " user.dir "); gc.setOutputDir (ProjectPath +" / the src / main / Java "); gc.setAuthor (" jobob "); gc.setOpen (to false); // gc.setIdType (null); // GC .setSwagger2 (true); entity attributes Swagger2 annotation mpg.setGlobalConfig (GC); // data source configuration DataSourceConfig dsc = new DataSourceConfig (); dsc.setUrl ( "jdbc: mysql: //10.11.22.33 :? 4000 / prd_demo characterEncoding = utf8"); Dsc.setSchemaName // ( "public"); dsc.setDriverName ( "com.mysql.cj.jdbc.Driver"); dsc.setUsername ( "root"); dsc.setPassword ( "123456"); mpg.setDataSource ( DSC); // package configuration PackageConfig new new PackageConfig PC = (); pc.setModuleName ( "Product"); // Scanner ( "module name") pc.setParent ( "com.imodule.product"); mpg.setPackageInfo ( PC); // custom configuration InjectionConfig new new InjectionConfig CFG = () { @Override public void initMap () { // Nothing to do } }; // template if the engine is freemarker // the templatePath String = "/templates/mapper.xml.ftl"; // template if the engine is Velocity String the templatePath = "/templates/mapper.xml.vm"; // Custom Output Configuration List <FileOutConfig> focList = ArrayList new new <> (); // custom configuration will be given priority output focList.add (new new FileOutConfig (the templatePath) { @Override public String outputFile (TableInfo TableInfo) { // customize the output file name, if you pre-set Entity suffix name xml attention here will follow the change !! return ProjectPath + "/ src / main / Resources / Mapper /" + pc.getModuleName () + "/" + tableInfo.getEntityName () + "Mapper" + StringPool .DOT_XML; } }); / * Cfg.setFileCreate (new new IFileCreate () { @Override public boolean isCreate (ConfigBuilder configBuilder, FileType fileType, String filePath) { // determine whether you need a custom folder created checkDir ( "call the default method to create the directory, custom catalogs "); IF (fileType == FileType.MAPPER) { // file mapper is determined that there has been generated, do not want to regenerate returns to false return new new file (filePath) .exists ();! } // template file allows the generation to true return; } }); * / cfg.setFileOutConfigList (focList); mpg.setCfg (CFG); // configuration template TemplateConfig templateConfig new new TemplateConfig = (); // configure custom output templates // specified path is defined from the template, be careful not to take .ftl / .vm, the engine will automatically identify the template used according templateConfig.setEntity ( " Templates / entity.java "); templateConfig.setMapper (" Templates / mapper.java "); templateConfig.setXml (" Templates / mapper.xml "); templateConfig.setService (" Templates / service.java "); templateConfig.setServiceImpl ( "Templates / serviceImpl.java"); templateConfig.setController ( "Templates / Controller.java"); templateConfig.setXml (null); mpg.setTemplate (templateConfig); // policy configuration StrategyConfig strategy = new StrategyConfig (); strategy.setNaming (NamingStrategy.underline_to_camel); strategy.setColumnNaming (NamingStrategy.underline_to_camel); / * strategy.setSuperEntityClass ( "your own parent entity, no do not set!"); strategy.setSuperMapperClass ( ""); strategy.setSuperServiceClass ( ""); strategy.setSuperControllerClass ( "do you own parent controller, no do not set!"); * / strategy.setEntityLombokModel (to true); strategy.setRestControllerStyle (to true); // common parent class // write the parent class public fields String [] = {TableName "PRD_BASE", "PRD_PROPERTY"}; strategy.setInclude (TableName); // contains those tables, tables which exclude excude, represented by an array of multiple tables strategy.setControllerMappingHyphenStyle (to true); // EG: TableName : PRD_USER, StrategyConfig.setTablePrefix ( "PRD"); the generated entity classes: User // strategy.setTablePrefix (new String [] { "PRD", "demo _"}); // prefix removing the generated entity class // strategy.setTablePrefix (pc.getModuleName () + "_"); mpg.setStrategy (at Strategy); // mpg.setTemplateEngine (new new FreemarkerTemplateEngine ()); mpg.setTemplateEngine (new new VelocityTemplateEngine ()); // change the template engine / ** * this section is to test to see which contains some of what can be ignored * / = new new configBuilder configBuilder configBuilder (PC, DSC, Strategy, templateConfig, GC); MySqlQuery mySqlQuery new new MySqlQuery = (); String SQL = mySqlQuery.tablesSql (); log.info ( "SQL tidb:" + SQL); // Show Status Table List <the TableInfo> = configBuilder TableInfo .getTableInfoList (); for (TableInfo table: tableinfo) { log.info("tidb tableinfo:"+table.getEntityName()); log.info("tidb tableinfo:"+table.getXmlName()); } mpg.execute(); } }
3. Here is a VM template, template files are as follows (decompression official mybatis-plus-generator-3.0.5.jar, get in mybatis-plus-generator-3.0.5 \ templates directory)
entity.java.vm (default)
package ${package.Entity}; #foreach($pkg in ${table.importPackages}) import ${pkg}; #end #if(${swagger2}) import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; #end #if(${entityLombokModel}) import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; #end /** * <p> * $!{table.comment} * </p> * * @author ${author} * @since ${date} */ #if(${entityLombokModel}) @Data #if(${superEntityClass}) @EqualsAndHashCode(callSuper = true) #else @EqualsAndHashCode(callSuper = false) #end @Accessors(chain = true) #end #if(${table.convert}) @TableName("${table.name}") #end #if(${swagger2}) @ApiModel(value="${entity}对象", description="$!{table.comment}") #end #if(${superEntityClass}) public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { #elseif(${activeRecord}) public class ${entity} extends Model<${entity}> { #else public class ${entity} implements Serializable { #end private static final long serialVersionUID = 1L; ## ---------- BEGIN 字段循环遍历 ---------- #foreach($field in ${table.fields}) #if(${field.keyFlag}) #set($keyPropertyName=${field.propertyName}) #end #if("$!field.comment" != "") #if(${swagger2}) @ApiModelProperty(value = "${field.comment}") #else /** * ${field.comment} */ #end #end #if(${field.keyFlag}) ## 主键 #if(${field.keyIdentityFlag}) @TableId(value = "${field.name}", type = IdType.AUTO) #elseif(!$null.isNull(${idType}) && "$!idType" != "") @TableId(value = "${field.name}", type = IdType.${idType}) #elseif(${field.convert}) @TableId("${field.name}") ## ordinary field #End #elseif(${field.} Fill) ## ----- ----- disposed present field filled #if(${field.convert}) @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) #else @TableField(fill = FieldFill.${field.fill}) #end #elseif(${field.convert}) @TableField("${field.name}") #end ## 乐观锁注解 #if(${versionFieldName}==${field.name}) @Version #end ## 逻辑删除注解 #if(${logicDeleteFieldName}==${field.name}) @TableLogic #end private ${field.propertyType} ${field.propertyName}; #end ## ---------- END 字段循环遍历 ---------- #if(!${entityLombokModel}) #foreach($field in ${table.fields}) #if(${field.propertyType.equals("boolean")}) #set($getprefix="is") #else #set($getprefix="get") #end public ${field.propertyType} ${getprefix}${field.capitalName}() { return ${field.propertyName}; } #if(${entityBuilderModel}) public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { #else public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { #end this.${field.propertyName} = ${field.propertyName}; #if(${entityBuilderModel}) return this; #end } #end #end #if(${entityColumnConstant}) #foreach($field in ${table.fields}) public static final String ${field.name.toUpperCase()} = "${field.name}"; #end #end #if(${activeRecord}) @Override protected Serializable pkVal() { #if(${keyPropertyName}) return this.${keyPropertyName}; #else return null; #end } #end #if(!${entityLombokModel}) @Override public String toString() { return "${entity}{" + #foreach($field in ${table.fields}) #if($!{foreach.index}==0) "${field.propertyName}=" + ${field.propertyName} + #else ", ${field.propertyName}=" + ${field.propertyName} + #end #end "}"; } #end }
mapper.xml.vm (default)
<?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}" /> #foreach ($ {$ table.commonFields in Field}) generating a common field ## #end #end <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>
mapper.java.vm (default)
package ${package.Mapper}; import ${package.Entity}.${entity}; import ${superMapperClassPackage}; import org.apache.ibatis.annotations.Mapper; /** * <p> * $!{table.comment} Mapper 接口 * </p> * * @author ${author} * @since ${date} */ #if(${kotlin}) interface ${table.mapperName} : ${superMapperClass}<${entity}> #else @Mapper public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { } #end
service.java.vm (default)
package ${package.Service}; import ${package.Entity}.${entity}; import ${superServiceClassPackage}; /** * <p> * $!{table.comment} 服务类 * </p> * * @author ${author} * @since ${date} */ #if(${kotlin}) interface ${table.serviceName} : ${superServiceClass}<${entity}> #else public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { } #end
seviceimpl.java.vm (default)
package ${package.ServiceImpl}; import ${package.Entity}.${entity}; import ${package.Mapper}.${table.mapperName}; import ${package.Service}.${table.serviceName}; import ${superServiceImplClassPackage}; import org.springframework.stereotype.Service; /** * <p> * $!{table.comment} 服务实现类 * </p> * * @author ${author} * @since ${date} */ @Service #if(${kotlin}) open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { } #else public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} { } #end
controller.java.vm (default)
package ${package.Controller}; import org.springframework.web.bind.annotation.RequestMapping; #if(${restControllerStyle}) import org.springframework.web.bind.annotation.RestController; #else import org.springframework.stereotype.Controller; #end #if(${superControllerClassPackage}) import ${superControllerClassPackage}; #end /** * <p> * $!{table.comment} 前端控制器 * </p> * * @author ${author} * @since ${date} */ #if(${restControllerStyle}) @RestController #else @Controller #end @RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end") #if(${kotlin}) class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end #else #if(${superControllerClass}) public class ${table.controllerName} extends ${superControllerClass} { #else public class ${table.controllerName} { #end } #end
4. The main class design ProductApplication.java
package com.imodule.product; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ProductApplication { /** * springboot 项目主启动类 * @param args main 函数入参 */ public static void main(String[] args) { SpringApplication.run(ProductApplication.class, args); } }
Perform the steps of: main method of direct execution CodeGenerator.java on it it
The results: (red box marked files are automatically generated)
5. Be tested it, we can just add a data source configuration information write test classes begin testing it on this project
Add a data source configuration:
Test class written: PrdBaseMapperTest.java
package com.imodule.product.mapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.imodule.product.product.entity.PrdBase; import com.imodule.product.product.mapper.PrdBaseMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import java.util.Arrays; import java.util.List; //@RunWith(SpringRunner.class) @ContextConfiguration @SpringBootTest class PrdBaseMapperTest { @Autowired private PrdBaseMapper prdBaseMapper; @Test public void testPrdBaseMapper(){ QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("columnname","columnvalue");//这里写对应的列名与列值即可 List<PrdBase> prdbase = prdBaseMapper.selectList(queryWrapper); System.out.println("testPrdBaseMapper result:"+prdbase); } }
测试结果 欧克啦啦啦啦~
完整的生成流程就如上所述啦~
最后提供一下更改之后的entity模板文件(基于VM)
package ${package.Entity}; #foreach($pkg in ${table.importPackages}) import ${pkg}; #end #if(${swagger2}) import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; #end #if(${entityLombokModel}) import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; #end /** * <p> * $!{table.comment} * </p> * * @author ${author} * @since ${date} */ #if(${entityLombokModel}) @Data #if(${superEntityClass}) @EqualsAndHashCode(callSuper = true) #else @EqualsAndHashCode(callSuper = false) #end @Accessors(chain = true) #end #if(${table.convert}) @TableName("prd_prd.${table.name}") #end #if(${swagger2}) @ApiModel(value="${entity}对象", description="$!{table.comment}") #end #if(${superEntityClass}) public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { #elseif(${activeRecord}) public class ${entity} extends Model<${entity}> { #else public class ${entity} implements Serializable { #end private static final long serialVersionUID = 1L; ## ---------- BEGIN 字段循环遍历 ---------- #foreach($field in ${table.fields}) #if(${field.name.equals("_id")}) #else #if(${field.keyFlag}) #set($keyPropertyName=${field.propertyName}) #end #if("$!field.comment" != "") #if(${swagger2}) @ApiModelProperty(value = "${field.comment}") #else /** * ${field.comment} */ #end #end #if(${field.keyFlag}) ## 主键 #if(${field.keyIdentityFlag}) @TableId(value = "${field.name}", type = IdType.AUTO) #elseif(!$null.isNull(${idType}) && "$!idType" != "") @TableId(value = "${field.name}", type = IdType.${idType}) #elseif(${field.convert}) @TableId("${field.name}") #end ## 普通字段 #elseif(${field.fill}) ## ----- 存在字段填充设置 ----- #if(${field.convert}) @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) #else @TableField(fill = FieldFill.${field.fill}) #end #elseif(${field.convert}) @TableField("${field.name}") #end ## 乐观锁注解 #if(${versionFieldName}==${field.name}) @Version #end ## 逻辑删除注解 #if(${logicDeleteFieldName}==${field.name}) @TableLogic #end private ${field.propertyType} ${field.propertyName}; #end #end ## ---------- END 字段循环遍历 ---------- #if(!${entityLombokModel}) #foreach($field in ${table.fields}) #if(${field.propertyType.equals("boolean")}) #set($getprefix="is") #else #set($getprefix="get") #end public ${field.propertyType} ${getprefix}${field.capitalName}() { return ${field.propertyName}; } #if(${entityBuilderModel}) public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { #else public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { #end this.${field.propertyName} = ${field.propertyName}; #if(${entityBuilderModel}) return this; #end } #end #end #if(${entityColumnConstant}) #foreach($field in ${table.fields}) public static final String ${field.name.toUpperCase()} = "${field.name}"; #end #end #if(${activeRecord}) @Override protected Serializable pkVal() { #if(${keyPropertyName}) return this.${keyPropertyName}; #else return null; #end } #end #if(!${entityLombokModel}) @Override public String toString() { return "${entity}{" + #foreach($field in ${table.fields}) #if($!{foreach.index}==0) "${field.propertyName}=" + ${field.propertyName} + #else ", ${field.propertyName}=" + ${field.propertyName} + #end #end "}"; } #end }