mybatis-generatro自定义插件

    起因,在我日常开发中总是会遇到一些问题,公司自己封装的框架需要有一套自己对数据库的CURD操作。就以我公司的来说,前端需要显示一个列表(基本上每一个在前端显示的表数据都是以一个列表的形式展现的),这就意味着后端对数据库需要有一个getPage操作。而每一个表都需要添加getPage操作。我觉得总是去写重复的操作总是有一些麻烦。于是就有了自己折腾出来的自定义插件(公司也有自己的mybatis-generatro插件,可是功能满足不了)。于是就研究了一下怎么自定义插件,去解决一些重复性的工作。

1)  自定义类注释生成

2)  自定义插件

3)  使用Velocity生成service controller层等

4)  使用自己的插件

5)调试插件


    1)  自定义类注释生成

        通过查找资料可以找出,我们要给类添加表的注释,有俩种方式。把表,列的注释映射到java类上面

        a) 实现org.mybatis.generator.api.CommentGenerator接口。

        b) 继承org.mybatis.generator.internal.DefaultCommentGenerator类,重写它的方法。这个是他的默认现实类,我们生成的java对象的注释就是由这个类定义的。mybatis-generator默认就是使用的这个。我们需要完全自己定义自己的注释,所以我们直接实现CommentGenerator接口。

        我们先来看一下CommentGenerator接口的方法

mybatis-generatro自定义插件_第1张图片

        看到方法名的瞬间是不是知道自己要做什么了?

        我们可以先写一个空的CommentGenerator实现。然后继承我们自己空的CommentGenerator,再去重写自己需要的方法。这样子我们就可以实现自己的自定义注解。

        贴上我的CommentGenerator


package com.dgbiztech.generator.plugin.comment;

import com.dgbiztech.generator.utils.StringUtils;

import org.mybatis.generator.api.IntrospectedColumn;

import org.mybatis.generator.api.IntrospectedTable;

import org.mybatis.generator.api.dom.java.*;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Properties;

public class CommentGenerator extends EmptyCommentGenerator {

    private Properties properties;

    public CommentGenerator() {

        properties =new Properties();

    }

    @Override

    public void addConfigurationProperties(Properties properties) {

        // 获取自定义的 properties

        this.properties.putAll(properties);

    }

    @Override

    public void addModelClassComment(TopLevelClass topLevelClass,IntrospectedTable introspectedTable) {

        String author =properties.getProperty("author");

        String dateFormat =properties.getProperty("dateFormat","yyyy-MM-dd");

        String baseModel =properties.getProperty("interface","false");

        if (baseModel.equals("true")){

            String baseClass =properties.getProperty("classpath","x");

        if (baseClass.equals("x")){

                throw new RuntimeException("classpath路径不存在!");

        }

           topLevelClass.addImportedType(baseClass);

    topLevelClass.addSuperInterface(new FullyQualifiedJavaType(baseClass.substring(baseClass.lastIndexOf(".")+1,baseClass.length())));

}

        SimpleDateFormat dateFormatter =new SimpleDateFormat(dateFormat);

// 获取表注释

        String remarks =introspectedTable.getRemarks();

    topLevelClass.addJavaDocLine("/**");

    topLevelClass.addJavaDocLine(" * " + remarks);

    topLevelClass.addJavaDocLine(" * @author " + author);

    topLevelClass.addJavaDocLine(" * @date  " + dateFormatter.format(new Date()));

    topLevelClass.addJavaDocLine(" */");

    }

    @Override

    public void addFieldComment(Field field,IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {

        // 获取列注释

        String remarks =introspectedColumn.getRemarks();

        field.addJavaDocLine("/**");

        field.addJavaDocLine(" * " +(StringUtils.isEmpty(remarks)?introspectedColumn.getActualColumnName():remarks));

        field.addJavaDocLine(" */");

    }

    @Override

    public void addGetterComment(Method method,IntrospectedTable introspectedTable,

IntrospectedColumn introspectedColumn) {

        method.addJavaDocLine("/**");

        StringBuilder sb =new StringBuilder();

    sb.append(" * ");

    sb.append(introspectedColumn.getRemarks());

    method.addJavaDocLine(sb.toString().replace("\n"," "));

    sb.setLength(0);

    sb.append(" * @return ");

    sb.append(introspectedColumn.getActualColumnName());

    sb.append(" ");

    sb.append(introspectedColumn.getRemarks());

    method.addJavaDocLine(sb.toString().replace("\n"," "));

    method.addJavaDocLine(" */");

    }

    @Override

    public void addSetterComment(Method method,IntrospectedTable introspectedTable,

IntrospectedColumn introspectedColumn) {

        method.addJavaDocLine("/**");

        StringBuilder sb =new StringBuilder();

        sb.append(" * ");

        sb.append(introspectedColumn.getRemarks());

        method.addJavaDocLine(sb.toString().replace("\n"," "));

        Parameter parm =method.getParameters().get(0);

        sb.setLength(0);

        sb.append(" * @param ");

        sb.append(parm.getName());

        sb.append(" ");

        sb.append(introspectedColumn.getRemarks());

        method.addJavaDocLine(sb.toString().replace("\n"," "));

        method.addJavaDocLine(" */");

    }

}

  2)  自定义插件

    自定义插件我们需要继承org.mybatis.generator.api.PluginAdapter类

    先上代码

 package com.dgbiztech.generator.plugin;

import com.dgbiztech.generator.utils.SqlMapperGeneratorTool;

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.FullyQualifiedJavaType;

import org.mybatis.generator.api.dom.xml.Document;

import org.mybatis.generator.api.dom.xml.TextElement;

import org.mybatis.generator.api.dom.xml.XmlElement;

import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;

import java.util.List;

public class GetPagePlugin extends PluginAdapter {

    private final static String GET_PAGE ="getPage";

private Boolean likequery;

@Override

    public boolean validate(List warnings) {

        return true;

}

    /**

* 方法对应的xml节点在这里添加

    * @param document

    * @param introspectedTable

    * @return

    */

    @Override

    public boolean sqlMapDocumentGenerated(Document document,IntrospectedTable introspectedTable) {

        if (introspectedTable.getTargetRuntime().equals(IntrospectedTable.TargetRuntime.MYBATIS3)) {

            addSqlMapper(document,introspectedTable);

}

        return super.sqlMapDocumentGenerated(document,introspectedTable);

}

    public void addSqlMapper(Document document,IntrospectedTable introspectedTable) {

        likequery =Boolean.valueOf(properties.getProperty("likequery","false"));

String tableName =introspectedTable.getFullyQualifiedTableNameAtRuntime();

List columnList =introspectedTable.getAllColumns();

//model的包路径

        String baseRecordType =introspectedTable.getBaseRecordType();

//primaryKey的JDBC名字

        String primaryKeyName =introspectedTable.getPrimaryKeyColumns().get(0).getActualColumnName();

//primaryKey的JAVA变量

        String primaryKeyParameterClause =MyBatis3FormattingUtilities.getParameterClause(introspectedTable.getPrimaryKeyColumns().get(0),"item.");

//primaryKey的JAVA名字

        String primaryKeyJavaName =introspectedTable.getPrimaryKeyColumns().get(0).getJavaProperty();

//构建一个xml节点,

        XmlElement getPageXmlElement =SqlMapperGeneratorTool.baseElementGenerator(SqlMapperGeneratorTool.SELECT,

GET_PAGE,

new FullyQualifiedJavaType(baseRecordType),

new FullyQualifiedJavaType("com.dgbiztech.core.dto.MapDto"));

getPageXmlElement.addElement(new TextElement(String.format("SELECT * FROM %s ",tableName)));

XmlElement whereElement =new XmlElement("where");

getPageXmlElement.addElement(whereElement);

for (int i =0; i < columnList.size(); i++) {

            IntrospectedColumn introspectedColumn = columnList.get(i);

String columnName = introspectedColumn.getActualColumnName();

String columnJavaTypeName = introspectedColumn.getJavaProperty();

String parameterClause =MyBatis3FormattingUtilities.getParameterClause(introspectedColumn);

String ifSql;

if(likequery) {

                ifSql =String.format("AND %s LIKE %s || ",columnName,parameterClause);

ifSql+=" '%' ";

}else {

                ifSql =String.format("AND %s = %s ",columnName,parameterClause);

}

            XmlElement ifElement =SqlMapperGeneratorTool.baseIfJudgeElementGen(columnJavaTypeName, ifSql, introspectedColumn);

whereElement.addElement(ifElement);

}

        document.getRootElement().addElement(getPageXmlElement);

}

}

如果我们需要在xml文件里面自己自定义一个节点,那么我们需要重写sqlMapDocumentGenerated方法

里面有两个参数,Document document 和 IntrospectedTable introspectedTable

document代表的就是整个xml文件。introspectedTable就是当前表的信息。(每一个表都会运行插件)

在introspectedTable里面可以获取到我们需要的表的信息,例如表名,列名,生成java类的属性等等。我们就可以自己拼接自己的节点。

通过document.getRootElement().addElement(自己的节点);我们就可以把自己的节点添加到xml文件。

 3)  使用Velocity生成service controller层等

        对应的插件是com.dgbiztech.generator.plugin.ServiceControllerPlugin

        原理就是通过使用Velocity模板文件(*.vm),把表的数据写入到模板当中,然后写出到文件夹。

  4)  使用自己的插件

     a)先把我们的自定义插件install一次(mvn命令),这里使用的是mybatis-generator的maven插件。


mybatis-generatro自定义插件_第2张图片

     然后把我们的插件添加到mybatis-generator的maven插件的依赖里面。


mybatis-generatro自定义插件_第3张图片

然后我们在generatorConfig.xml里面配置我们的插件就可以了。


mybatis-generatro自定义插件_第4张图片

5)调试插件

    开发插件的时候我们使用junit4来调试插件

package com.dgbiztech.generator.plugin;

import org.junit.Before;

import org.junit.Test;

import org.mybatis.generator.api.MyBatisGenerator;

import org.mybatis.generator.config.Configuration;

import org.mybatis.generator.config.xml.ConfigurationParser;

import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;

import java.util.ArrayList;

import java.util.List;

import static org.junit.Assert.*;

public class ServiceControllerPluginTest {

    private File configFile;

@Before

    public void before() {

        //读取mybatis参数

        configFile =new File("D:\\repo-git\\mybatis-generator\\mybatis-generator\\src\\main\\resources\\generatorConfig.xml");

//        configFile = new File("/Users/zhangsiyuan/Documents/MybatisFun/Mybatis-Chapter9-GeneratorPlugin/src/main/resources/mybatisConfig.xml");

    }

    @Test

    public void test() throws Exception{

        List warnings =new ArrayList();

        boolean overwrite =true;

        ConfigurationParser cp =new ConfigurationParser(warnings);

        Configuration config = cp.parseConfiguration(configFile);

        DefaultShellCallback callback =new DefaultShellCallback(overwrite);

        MyBatisGenerator myBatisGenerator =new MyBatisGenerator(config, callback, warnings);

        myBatisGenerator.generate(null);

    }

}


本文源码:   

mybatis-generator自定义插件

参考:

Mybatis Generator生成数据库自带的中文注释

图形化MBG,内置丰富插件,可生成Service、Controller、View,配置简单。 A powerful GUI tool for MyBatisGenerator(MBG)

Velocity初探小结--velocity使用语法详解

PS:源码里面的数据大都是我根据公司自己的要求制定出来的。比如增加一些baseclass之类的。

你可能感兴趣的:(mybatis-generatro自定义插件)