自定义 mybatis generator,修改 mapper 名、集成 lombok

mybatis 逆向工程生成实体类和 mapper,有以下几点想要自定义:
1、Mapper.xml、Mapper.java 想改为 Dao.xml、Dao.java。
2、自动带出数据库已经添加的字段注释。
3、结合 lombok 使用。
4、生成默认的 serialVersionUID。
Todo:
4、对于自动生成的 xml 进行整改。
5、取消默认的构造器。
6、生成全局的 serialVersionUID。

准备工作:要先配置好 generatorConfig.xml,能跑起来,这里就不说明。
把 mybatis-generator-core 加入到 pom 中,版本为你使用的插件版本。

<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.3.5</version>
    <scope>provided</scope>
</dependency>

1、新建如下两个文件RenameJavaMapperPlugins.java,RenameSqlMapperPlugins.java(名字不重要,你可以取你想要的名字),功能分别为修改 .java 与 .xml 文件名。

package org.mybatis.generator.plugins;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import static org.mybatis.generator.internal.util.messages.Messages.getString;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;

/**
 * @ClassName: RenameMapperPlugins
 *
 * @author xuxx
 * @date 2019-05-12 16:12:45
 * @since JDK 1.8
 *
 */
public class RenameJavaMapperPlugins extends PluginAdapter {

    private String searchString;
    private String replaceString;
    private Pattern pattern;

    public boolean validate(List<String> warnings) {

        searchString = properties.getProperty("searchString");
        replaceString = properties.getProperty("replaceString");

        boolean valid = stringHasValue(searchString)
                && stringHasValue(replaceString);

        if (valid) {
            pattern = Pattern.compile(searchString);
        } else {
            if (!stringHasValue(searchString)) {
                warnings.add(getString("ValidationError.18",
                        "RenameExampleClassPlugin",
                        "searchString"));
            }
            if (!stringHasValue(replaceString)) {
                warnings.add(getString("ValidationError.18",
                        "RenameExampleClassPlugin",
                        "replaceString"));
            }
        }

        return valid;
    }

    @Override
    public void initialized(IntrospectedTable introspectedTable) {
        String oldType = introspectedTable.getMyBatis3JavaMapperType();
        Matcher matcher = pattern.matcher(oldType);
        oldType = matcher.replaceAll(replaceString);

        introspectedTable.setMyBatis3JavaMapperType(oldType);
    }
}

在 generatorConfig.xml 合适位置(如果 context 标签下有 property 标签,就在 prope 标签后,如果没有,就放到 context 内最上面)添加如下代码:

<!-- 此处是将UserMapper.xml改名为UserDao.xml -->        
<plugin type="org.mybatis.generator.plugins.RenameSqlMapperPlugins">  
    <property name="searchString" value="Mapper" />
    <property name="replaceString" value="Dao" />
</plugin>  

<!-- 此处是将UserMapper改名为UserDao 接口  -->        
<plugin type="org.mybatis.generator.plugins.RenameJavaMapperPlugins">  
    <property name="searchString" value="Mapper$" />
    <property name="replaceString" value="Dao" />
</plugin> 

type为新建类的全限定名,第一个问题就解决了。
2、新建 MyLombokPlugin.java 文件(其实名字不重要,你可以取你想要的名字),全部代码如下:

package org.mybatis.generator.plugins;

import static org.mybatis.generator.internal.util.messages.Messages.getString;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;

/**
 * mybatis-generator 集成 lombok 的插件
 * 
 * @ClassName: LombokPlugin
 * @author xuxx
 * @date 2019-05-12 14:09:43
 * @since JDK 1.8
 *
 */
public class MyLombokPlugin extends PluginAdapter {
    private final String IGNORE_FIELDS = "ignoreFields";
    private final String MY_SUPPER_CLASS = "supperClass";
    private final String GENERATOR_DEFAULT_SERIAL_VERSION_UID = "defaultSerialVersionUID";

    private String supperClass;

    @Override
    public boolean validate(List<String> warnings) {
        boolean valid = true;
        supperClass = properties.getProperty(MY_SUPPER_CLASS);
        try {
            Class.forName(supperClass);
        } catch (ClassNotFoundException e) {
            warnings.add(getString("ValidationError.18",
                    "MyLombokPlugin",
                    "MY_SUPPER_CLASS"));
            valid = false;
        }

        return valid;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        // 添加domain的import
        topLevelClass.addImportedType("lombok.Data");
        topLevelClass.addImportedType("lombok.NoArgsConstructor");
        topLevelClass.addImportedType("lombok.AllArgsConstructor");
        topLevelClass.addImportedType("lombok.EqualsAndHashCode");

        // 添加domain的注解
        topLevelClass.addAnnotation("@Data");
        topLevelClass.addAnnotation("@NoArgsConstructor");
        topLevelClass.addAnnotation("@AllArgsConstructor");
        topLevelClass.addAnnotation("@EqualsAndHashCode(callSuper = false)");

        // 添加domain的注释
        topLevelClass.addJavaDocLine("/**");
        topLevelClass.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
        topLevelClass.addJavaDocLine("*/");

        // 设置父类
        if (supperClass != null) {
            topLevelClass.setSuperClass(new FullyQualifiedJavaType(supperClass));
        }

        // 设置 GENERATOR_DEFAULT_SERIAL_VERSION_UID
        String generatorDefaultSerialVersionUID = properties.getProperty(GENERATOR_DEFAULT_SERIAL_VERSION_UID);
        if ("true".equals(generatorDefaultSerialVersionUID)) {
            generatorDefaultSerialVersionUID(topLevelClass);
        }

        // 将需要忽略生成的属性过滤掉
        List<Field> fields = topLevelClass.getFields();
        String ignoreFields = getIgnoreFields();
        if (null != ignoreFields && !"".equals(ignoreFields)) {
            String[] field = ignoreFields.split(",");
            for (String ignoreField : field) {
                System.out.println(ignoreField);
                for (int i = 0; i < fields.size(); i++) {
                    Field tableField = fields.get(i);
                    System.out.println(tableField.getName());
                    if (ignoreField.equalsIgnoreCase(tableField.getName())) {
                        fields.remove(tableField);
                        i--;
                    }
                }
            }
        }

        // 给每个字段加注释
        for (Field field : fields) {
            StringBuilder fieldSb = new StringBuilder();
            field.addJavaDocLine("/**");
            fieldSb.append(" * ");
            String fieldName = field.getName(); // java字段名是驼峰的,需要转成下划线分割
            String underlineFieldName = camelToUnderline(fieldName);
            IntrospectedColumn introspectedColumn = introspectedTable.getColumn(underlineFieldName);
            if (null != introspectedColumn) {
                fieldSb.append(introspectedColumn.getRemarks());
            }
            field.addJavaDocLine(fieldSb.toString().replace("\n", " "));
            field.addJavaDocLine(" */");
        }
        return true;
    }

    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable) {
        // Mapper文件的注释
        interfaze.addJavaDocLine("/**");
        interfaze.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
        interfaze.addJavaDocLine("*/");
        return true;
    }

    @Override
    public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass,
            IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        // 不生成getter
        return false;
    }

    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass,
            IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        // 不生成setter
        return false;
    }

    private String date2Str(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    private String getIgnoreFields() {
        return properties.getProperty(IGNORE_FIELDS);
    }

    /**
     * 
     * @Title: camelToUnderline
     * @Description: 把 java 驼峰的变量变为下划线的
     * @param fieldName
     * @return String
     */
    private static String camelToUnderline(String fieldName) {
        StringBuilder result = new StringBuilder();
        if (fieldName != null && fieldName.length() > 0) {
            // 将第一个字符处理成大写
            result.append(fieldName.substring(0, 1).toUpperCase());
            // 循环处理其余字符
            for (int i = 1; i < fieldName.length(); i++) {
                String s = fieldName.substring(i, i + 1);
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_");
                }
                // 其他字符直接转成大写
                result.append(s.toUpperCase());
            }
        }
        return result.toString();
    }

    /**
     * 
     * @Title: generatorDefaultSerialVersionUID
     * @Description: 生成默认的 serialVersionUID
     * @param topLevelClass
     * @return void
     */
    private void generatorDefaultSerialVersionUID(TopLevelClass topLevelClass) {
        Field field = new Field();
        field.setFinal(true);
        field.setInitializationString("1L");
        field.setName("serialVersionUID");
        field.setStatic(true);
        field.setType(new FullyQualifiedJavaType("long"));
        field.setVisibility(JavaVisibility.PRIVATE);
        topLevelClass.getFields().add(0, field);
    }
}

在 generatorConfig.xml 合适位置添加一下代码:

<plugin type="org.mybatis.generator.plugins.MyLombokPlugin">
    <property name="defaultSerialVersionUID" value="true"/>
    <property name="supperClass" value="com.xuxx.spike.entity.BaseEntity" />
    <property name="ignoreFields"
        value="id,revision,createdBy,createdTime,updatedBy,updatedTime" />
</plugin>

插件代码就写完了,具体做什么,代码里面有注释。

这三个插件类不需要加入到 mybatis generator 的 jar 里面,只需要确保这三个类与 generatorConfig.xml 在同一个项目且编译通过就可以了。
这里面 pojo、dao 是分开的,在不同的项目中。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容