点击上方“猿芯”,选择“设为星标”
后台回复"1024",有份惊喜送给面试的你
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的相关的依赖。
com.baomidou
mybatis-plus-boot-starter
3.0.7.1
com.baomidou
mybatis-plus-generator
3.0.7.1
org.apache.commons
commons-configuration2
2.2
generate.properties
############################数据源配置############################jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://xxxxx/test?useUnicode=true&characterEncoding=utf-8&useSSL=falsejdbc.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 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 getObjectMap(TableInfo tableInfo) {
Map 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;#elseimport 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} {#elsepublic 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#endimport 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}> {#elsepublic 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}>
#elsepublic 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}>#elsepublic 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}>#elsepublic 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();
}
}
其中配置文件中的有些配置需要修改为自己项目的配置,希望这段代码对有需要的朋友有帮助,有错误欢迎指正。
往期推荐
肝九千字长文 | MyBatis-Plus 码之重器 lambda 表达式使用指南,开发效率瞬间提升80%
用 MHA 做 MySQL 读写分离,频繁爆发线上生产事故后,泪奔分享 Druid 连接池参数优化实战
微服务架构下,解决数据库跨库查询的一些思路
一文读懂阿里大中台、小前台战略
作者简介:猿芯,一枚简单的北漂程序员。喜欢用简单的文字记录工作与生活中的点点滴滴,愿与你一起分享程序员灵魂深处真正的内心独白。我的微信号:WooolaDunzung,公众号【猿芯】输入 1024 ,有份面试惊喜送给你哦。
< END >
【猿芯】
微信扫描二维码,关注我的公众号。
分享不易,莫要干想,如果觉得有点用的话,动动你的发财之手,一键三连击:分享、点赞、在看,你们的鼓励是我分享优质文章的最强动力 ^_^