MyBatis-Generator plugin 自定义mapper,model
最近公司leader让我使用mybatis generator 生成符合公司规范的代码,但是一直以来我都是使用easycode生成的,mbg这种"老东西"不太熟悉,就很久之前用maven插件生成过默认的代码,所以记录一下,如果有相似要求的就可以直接粘贴我的参考,避免浪费时间挨d
公司规范代码
就是model 生成注释 添加注解 主键添加两个注解;mapper继承父接口
package airport.cargos.web_common_special_goods_identify.entity.po;
import airport.cargos.web_common_special_goods_identify.utils.UUIDGenId;
import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
import java.io.Serializable;
/**
* GoodsPo
*
* @author leen
* @since 2023-11-23 14:56:49
*/
@Data
@Table(name = "goods")
public class Goods {
/**
* 主键
*/
@Id
/* @GeneratedValue(
strategy = GenerationType.IDENTITY
)*/
@KeySql(genId = UUIDGenId.class)
private Long id;
/**
* 货品名称
*/
private String chineseName;
/**
* 英文名称
*/
private String englishName;
/**
* 货品编码
*/
//private String goodsCode;
/**
* 货品类型id
*/
private Long typeId;
/**
* 主要成分货品描述
*/
private String description;
/**
* 主要危险性
*/
private String primaryDanger;
/**
* 货品形状
*/
private String shape;
/**
* 货品形状
*/
private Long manufacturerId;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改时间
*/
private Date modifyTime;
}
package airport.cargos.iwmsAdmin.mapper;
import airport.cargos.iwms.bean.Warehouse;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface WarehouseMapper extends tk.mybatis.mapper.common.Mapper<Warehouse> {
}
plugin代码
因为公司不用mapper.xml,mapper也不用声明方法,所以选择通过重写 contextGenerateAdditionalJavaFiles生成mapper(如果你想的话可以用它来生成model),所以干脆用插件属性来控制生成的位置,配置文件不用写mapper配置;后面想着通过插件属性控制model的生成去除xml中model的配置但是发现删除这个配置会报错,又怕leader催就不管了,使用原生的生成也很方便,可以通过控制Model[Getter|Setter]Methoed方法返回值来去除setter,getter
package com.airport.ape.mbg.adaptor;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.internal.util.StringUtility;
public class MapperPlugin extends PluginAdapter {
//dao 默认父类
private static final String DEFAULT_DAO_SUPER_CLASS = "tk.mybatis.mapper.common.Mapper";
//dao 目标文件夹 targetProject
private String daoTargetDir;
//dao 目标包 targetPackage
private String daoTargetPackage;
private Boolean generateMapper;
//dao 父类
private List<String> superClassList = new ArrayList<>();
//lombok 开关
private Boolean hasLombok;
/**
* 验证参数是否有效
*
* @param warnings
* @return
*/
public boolean validate(List<String> warnings) {
daoTargetDir = properties.getProperty("mapper.targetProject");
daoTargetPackage = properties.getProperty("mapper.targetPackage");
generateMapper=stringHasValue(daoTargetDir)&&stringHasValue(daoTargetPackage);
String daoSuperClass = properties.getProperty("daoSuperClass",DEFAULT_DAO_SUPER_CLASS);
if(stringHasValue(daoSuperClass)){
superClassList.add(daoSuperClass);
}
superClassList = getPropertiesWithPrefix(properties, "daoExtendSuperClass");
String lombok = properties.getProperty("lombok","false");
hasLombok = Boolean.parseBoolean(lombok);
return true;
}
private List<String> getPropertiesWithPrefix(Properties properties, String prefix) {
List<String> result = new ArrayList<>();
for (String propertyName : properties.stringPropertyNames()) {
if (propertyName.startsWith(prefix)) {
result.add(properties.getProperty(propertyName));
}
}
return result;
}
/*
* mapper
* */
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
JavaFormatter javaFormatter = context.getJavaFormatter();
List<GeneratedJavaFile> mapperJavaFiles = new ArrayList<GeneratedJavaFile>();
if(!generateMapper){
return mapperJavaFiles;
}
for (GeneratedJavaFile javaFile : introspectedTable.getGeneratedJavaFiles()) {
CompilationUnit unit = javaFile.getCompilationUnit();
FullyQualifiedJavaType baseModelJavaType = unit.getType();
String shortName = baseModelJavaType.getShortName();
GeneratedJavaFile mapperJavaFile = null;
Interface mapperInterface = new Interface(daoTargetPackage + "." + shortName + "Mapper");
mapperInterface.setVisibility(JavaVisibility.PUBLIC);
mapperInterface.addJavaDocLine("/**");
mapperInterface.addJavaDocLine(" * "+introspectedTable.getFullyQualifiedTableNameAtRuntime()+"Dao");
mapperInterface.addJavaDocLine(" * ");
mapperInterface.addJavaDocLine(" * @author "+properties.getProperty("user.name"));
mapperInterface.addJavaDocLine(" * @Date "+getDateString());
mapperInterface.addJavaDocLine(" */");
superClassList.forEach(superClass->{
FullyQualifiedJavaType daoSuperType = new FullyQualifiedJavaType(superClass);
// 添加泛型支持
daoSuperType.addTypeArgument(baseModelJavaType);
mapperInterface.addImportedType(baseModelJavaType);
//添加daoSuperClass,为默认时不能import,因为和@Mapper重名
if(!daoSuperType.equals(DEFAULT_DAO_SUPER_CLASS)){
mapperInterface.addImportedType(daoSuperType);
}
mapperInterface.addSuperInterface(daoSuperType);
});
mapperInterface.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
mapperInterface.addAnnotation("@Mapper");
mapperJavaFile = new GeneratedJavaFile(mapperInterface, daoTargetDir, javaFormatter);
mapperJavaFiles.add(mapperJavaFile);
}
return mapperJavaFiles;
}
/*
* 自定义model 注释,注解
* */
@Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
if (hasLombok) {
// 添加domain的import
topLevelClass.addImportedType("lombok.Data");
// 添加domain的注解
topLevelClass.addAnnotation("@Data");
}
topLevelClass.addImportedType("javax.persistence.Table");
topLevelClass.addAnnotation("@Table(name = \""+introspectedTable.getFullyQualifiedTableNameAtRuntime()+"\")");
topLevelClass.addJavaDocLine("/**");
String remarks = introspectedTable.getFullyQualifiedTableNameAtRuntime();
topLevelClass.addJavaDocLine(" * " + remarks+"Po");
StringBuilder sb = new StringBuilder();
sb.append(" * ");
topLevelClass.addJavaDocLine(sb.toString());
sb.setLength(0);
sb.append(" * @author ").append(properties.getProperty("user.name"));
topLevelClass.addJavaDocLine(sb.toString());
sb.setLength(0);
sb.append(" * @date ");
sb.append(getDateString());
topLevelClass.addJavaDocLine(sb.toString());
topLevelClass.addJavaDocLine(" */");
//给主键添加注解
List<IntrospectedColumn> primaryKeyColumns = introspectedTable.getPrimaryKeyColumns();
for (IntrospectedColumn primaryKeyColumn : primaryKeyColumns) {
// 获取主键字段的属性名
String propertyName = primaryKeyColumn.getJavaProperty();
// 在属性上添加@Id注解
Field field = findField(topLevelClass, propertyName);
if (field != null) {
topLevelClass.addImportedType("javax.persistence.Id");
field.addAnnotation("@Id");
topLevelClass.addImportedType("javax.persistence.GeneratedValue");
topLevelClass.addImportedType("javax.persistence.GenerationType");
field.addAnnotation("@GeneratedValue(\n" +
" strategy = GenerationType.IDENTITY\n" +
" )");
}
}
return true;
}
private Field findField(TopLevelClass topLevelClass, String propertyName) {
// 查找属性
for (Field field : topLevelClass.getFields()) {
if (field.getName().equals(propertyName)) {
return field;
}
}
return null;
}
@Override
public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable, ModelClassType modelClassType) {
field.addJavaDocLine("/**");
String remarks = introspectedColumn.getRemarks();
if (StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
field.addJavaDocLine(" * " + remarkLine);
}
}
field.addJavaDocLine(" */");
return true;
}
@Override
public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable, ModelClassType modelClassType) {
return !hasLombok;
}
@Override
public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable, ModelClassType modelClassType) {
return !hasLombok;
}
protected String getDateString() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(properties.getProperty("dateTimeFormat", "yyyy-MM-dd HH:mm:ss"));
return simpleDateFormat.format(new Date());
}
}
启动
1. 添加插件com.example.adapter.MapperPlugin
2. 配置属性
- user.name 作者名
- lombok 是否添加@Data
- mapper.targetPackage 生成mapper所在包名
- mapper.targetProject 生成mapper所在文件夹
- daoSuperClass 父类,默认 tk.mybatis.mapper.common.Mapper 设置为空则不生成
- daoExtendSuperClass 扩展父类,可配置多个,匹配前缀 daoExtendSuperClass
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>
<!-- 数据库连接信息 -->
<context id="MyBatisGenerator" targetRuntime="MyBatis3">
<!--防止生成重复代码-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"></plugin>
<plugin type="com.example.adapter.MapperPlugin">
<property name="user.name" value="lee"/>
<property name="lombok" value="true"/>
<property name="mapper.targetPackage" value="com.example.mapper"/>
<property name="mapper.targetProject" value="src/main/java"/>
</plugin>
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--连接数据库信息-->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/white_list"
userId="root"
password="root">
</jdbcConnection>
<!-- 实体类生成的目标包配置 -->
<javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java"></javaModelGenerator>
<!-- 表的映射配置 -->
<table tableName="user" domainObjectName="User"/>
<!-- 可以添加多个table节点配置多个表 -->
<table tableName="goods" domainObjectName="Goods"/>
<table tableName="role" domainObjectName="Role"/>
</context>
</generatorConfiguration>
- 导入依赖
- 编辑xml
- 传递xml所在路径 调用Generator.runner
public class Generator{
public static void runner( String filePath ) throws Exception {
List<String> warnings = new ArrayList<>();
File configFile = new File(filePath);
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(true);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
run demo
import com.example.Generator;
import java.io.File;
public class Test {
public static void main(String[] args) throws Exception {
String filePath = System.getProperty("user.dir") + File.separator + "generator"+File.separator+"mybatisGeneratorConfig.xml";
System.out.println(filePath);
Generator.runner(filePath);
}
}