使用MybatisPlus Generator生成优雅的代码、自定义的代码
撸代码的最高境界就是让代码帮你撸代码。目前mybatis相关的代码生成器都挺友好的,最后生成最简洁清爽易读,还得看mybatisplus-generator。使用mybatisplus-generator不一定需要是mybatisplus作为持久层框架,也可以生成通用mapper+mybatis的代码。代码模板都可以自定义,而且还支持多种代码模板。以下就是我用其中一种模板封装的代码生成器,供大家参考。
1.加入标准的maven依赖
mysql mysql-connector-java 8.0 . 19 com.oracle.database.jdbc ojdbc8 19.13 . 0.0 org.projectlombok lombok 1.18 . 20 provided org.springframework.boot spring-boot-starter-web io.springfox springfox-swagger2 2.4 . 0 io.springfox springfox-swagger-ui 2.4 . 0 com.github.xiaoymin swagger-bootstrap-ui 1.9 . 6 tk.mybatis mapper-spring-boot-starter 2.1 . 5 com.alibaba fastjson 1.2 . 70 com.baomidou mybatis-plus-generator 3.4 . 1 org.apache.velocity velocity-engine-core 2.3
2.编写标准的核心代码
package org.example.core; import com.baomidou.mybatisplus.annotation.IdType; 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.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.FileOutConfig; 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.po.TableInfo; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine; import java.util.ArrayList; import java.util.List; import java.util.Objects; import org.apache.commons.lang3.StringUtils; import org.example.entity.dto.CodeGeneratorParamDTO; import org.springframework.stereotype.Service; /** * 代码生成服务类 **/ @Service public class CodeGenerator { public void execute(CodeGeneratorParamDTO codeGeneratorParamDTO) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig globalConfig = this .configGlobal(codeGeneratorParamDTO); mpg.setGlobalConfig(globalConfig); // 配置数据源 DataSourceConfig dataSourceConfig = this .configDataSource(codeGeneratorParamDTO); mpg.setDataSource(dataSourceConfig); // 配置包规则 PackageConfig packageConfig = this .configPackage(codeGeneratorParamDTO); mpg.setPackageInfo(packageConfig); // 自定义配置 InjectionConfig injectionConfig = this .configInjection(codeGeneratorParamDTO, packageConfig); mpg.setCfg(injectionConfig); // 配置要生成的模板 TemplateConfig templateConfig = this .configTemplate(codeGeneratorParamDTO); mpg.setTemplate(templateConfig); // 配置生成策略 StrategyConfig strategyConfig = this .configStrategy(codeGeneratorParamDTO); mpg.setStrategy(strategyConfig); // 设置模板引擎 mpg.setTemplateEngine( new VelocityTemplateEngine()); mpg.execute(); } private GlobalConfig configGlobal(CodeGeneratorParamDTO codeGeneratorParamDTO) { String projectPath = codeGeneratorParamDTO.getProjectPath(); if (!projectPath.endsWith( "\\" ) && !projectPath.endsWith( "/" )){ projectPath = projectPath + "\\" ; } String javaCodeOutputPath = projectPath + "src\\main\\java" ; GlobalConfig globalConfig = new GlobalConfig(); globalConfig.setOutputDir(javaCodeOutputPath) .setAuthor(codeGeneratorParamDTO.getAuthorName()) .setIdType(IdType.AUTO) .setBaseColumnList( true ) .setBaseResultMap( true ) .setOpen( false ) .setFileOverride(codeGeneratorParamDTO.getIsOverride()) .setServiceName( "%sService" ) .setMapperName( "%sDao" ); return globalConfig; } private DataSourceConfig configDataSource(CodeGeneratorParamDTO codeGeneratorParamDTO) { // 数据源配置 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setUrl(codeGeneratorParamDTO.getDataSourceUrl()); dataSourceConfig.setDriverName(codeGeneratorParamDTO.getDataSourceDriver()); dataSourceConfig.setUsername(codeGeneratorParamDTO.getDataSourceUserName()); dataSourceConfig.setPassword(codeGeneratorParamDTO.getDataSourcePassword()); return dataSourceConfig; } private PackageConfig configPackage(CodeGeneratorParamDTO codeGeneratorParamDTO) { // 包配置 PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent(codeGeneratorParamDTO.getBasePackageName()); packageConfig.setService(codeGeneratorParamDTO.getServicePackageName()); packageConfig.setServiceImpl(packageConfig.getService() + ".impl" ); packageConfig.setMapper(codeGeneratorParamDTO.getDaoPackageName()); packageConfig.setEntity(codeGeneratorParamDTO.getEntityPackageName()); return packageConfig; } private InjectionConfig configInjection(CodeGeneratorParamDTO codeGeneratorParamDTO, PackageConfig packageConfig) { // 自定义配置 InjectionConfig injectionConfig = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 指定模板引擎是 velocity String templatePath = "/templates/mapper.xml.vm" ; // 自定义输出配置 List focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add( new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 return codeGeneratorParamDTO.getProjectPath() + "/" + StringUtils.join(codeGeneratorParamDTO.getMapperXmlPath(),packageConfig.getModuleName()) + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); injectionConfig.setFileOutConfigList(focList); return injectionConfig; } private TemplateConfig configTemplate(CodeGeneratorParamDTO codeGeneratorParamDTO) { // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板 if (Objects.equals(codeGeneratorParamDTO.getIsNeedController(), Boolean.FALSE)){ templateConfig.setController( null ); } if (Objects.equals(codeGeneratorParamDTO.getIsNeedMapper(), Boolean.FALSE)){ templateConfig.setXml( null ); } if (Objects.equals(codeGeneratorParamDTO.getIsNeedDao(), Boolean.FALSE)){ templateConfig.setMapper( null ); } if (Objects.equals(codeGeneratorParamDTO.getIsNeedEntity(), Boolean.FALSE)){ templateConfig.setEntity( null ); } if (Objects.equals(codeGeneratorParamDTO.getIsNeedService(), Boolean.FALSE)){ templateConfig.setService( null ); templateConfig.setServiceImpl( null ); } return templateConfig; } private StrategyConfig configStrategy(CodeGeneratorParamDTO codeGeneratorParamDTO) { StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setNaming(NamingStrategy.underline_to_camel); strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); // 通用mapper作为父类则这里为:tk.mybatis.mapper.common.BaseMapper,如果是mybatisplus则改为com.baomidou.mybatisplus.core.mapper.BaseMapper strategyConfig.setSuperMapperClass( "tk.mybatis.mapper.common.BaseMapper" ); strategyConfig.setEntityLombokModel( true ); strategyConfig.setRestControllerStyle( true ); // 公共父类 strategyConfig.setInclude(codeGeneratorParamDTO.getTableNames().split( "," )); strategyConfig.setControllerMappingHyphenStyle( true ); strategyConfig.setTablePrefix(codeGeneratorParamDTO.getTablePrefix()); strategyConfig.setEntityTableFieldAnnotationEnable( false ); strategyConfig.setEntitySerialVersionUID( false ); return strategyConfig; } }
3.传入标准的核心参数
package org.example.entity.dto; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import lombok.Data; /** * 代码生成器的传参 * **/ @Data public class CodeGeneratorParamDTO implements Serializable { @ApiModelProperty (value = "项目所在目录:如:D:\\project\\demo" , required = true , position = 1 ) private String projectPath; @ApiModelProperty (value = "生成代码后所在的基础包,如com.example" , required = true , position = 2 ) private String basePackageName; @ApiModelProperty (value = "数据源连接的url" ,required = true , position = 3 ) private String dataSourceUrl; @ApiModelProperty (value = "数据源连接的驱动,默认为com.mysql.cj.jdbc.Driver。只支持mysql与Oracle" , hidden = true ) private String dataSourceDriver = "com.mysql.cj.jdbc.Driver" ; @ApiModelProperty (value = "数据源-数据库的用户" , required = true , position = 4 ) private String dataSourceUserName; @ApiModelProperty (value = "数据源-数据库的密码" , required = true , position = 5 ) private String dataSourcePassword; @ApiModelProperty (value = "生成代码的表名,多个表名用英文的逗号隔开" , required = true , position = 6 ) private String tableNames; @ApiModelProperty ( "mapper.xml文件所在项目的相对目录,如:src/main/resources/mapper/,默认src/main/resources/mapper/" ) private String mapperXmlPath = "src/main/resources/mapper/" ; @ApiModelProperty ( "service所在的包名,如:service,默认service" ) private String servicePackageName = "service" ; @ApiModelProperty ( "dao所在的包名,如:dao,默认dao" ) private String daoPackageName = "dao" ; @ApiModelProperty ( "生成的实体所在的包名,如:entity.po,默认entity.po" ) private String entityPackageName = "entity.po" ; @ApiModelProperty ( "生成代码需要去掉的表的前缀" ) private String tablePrefix; @ApiModelProperty ( "生成代码是否覆盖原有的类 false否 true是,默认true" ) private Boolean isOverride = true ; @ApiModelProperty ( "是否需要生成controller类 false否 true是,默认false" ) private Boolean isNeedController = false ; @ApiModelProperty ( "是否需要生成service类 false否 true是,默认false" ) private Boolean isNeedService = false ; @ApiModelProperty ( "是否需要生成dao类 false否 true是,默认true" ) private Boolean isNeedDao = true ; @ApiModelProperty ( "是否需要生成mapper.xml false否 true是,默认true" ) private Boolean isNeedMapper = true ; @ApiModelProperty ( "是否需要生成entity false否 true是,默认true" ) private Boolean isNeedEntity = true ; @ApiModelProperty ( "代码生成当前开发者名称" ) private String authorName; }
4.输出标准的优雅代码
略
探索不以困难而止,学习不以艰苦而终