SpringBoot集成Mybatis-Plus代码生成工具

前言

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网。那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA。

SpringBoot集成Mybatis-Plus在这里不贴代码了,网上有很多的例子。现在介绍集成Mybatis-Plus的代码生成工具。

版本

JDK:1.8

springboot:2.0.0.RELEASE

mybatis-plus-boot-starter:3.0.7.1

mybatis-plus-generator:3.0.7.1

依赖

这里只贴了mybatis-plus-generator的相关的依赖。

   <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.0.7.1version>
        dependency>
     <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-generatorartifactId>
            <version>3.0.7.1version>
        dependency>
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-configuration2artifactId>
            <version>2.2version>
        dependency>

配置文件

generate.properties

############################数据源配置############################
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://xxxxx/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=xxxx
jdbc.password=xxxxx

############################项目位置和表的配置############################
#其他实体类的路径-修改自己的项目中的位置
genetator_path=D:/workspace/test_workspace/common/src/main/java
#Mybatis的xml文件路径-修改自己的项目中的位置
xml_path=D:/workspace/test_workspace/common/src/main/resources/mapper


##################server,mapper,model包的配置##############################
server_package=com.test.service
mapper_package=com.test.dao
model_package=com.test.domain.bo

##################代码注释的作者,可修改为自己,不修改为默认##############################
author=my-generate
##################表配置,修改为数据中的表名称##############################
table_name=t_test

工具类

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
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 java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.ex.ConfigurationException;

public class MpGeneratorUtil {

	/**
	 * 请不要随意改动方法的代码
	 */
	public static void generateCode() {

		// 读取配置文件
		Configuration config = getConfig();

		// 全局配置
		GlobalConfig globalConfig = new GlobalConfig();
		globalConfig.setActiveRecord(false)
				.setAuthor(config.getString("author"))
				.setOutputDir(config.getString("genetator_path"))
				.setFileOverride(true)
				.setEnableCache(false)// XML 二级缓存
				.setBaseResultMap(true)// XML ResultMap
				.setBaseColumnList(true)// XML columList
				.setServiceImplName("%sServiceImpl")
				.setServiceName("%sService")
				.setIdType(IdType.INPUT);

		// 设置数据源
		DataSourceConfig dataSourceConfig = new DataSourceConfig();
		dataSourceConfig.setDbType(DbType.MYSQL)
				.setUrl(config.getString("jdbc.url"))
				.setUsername(config.getString("jdbc.username"))
				.setPassword(config.getString("jdbc.password"))
				.setDriverName(config.getString("jdbc.driverClassName"));

		// 策略配置
		StrategyConfig strategyConfig = new StrategyConfig();
		strategyConfig
				//.setCapitalMode(true) // 全局大写命名
				// .setTablePrefix("") // 设置表前缀
				.setEntityLombokModel(true)
		    .setRestControllerStyle(true)
				//.setSuperEntityClass(config.getString("supper_entity")) //父entity
				.setNaming(NamingStrategy.underline_to_camel)
		    .setColumnNaming(NamingStrategy.underline_to_camel)
				.setInclude(config.getString("table_name"));// 修改替换成你需要的表名,多个表名传数组
		// strategyConfig.entityTableFieldAnnotationEnable(true); // 是否生成实体时,生成字段注解

		// 包配置
		PackageConfig packageConfig = new PackageConfig();
		// 为了方便各个层级自定义包。将parent设置为空。在各个子层级set全路径
		String parentPackage = config.getString("server_package");
		String modelPackage = config.getString("model_package");
		String mapperPackage = config.getString("mapper_package");
		packageConfig.setParent(null)
				//.setController(parentPackage   "controller")
				.setService(parentPackage)
				.setServiceImpl(parentPackage   ".impl")
				.setMapper(mapperPackage)
				.setEntity(modelPackage);
		// 注入自定义配置,可以根据自己需求实现
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				// to do nothing
			}
		};
		// 自定义 xx.xml 生成
		List focList = new ArrayList<>();
		// 调整 xml 生成目录演示
		focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return config.getString("xml_path")   File.separator  
						tableInfo.getEntityName()   "Mapper.xml";
			}
		});
		cfg.setFileOutConfigList(focList);

		// 关闭默认 xml 生成,调整生成 至 根目录
		TemplateConfig tc = new TemplateConfig();
		tc.setXml(null).setController(null);

		new AutoGenerator().setGlobalConfig(globalConfig)
				.setDataSource(dataSourceConfig)
				.setStrategy(strategyConfig)
				.setPackageInfo(packageConfig)
				.setTemplate(tc)
				.setCfg(cfg)
				.setTemplateEngine(new MyVelocityTemplateEngine()) //自定义模板引擎
				.execute();

	}


	/**
	 * 获取配置信息
	 */
	public static Configuration getConfig() {
		try {
			Configuration config = new PropertiesConfiguration();
			InputStreamReader reader = new InputStreamReader(
					Thread.currentThread().getContextClassLoader()
							.getResourceAsStream("config/generate.properties"), "UTF-8");
			((PropertiesConfiguration) config).read(reader);
			return config;
		} catch (ConfigurationException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}

这里使用的Velocity模板,也可以使用freemarker模板。

自定义模板引擎:

import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

/**
 * 自定义模板引擎
 */
public class MyVelocityTemplateEngine extends AbstractTemplateEngine {

	private static final String DOT_VM = ".vm";
	private VelocityEngine velocityEngine;

	@Override
	public MyVelocityTemplateEngine init(ConfigBuilder configBuilder) {
		super.init(configBuilder);
		if (null == velocityEngine) {
			Properties p = new Properties();
			p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
			p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
			p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
			p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
			p.setProperty("file.resource.loader.unicode", "true");
			velocityEngine = new VelocityEngine(p);
		}
		return this;
	}


	@Override
	public void writer(Map<String, Object> objectMap, String templatePath, String outputFile)
			throws Exception {
		if (StringUtils.isEmpty(templatePath)) {
			return;
		}
		// 给生成的entity文件修改为entityVo
		/*if (templatePath.matches(".*entity\\.java\\.vm$")) {
			outputFile = outputFile.replace(".java", "Vo.java");
		}*/
		Template template = velocityEngine.getTemplate(templatePath, ConstVal.UTF8);
		FileOutputStream fos = new FileOutputStream(outputFile);
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, ConstVal.UTF8));
		template.merge(new VelocityContext(objectMap), writer);
		writer.close();
		logger.debug("模板:"   templatePath   ";  文件:"   outputFile);
	}

	/**
	 * 自定义获取table信息表。对entity值扩展为entity Vo
	 */
	@Override
	public Map<String, Object> getObjectMap(TableInfo tableInfo) {
		Map<String, Object> map = super.getObjectMap(tableInfo);
		//将实体类加上VO后缀
		//map.replace("entity", map.get("entity").toString()   "Vo");
		return map;
	}


	@Override
	public String templateFilePath(String filePath) {
		if (null == filePath || filePath.contains(DOT_VM)) {
			return filePath;
		}
		StringBuilder fp = new StringBuilder();
		fp.append(filePath).append(DOT_VM);
		return fp.toString();
	}
}

模板文件

模板文件位于
src/main/resource/templates目录下,主要有:

controller.java.vm

entity.java.vm

mapper.java.vm

mapper.xml.vm

service.java.vm

serviceImpl.java.vm

根据模板文件定义的模板实现相应的类

controller.java.vm



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

/**
 *

* $!{table.comment} 前端控制器 *


 *
 * @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

entity.java.vm

package ${package.Entity};

#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${entityLombokModel})

import lombok.Data;
#if(${superEntityClass})
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
#end
#end

import com.baomidou.mybatisplus.annotation.TableName;
/**
 *

* $!{table.comment} *


 *
 * @author ${author}
 * @since ${date}
 */
#if(${entityLombokModel})
@Data
#if(${superEntityClass})
@EqualsAndHashCode(callSuper = true)
#end
#end
@TableName("${table.name}")
#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" != "")
    /**
     * ${field.comment}
     */
#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 字段循环遍历  ----------

#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 this.id;
#end
    }

#end
#if(!${entityLombokModel})
    @Override
    public String toString() {
        return "${entity}{"  
#foreach($field in ${table.fields})
#if($!{velocityCount}==1)
        "${field.propertyName}="   ${field.propertyName}  
#else
        ", ${field.propertyName}="   ${field.propertyName}  
#end
#end
        "}";
    }
#end
}

mapper.java.vm

package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import ${cfg.commonPck}.BaseDto;
import ${cfg.commonPck}.Query;
import com.baomidou.mybatisplus.plugins.pagination.Pagination;
import org.apache.ibatis.annotations.Param;
import java.util.List;

/**
 *

* $!{table.comment} Mapper 接口 *


 *
 * @author ${author}
 * @since ${date}
 */
#if(${kotlin})
interface ${table.mapperName} : ${superMapperClass}<${entity}>
#else
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

    List<${entity}> queryPageList(Pagination page,@Param("query") Query query);

}
#end

mapper.xml.vm

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.Map;
import ${cfg.commonPck}.PageInfo;
import ${cfg.commonPck}.BaseDto;

/**
 *

* $!{table.comment} 服务类 *


 *
 * @author ${author}
 * @since ${date}
 */
#if(${kotlin})
interface ${table.serviceName} : ${superServiceClass}<${entity}>
#else
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

    /**
     * 分页查询
     * @param dto
     * @return
     */
    PageInfo<${entity}> queryPage(BaseDto<${entity}> dto);
}
#end

service.java.vm

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.Map;
import ${cfg.commonPck}.PageInfo;
import ${cfg.commonPck}.BaseDto;

/**
 *

* $!{table.comment} 服务类 *


 *
 * @author ${author}
 * @since ${date}
 */
#if(${kotlin})
interface ${table.serviceName} : ${superServiceClass}<${entity}>
#else
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

    /**
     * 分页查询
     * @param dto
     * @return
     */
    PageInfo<${entity}> queryPage(BaseDto<${entity}> dto);
}
#end

serviceImpl.java.vm

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import java.util.List;

import ${cfg.commonPck}.PageInfo;
import ${cfg.commonPck}.BaseDto;
import ${cfg.commonPck}.Query;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 *

* $!{table.comment} 服务实现类 *


 *
 * @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} {
    private Logger log=LogManager.getLogger(this.getClass().getName());
    /**
     * 分页查询
     * @param dto
     * @return
     */
    public PageInfo<${entity}>queryPage(BaseDto<${entity}> dto){

    Queryquery=new Query<>(dto);
    List<${entity}>list=this.baseMapper.queryPageList(query.getPage(),query);
    return new PageInfo<>(query.getPage(),list);
    }

    }
#end

最后编写一main运行工具类,运行main方法即可实现相关的类的构建。

public class MpGenerator {

	public static void main(String[] args) {
		//生成代码
		MpGeneratorUtil.generateCode();
	}

}

其中配置文件中的有些配置需要修改为自己项目的配置,希望这段代码对有需要的朋友有帮助,有错误欢迎指正。

内容出处:,

声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/23084.html

发表评论

登录后才能评论