千家信息网

什么是Mybatis-Generator扩展自定义生成

发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,这篇文章给大家介绍什么是Mybatis-Generator扩展自定义生成,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Mybatis-Generator 可自动生成Model、D
千家信息网最后更新 2024年11月18日什么是Mybatis-Generator扩展自定义生成

这篇文章给大家介绍什么是Mybatis-Generator扩展自定义生成,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

Mybatis-Generator 可自动生成Model、Dao、Mapper代码,但其自带生成的代码存在以下问题:

  • 生成的注释不是我们想要的,我们期望的是根据数据库表、字段生成不同的注释;

  • 分页代码生成缺失,每个公司的分页方式不同,尤其是老久项目或已发布API,不能随意变动,那么如何自适应分页代码生成;

  • Mapper.xml没有group by相关代码生成;

  • 重复生成代码时,Mapper.xml并不是覆盖原代码,而是对内容进行了追加;

  • 序列化,mybatis-generator内置了SerializablePlugin,但仅对Model,并没有对 Example序列化,在一些开发中是不够的;

  • 对Service Layer代码没有生成。

一、注释的自定义生成

根据数据库表或字段的COMMENT生成注释。@Date 生成的时间可根据需要自己定义格式。

package run.override;import java.util.Date;import java.util.Properties;import org.mybatis.generator.api.IntrospectedColumn;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.dom.java.CompilationUnit;import org.mybatis.generator.api.dom.java.Field;import org.mybatis.generator.api.dom.java.InnerClass;import org.mybatis.generator.api.dom.java.InnerEnum;import org.mybatis.generator.api.dom.java.JavaElement;import org.mybatis.generator.api.dom.java.Method;import org.mybatis.generator.api.dom.java.Parameter;import org.mybatis.generator.api.dom.xml.XmlElement;import org.mybatis.generator.internal.DefaultCommentGenerator;import org.mybatis.generator.internal.util.StringUtility;/** * Comment Generator * @ClassName CommentGenerator  * @Description  * @author Marvis */public class CommentGenerator extends DefaultCommentGenerator {    private Properties properties;    private boolean suppressDate;    private boolean suppressAllComments;    public CommentGenerator() {        this.properties = new Properties();        this.suppressDate = false;        this.suppressAllComments = false;    }    public void addJavaFileComment(CompilationUnit compilationUnit) {        compilationUnit.addFileCommentLine("/*** copyright (c) 2019 Marvis  ***/");    }    /**     * XML file Comment     */    public void addComment(XmlElement xmlElement) {        if (this.suppressAllComments) {            return;        }    }    public void addRootComment(XmlElement rootElement) {    }    public void addConfigurationProperties(Properties properties) {        this.properties.putAll(properties);        this.suppressDate = StringUtility.isTrue(properties.getProperty("suppressDate"));        this.suppressAllComments = StringUtility.isTrue(properties.getProperty("suppressAllComments"));    }    protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {        StringBuilder sb = new StringBuilder();        sb.append(" * ");        sb.append("@date");        String s = getDateString();        if (s != null) {            sb.append(' ');            sb.append(s);        }        javaElement.addJavaDocLine(sb.toString());    }    protected String getDateString() {        if (this.suppressDate) {            return null;        }        return new Date().toString();    }    /**      *  Comment of Example inner class(GeneratedCriteria ,Criterion)     */    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {        if (this.suppressAllComments) {            return;        }        innerClass.addJavaDocLine("/**");        innerClass.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ "

"); innerClass.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable().toString()); addJavadocTag(innerClass, false); innerClass.addJavaDocLine(" */"); } public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) { if (this.suppressAllComments) { return; } StringBuilder sb = new StringBuilder(); innerEnum.addJavaDocLine("/**"); innerEnum.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable().getAlias()+ "

"); innerEnum.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable()); innerEnum.addJavaDocLine(sb.toString()); addJavadocTag(innerEnum, false); innerEnum.addJavaDocLine(" */"); } /** * entity filed Comment */ public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { if (this.suppressAllComments) { return; }// if(introspectedColumn.getRemarks() != null && !introspectedColumn.getRemarks().trim().equals("")) field.addJavaDocLine("/**"); field.addJavaDocLine(" * " + introspectedColumn.getRemarks()); field.addJavaDocLine(" * @author " ); field.addJavaDocLine(" * @date " + getDateString() ); field.addJavaDocLine(" * @return"); field.addJavaDocLine(" */"); } /** * Comment of EXample filed */ public void addFieldComment(Field field, IntrospectedTable introspectedTable) { if (this.suppressAllComments) { return; } field.addJavaDocLine("/**"); addJavadocTag(field, false); field.addJavaDocLine(" */"); } /** * Comment of Example method */ public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) { if (this.suppressAllComments) { return; } } /** * * entity Getter Comment */ public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { if (this.suppressAllComments) { return; } method.addJavaDocLine("/**"); method.addJavaDocLine(" * @return " + introspectedTable.getFullyQualifiedTable().getAlias() + " : " + introspectedColumn.getRemarks()); method.addJavaDocLine(" */"); } public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { if (this.suppressAllComments) { return; } StringBuilder sb = new StringBuilder(); method.addJavaDocLine("/**"); Parameter parm = (Parameter) method.getParameters().get(0); sb.append(" * @param "); sb.append(parm.getName()); sb.append(" : "); sb.append(introspectedColumn.getRemarks()); method.addJavaDocLine(sb.toString()); method.addJavaDocLine(" */"); } /** * Comment of Example inner class(Criteria) */ public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) { if (this.suppressAllComments) { return; } innerClass.addJavaDocLine("/**"); innerClass.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable().getAlias()+ "

"); innerClass.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable().toString()); addJavadocTag(innerClass, markAsDoNotDelete); innerClass.addJavaDocLine(" */"); }

Model 类注释(表的描述): MySQL。

1)EntityCommentPlugin

package run.override.model;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Date;import java.util.List;import org.mybatis.generator.api.FullyQualifiedTable;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.PluginAdapter;import org.mybatis.generator.api.dom.java.TopLevelClass;import org.mybatis.generator.internal.JDBCConnectionFactory;import org.mybatis.generator.internal.util.StringUtility;/** * Comment of Entity,only support MySQL * @ClassName CommentPlugin  * @Description  * @author Marvis */public class EntityCommentPlugin extends PluginAdapter {    @Override    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {        addModelClassComment(topLevelClass, introspectedTable);        return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);    }    @Override    public boolean modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass,            IntrospectedTable introspectedTable) {        addModelClassComment(topLevelClass, introspectedTable);        return super.modelRecordWithBLOBsClassGenerated(topLevelClass, introspectedTable);    }    protected void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {        FullyQualifiedTable table = introspectedTable.getFullyQualifiedTable();        String tableComment = getTableComment(table);        topLevelClass.addJavaDocLine("/**");        if(StringUtility.stringHasValue(tableComment))            topLevelClass.addJavaDocLine(" * " + tableComment + "

"); topLevelClass.addJavaDocLine(" * " + table.toString() + "

"); topLevelClass.addJavaDocLine(" * @date " + new Date().toString()); topLevelClass.addJavaDocLine(" *"); topLevelClass.addJavaDocLine(" */"); } /** * @author Marvis * @date Jul 13, 2017 4:39:52 PM * @param table */ private String getTableComment(FullyQualifiedTable table) { String tableComment = ""; Connection connection = null; Statement statement = null; ResultSet rs = null; try { JDBCConnectionFactory jdbc = new JDBCConnectionFactory(context.getJdbcConnectionConfiguration()); connection = jdbc.getConnection(); statement = connection.createStatement(); rs = statement.executeQuery("SHOW CREATE TABLE " + table.getIntrospectedTableName()); if (rs != null && rs.next()) { String createDDL = rs.getString(2); int index = createDDL.indexOf("COMMENT='"); if (index < 0) { tableComment = ""; } else { tableComment = createDDL.substring(index + 9); tableComment = tableComment.substring(0, tableComment.length() - 1); } } } catch (SQLException e) { } finally { closeConnection(connection, statement, rs); } return tableComment; } /** * * @author Marvis * @date Jul 13, 2017 4:45:26 PM * @param connection * @param statement * @param rs */ private void closeConnection(Connection connection, Statement statement, ResultSet rs) { try { if (null != rs) rs.close(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (statement != null) statement.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (connection != null) connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } } /** * This plugin is always valid - no properties are required */ @Override public boolean validate(List warnings) { return true; }}

二、分页和分组代码生成

这里,我对Dao Model进行了通用方法的抽取,建立通用基类。同时,对其进行了一些扩展,增加分页和分组。

先对基类进行介绍。

1)BaseMapper

package cn.xxx.core.base.dao;import java.util.List;import org.apache.ibatis.annotations.Param;public interface BaseMapper {    long countByExample(Example example);    int deleteByExample(Example example);    int deleteByPrimaryKey(ID id);    int insert(T record);    int insertSelective(T record);    List selectByExample(Example example);    T selectByPrimaryKey(ID id);    int updateByExampleSelective(@Param("record") T record, @Param("example") Example example);    int updateByExample(@Param("record") T record, @Param("example") Example example);    int updateByPrimaryKeySelective(T record);    int updateByPrimaryKey(T record);}

2)BaseExample

package cn.xxx.core.base.model;/** * BaseExample 基类 * @ClassName BaseExample * @Description 增加分页参数 * @author Marvis * @date Jul 31, 2017 11:26:53 AM */public abstract class BaseExample {    protected PageInfo pageInfo;    protected String groupByClause;    public PageInfo getPageInfo() {        return pageInfo;    }    public void setPageInfo(PageInfo pageInfo) {        this.pageInfo = pageInfo;    }    public String getGroupByClause() {        return groupByClause;    }    public void setGroupByClause(String groupByClause) {        this.groupByClause = groupByClause;    }}

3)PageInfo

package cn.xxx.core.base.model;import com.fasterxml.jackson.annotation.JsonIgnore;/** * 分页查询参数类 *  * @author * */public class PageInfo {    public static final int Default_PageSize = 20;    // 当前页码    protected int currentPage = 1;    // 总页数    protected int totalPage;    // 总记录数    protected int totalCount;    // 每页条数    protected int pageSize = Default_PageSize;    // 开始    protected int pageBegin = 0;    // 结束    protected int pageEnd = 20;    /**     * bean起始坐标(不包含)     */    private Integer pageBeginId = null;    public static final String PageQuery_classname = "pageInfo";    /**     * 将分布参数传入处理,最终计算出当前页码PageQuery_currPage,开始坐标PageQuery_star,     * 结束坐标PageQuery_end,总页数PageQuery_Psize     * 

* 页数从1开始计数 * * @param totalCount * 记录总数 * @param pageSize * 每页显示个数 * @param currentPage * 当前页码 */ public void setPageParams(int totalCount, int pageSize, int currentPage) { this.totalPage = pageSize == 0 ? 1 : (int) Math.ceil((double) totalCount / (double) pageSize); this.totalCount = totalCount; this.pageSize = pageSize; this.currentPage = currentPage; float Psize_l = totalCount / (float) (this.pageSize); if (currentPage < 2) { currentPage = 1; pageBegin = 0; } else if (currentPage > Psize_l) { if (Psize_l == 0) { currentPage = 1; } else { currentPage = (int) Math.ceil(Psize_l); } pageBegin = (currentPage - 1) * this.pageSize; } else { pageBegin = (currentPage - 1) * this.pageSize; } pageSize = (int) Math.ceil(Psize_l); this.pageEnd = currentPage * this.pageSize; if (this.currentPage <= 0 || this.currentPage > this.totalPage) this.pageSize = 0; } /** * 将分布参数传入处理,最终计算出当前页码PageQuery_currPage,开始坐标PageQuery_star, * 结束坐标PageQuery_end,总页数PageQuery_Psize * * @param infoCount * 记录总数 */ public void setPageParams(int totalCount) { this.setPageParams(totalCount, this.pageSize, this.currentPage); } @Override public String toString() { return "PageInfo [currentPage=" + currentPage + ", totalPage=" + totalPage + ", totalCount=" + totalCount + ", pageSize=" + pageSize + ", pageBegin=" + pageBegin + ", pageEnd=" + pageEnd + ", pageBeginId=" + pageBeginId + "]"; } public int getCurrentPage() { return currentPage; } public int getTotalPage() { return totalPage; } public int getTotalCount() { return totalCount; } /** * 每页显示个数 */ public int getPageSize() { return pageSize; } @JsonIgnore public int getPageBegin() { return pageBegin; } @JsonIgnore public int getPageEnd() { return pageEnd; } /** * bean起始id(不包含) */ @JsonIgnore public Integer getPageBeginId() { return pageBeginId; } /** * 请求页 */ public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } /** * 每页显示个数 */ public void setPageSize(int pageSize) { this.pageSize = pageSize; }}

4)PaginationPlugin

分页扩展。并且Example继承BaseExample

package run.override.pagination;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;import org.mybatis.generator.api.dom.java.TopLevelClass;import org.mybatis.generator.api.dom.xml.Attribute;import org.mybatis.generator.api.dom.xml.TextElement;import org.mybatis.generator.api.dom.xml.XmlElement;import run.override.mapper.SqlMapIsMergeablePlugin;import run.override.proxyFactory.FullyQualifiedJavaTypeProxyFactory;public class PaginationPlugin extends SqlMapIsMergeablePlugin {    @Override    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {        FullyQualifiedJavaType baseExampleType = FullyQualifiedJavaTypeProxyFactory.getBaseExampleInstance();        topLevelClass.setSuperClass(baseExampleType);        topLevelClass.addImportedType(baseExampleType);        return super.modelExampleClassGenerated(topLevelClass, introspectedTable);    }    @Override    public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element,            IntrospectedTable introspectedTable) {        XmlElement isNotNullElement1 = new XmlElement("if");         isNotNullElement1.addAttribute(new Attribute("test", "groupByClause != null"));         isNotNullElement1.addElement(new TextElement("group by ${groupByClause}"));        element.addElement(5, isNotNullElement1);        XmlElement isNotNullElement = new XmlElement("if");        isNotNullElement.addAttribute(new Attribute("test", "pageInfo != null"));         isNotNullElement.addElement(new TextElement("limit #{pageInfo.pageBegin} , #{pageInfo.pageSize}"));        element.addElement(isNotNullElement);        return super.sqlMapUpdateByExampleWithBLOBsElementGenerated(element, introspectedTable);    }    @Override    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,            IntrospectedTable introspectedTable) {        XmlElement isNotNullElement1 = new XmlElement("if");        isNotNullElement1.addAttribute(new Attribute("test", "groupByClause != null"));        isNotNullElement1.addElement(new TextElement("group by ${groupByClause}"));        element.addElement(5, isNotNullElement1);        XmlElement isNotNullElement = new XmlElement("if");         isNotNullElement.addAttribute(new Attribute("test", "pageInfo != null"));        isNotNullElement.addElement(new TextElement("limit #{pageInfo.pageBegin} , #{pageInfo.pageSize}"));        element.addElement(isNotNullElement);        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);    }    @Override    public boolean sqlMapCountByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {        XmlElement answer = new XmlElement("select");        String fqjt = introspectedTable.getExampleType();        answer.addAttribute(new Attribute("id", introspectedTable.getCountByExampleStatementId()));        answer.addAttribute(new Attribute("parameterType", fqjt));        answer.addAttribute(new Attribute("resultType", "java.lang.Integer"));        this.context.getCommentGenerator().addComment(answer);        StringBuilder sb = new StringBuilder();        sb.append("select count(1) from ");        sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());        XmlElement ifElement = new XmlElement("if");        ifElement.addAttribute(new Attribute("test", "_parameter != null"));        XmlElement includeElement = new XmlElement("include");        includeElement.addAttribute(new Attribute("refid", introspectedTable.getExampleWhereClauseId()));        ifElement.addElement(includeElement);        element.getElements().clear();        element.getElements().add(new TextElement(sb.toString()));        element.getElements().add(ifElement);        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);    }}

5)FullyQualifiedJavaTypeProxyFactory

package run.override.proxyFactory;import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;public class FullyQualifiedJavaTypeProxyFactory  extends FullyQualifiedJavaType{    private static FullyQualifiedJavaType pageInfoInstance = new FullyQualifiedJavaType("cn.xxx.core.base.model.PageInfo");    private static FullyQualifiedJavaType baseExampleInstance = new FullyQualifiedJavaType("cn.xxx.core.base.model.BaseExample");    private static FullyQualifiedJavaType baseMapperInstance = new FullyQualifiedJavaType("cn.xxx.core.base.dao.BaseMapper");    private static FullyQualifiedJavaType baseServiceInstance = new FullyQualifiedJavaType("cn.xxx.core.base.service.BaseService");    private static FullyQualifiedJavaType baseServiceImplInstance = new FullyQualifiedJavaType("cn.xxx.core.base.service.impl.BaseServiceImpl");    public FullyQualifiedJavaTypeProxyFactory(String fullTypeSpecification) {        super(fullTypeSpecification);    }    public static final FullyQualifiedJavaType getPageInfoInstanceInstance() {        return pageInfoInstance;    }    public static final FullyQualifiedJavaType getBaseExampleInstance() {        return baseExampleInstance;    }    public static final FullyQualifiedJavaType getBaseMapperInstance() {        return baseMapperInstance;    }    public static final FullyQualifiedJavaType getBaseServiceInstance() {        return baseServiceInstance;    }    public static final FullyQualifiedJavaType getBaseServiceImplInstance() {        return baseServiceImplInstance;    }}

三、Dao 生成代码简化

1)ClientDaoPlugin

package run.override.dao;import java.util.Arrays;import java.util.List;import java.util.stream.Collectors;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.JavaTypeResolver;import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;import org.mybatis.generator.api.dom.java.Interface;import org.mybatis.generator.api.dom.java.Method;import org.mybatis.generator.api.dom.java.TopLevelClass;import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;import run.override.model.EntityCommentPlugin;import run.override.proxyFactory.FullyQualifiedJavaTypeProxyFactory;/** * javaClient("XMLMAPPER") extended *  * @ClassName ClientDaoPlugin * @Description Mapper.java * @author Marvis */public class ClientDaoPlugin extends EntityCommentPlugin {    @Override    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass,            IntrospectedTable introspectedTable) {        JavaTypeResolver javaTypeResolver = new JavaTypeResolverDefaultImpl();        FullyQualifiedJavaType calculateJavaType = javaTypeResolver                .calculateJavaType(introspectedTable.getPrimaryKeyColumns().get(0));        FullyQualifiedJavaType superInterfaceType = new FullyQualifiedJavaType(                new StringBuilder("BaseMapper<")                    .append(introspectedTable.getBaseRecordType())                    .append(",")                    .append(introspectedTable.getExampleType())                    .append(",")                    .append(calculateJavaType.getShortName())                    .append(">")                    .toString()                );        FullyQualifiedJavaType baseMapperInstance = FullyQualifiedJavaTypeProxyFactory.getBaseMapperInstance();        interfaze.addSuperInterface(superInterfaceType);        interfaze.addImportedType(baseMapperInstance);        List changeMethods = interfaze.getMethods().stream()                .filter(method -> method.getName().endsWith("WithBLOBs")                        || method.getReturnType().toString().endsWith("WithBLOBs")                        || Arrays.toString(method.getParameters().toArray()).contains("WithBLOBs"))                .collect(Collectors.toList());        interfaze.getMethods().retainAll(changeMethods);        if (changeMethods.isEmpty())            interfaze.getImportedTypes().removeIf(javaType -> javaType.getFullyQualifiedName().equals("java.util.List")                    || javaType.getFullyQualifiedName().equals("org.apache.ibatis.annotations.Param"));        return super.clientGenerated(interfaze, topLevelClass, introspectedTable);    }}

四、修正

重复生成时Mapper.xml不是覆盖原代码,而是对内容进行了追加。

1)SqlMapIsMergeablePlugin

package run.override.mapper;import org.mybatis.generator.api.GeneratedXmlFile;import org.mybatis.generator.api.IntrospectedTable;import run.override.dao.ClientDaoPlugin;public class SqlMapIsMergeablePlugin extends ClientDaoPlugin {    @Override    public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {        //重新生成代码,xml内容覆盖        sqlMap.setMergeable(false);        return super.sqlMapGenerated(sqlMap, introspectedTable);    }}

五、序列化自定义扩展

增加Example的序列化,并增加@SuppressWarnings("serial")注解。

1)SerializablePlugin

package run.override;import java.util.List;import java.util.Properties;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.java.TopLevelClass;public class SerializablePlugin extends PluginAdapter {    private FullyQualifiedJavaType serializable;    private FullyQualifiedJavaType gwtSerializable;    private boolean addGWTInterface;    private boolean suppressJavaInterface;    public SerializablePlugin() {        this.serializable = new FullyQualifiedJavaType("java.io.Serializable");        this.gwtSerializable = new FullyQualifiedJavaType("com.google.gwt.user.client.rpc.IsSerializable");    }    @Override    public void setProperties(Properties properties) {        super.setProperties(properties);        this.addGWTInterface = Boolean.valueOf(properties.getProperty("addGWTInterface")).booleanValue();        this.suppressJavaInterface = Boolean.valueOf(properties.getProperty("suppressJavaInterface")).booleanValue();    }    @Override    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {        makeSerializable(topLevelClass, introspectedTable);        return true;    }    @Override    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {        makeSerializable(topLevelClass, introspectedTable);        return true;    }    @Override    public boolean modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass,            IntrospectedTable introspectedTable) {        makeSerializable(topLevelClass, introspectedTable);        return true;    }    @Override    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,IntrospectedTable introspectedTable){        makeSerializable(topLevelClass, introspectedTable);        return true;    }    protected void makeSerializable(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {        if (this.addGWTInterface) {            topLevelClass.addImportedType(this.gwtSerializable);            topLevelClass.addSuperInterface(this.gwtSerializable);        }        if (!(this.suppressJavaInterface)) {            topLevelClass.addImportedType(this.serializable);            topLevelClass.addSuperInterface(this.serializable);            topLevelClass.addAnnotation("@SuppressWarnings(\"serial\")");        }    }    /**     * This plugin is always valid - no properties are required     */    @Override    public boolean validate(List warnings) {        return true;    }}

六、服务层代码自定义生成

重写Context,ConfigurationParserMyBatisGeneratorConfigurationParser,增加服务层生成逻辑。

先对Service基类进行介绍。

1)BaseService

package cn.xxx.core.base.service;import java.util.List;import org.apache.ibatis.annotations.Param;import cn.xxx.core.base.model.BaseExample;import cn.xxx.core.base.model.PageInfo;public interface BaseService {    long countByExample(Example example);    int deleteByExample(Example example);    int deleteByPrimaryKey(ID id);    int insert(T record);    int insertSelective(T record);    List selectByExample(Example example);    /**     * return T object     * @author Marvis     * @date May 23, 2018 11:37:11 AM     * @param example     * @return     */    T selectByCondition(Example example);    /**     * if pageInfo == null

* then return result of selectByExample(example) * @author Marvis * @date Jul 13, 2017 5:24:35 PM * @param example * @param pageInfo * @return */ List selectByPageExmple(Example example, PageInfo pageInfo); T selectByPrimaryKey(ID id); int updateByExampleSelective(@Param("record") T record, @Param("example") Example example); int updateByExample(@Param("record") T record, @Param("example") Example example); int updateByPrimaryKeySelective(T record); int updateByPrimaryKey(T record);}

2)BaseServiceImpl

package cn.xxx.core.base.service.impl;import java.util.List;import cn.xxx.core.base.dao.BaseMapper;import cn.xxx.core.base.model.BaseExample;import cn.xxx.core.base.model.PageInfo;import cn.xxx.core.base.service.BaseService;public abstract class BaseServiceImpl implements BaseService {    private BaseMapper mapper;    public void setMapper(BaseMapper mapper) {        this.mapper = mapper;    }    public long countByExample(Example example) {        return mapper.countByExample(example);    }    @Override    public int deleteByExample(Example example) {        return mapper.deleteByExample(example);    }    @Override    public int deleteByPrimaryKey(ID id) {        return mapper.deleteByPrimaryKey(id);    }    @Override    public int insert(T record) {        return mapper.insert(record);    }    @Override    public int insertSelective(T record) {        return mapper.insertSelective(record);    }    @Override    public List selectByExample(Example example) {        return mapper.selectByExample(example);    }    @Override    public T selectByCondition(Example example) {        List datas = selectByExample(example);        return datas != null && datas.size() == 0 ? null : datas.get(0);    }    @Override    public List selectByPageExmple(Example example, PageInfo pageInfo) {        if(pageInfo != null){            example.setPageInfo(pageInfo);            pageInfo.setPageParams(Long.valueOf(this.countByExample(example)).intValue());        }        return this.selectByExample(example);    }    @Override    public T selectByPrimaryKey(ID id) {        return mapper.selectByPrimaryKey(id);    }    @Override    public int updateByExampleSelective(T record, Example example) {        return mapper.updateByExampleSelective(record, example);    }    @Override    public int updateByExample(T record, Example example) {        return mapper.updateByExample(record, example);    }    @Override    public int updateByPrimaryKeySelective(T record) {        return mapper.updateByPrimaryKeySelective(record);    }    @Override    public int updateByPrimaryKey(T record) {        return mapper.updateByPrimaryKey(record);    }}

3)ServiceLayerPlugin

package run.override.service;import org.mybatis.generator.api.GeneratedJavaFile;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.JavaTypeResolver;import org.mybatis.generator.api.dom.java.CompilationUnit;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.Parameter;import org.mybatis.generator.api.dom.java.TopLevelClass;import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;import run.override.pagination.PaginationPlugin;import run.override.proxyFactory.FullyQualifiedJavaTypeProxyFactory;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;public class ServiceLayerPlugin extends PaginationPlugin {    /**     * 生成额外java文件     */    @Override    public List contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {        ContextOverride context = (ContextOverride) introspectedTable.getContext();        ServiceGeneratorConfiguration serviceGeneratorConfiguration;        if ((serviceGeneratorConfiguration = context.getServiceGeneratorConfiguration()) == null)            return null;        String targetPackage = serviceGeneratorConfiguration.getTargetPackage();        String targetProject = serviceGeneratorConfiguration.getTargetProject();        String implementationPackage = serviceGeneratorConfiguration.getImplementationPackage();        CompilationUnit addServiceInterface = addServiceInterface(introspectedTable, targetPackage);        CompilationUnit addServiceImplClazz = addServiceImplClazz(introspectedTable, targetPackage,                implementationPackage);        GeneratedJavaFile gjfServiceInterface = new GeneratedJavaFile(addServiceInterface, targetProject,                this.context.getProperty("javaFileEncoding"), this.context.getJavaFormatter());        GeneratedJavaFile gjfServiceImplClazz = new GeneratedJavaFile(addServiceImplClazz, targetProject,                this.context.getProperty("javaFileEncoding"), this.context.getJavaFormatter());        List list = new ArrayList<>();        list.add(gjfServiceInterface);        list.add(gjfServiceImplClazz);        return list;    }    protected CompilationUnit addServiceInterface(IntrospectedTable introspectedTable, String targetPackage) {        String entityClazzType = introspectedTable.getBaseRecordType();        String serviceSuperPackage = targetPackage;        String entityExampleClazzType = introspectedTable.getExampleType();        String domainObjectName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();        JavaTypeResolver javaTypeResolver = new JavaTypeResolverDefaultImpl();        FullyQualifiedJavaType calculateJavaType = javaTypeResolver                .calculateJavaType(introspectedTable.getPrimaryKeyColumns().get(0));        StringBuilder builder = new StringBuilder();        FullyQualifiedJavaType superInterfaceType = new FullyQualifiedJavaType(                builder.append("BaseService<")                        .append(entityClazzType)                        .append(",")                        .append(entityExampleClazzType)                        .append(",")                        .append(calculateJavaType.getShortName()).append(">").toString());        Interface serviceInterface = new Interface(                builder.delete(0, builder.length())                        .append(serviceSuperPackage)                        .append(".")                        .append(domainObjectName)                        .append("Service")                        .toString()        );        serviceInterface.addSuperInterface(superInterfaceType);        serviceInterface.setVisibility(JavaVisibility.PUBLIC);        FullyQualifiedJavaType baseServiceInstance = FullyQualifiedJavaTypeProxyFactory.getBaseServiceInstance();        FullyQualifiedJavaType modelJavaType = new FullyQualifiedJavaType(entityClazzType);        FullyQualifiedJavaType exampleJavaType = new FullyQualifiedJavaType(entityExampleClazzType);        serviceInterface.addImportedType(baseServiceInstance);        serviceInterface.addImportedType(modelJavaType);        serviceInterface.addImportedType(exampleJavaType);        serviceInterface.addFileCommentLine("/*** copyright (c) 2019 Marvis  ***/");        this.additionalServiceMethods(introspectedTable, serviceInterface);        return serviceInterface;    }    protected CompilationUnit addServiceImplClazz(IntrospectedTable introspectedTable, String targetPackage,                                                  String implementationPackage) {        String entityClazzType = introspectedTable.getBaseRecordType();        String serviceSuperPackage = targetPackage;        String serviceImplSuperPackage = implementationPackage;        String entityExampleClazzType = introspectedTable.getExampleType();        String javaMapperType = introspectedTable.getMyBatis3JavaMapperType();        String domainObjectName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();        JavaTypeResolver javaTypeResolver = new JavaTypeResolverDefaultImpl();        FullyQualifiedJavaType calculateJavaType = javaTypeResolver                .calculateJavaType(introspectedTable.getPrimaryKeyColumns().get(0));        StringBuilder builder = new StringBuilder();        FullyQualifiedJavaType superClazzType = new FullyQualifiedJavaType(                builder.append("BaseServiceImpl<")                        .append(entityClazzType)                        .append(",")                        .append(entityExampleClazzType)                        .append(",")                        .append(calculateJavaType.getShortName()).append(">")                        .toString()        );        FullyQualifiedJavaType implInterfaceType = new FullyQualifiedJavaType(                builder.delete(0, builder.length())                        .append(serviceSuperPackage)                        .append(".")                        .append(domainObjectName)                        .append("Service")                        .toString()        );        TopLevelClass serviceImplClazz = new TopLevelClass(                builder.delete(0, builder.length())                        .append(serviceImplSuperPackage)                        .append(".")                        .append(domainObjectName)                        .append("ServiceImpl")                        .toString()        );        serviceImplClazz.addSuperInterface(implInterfaceType);        serviceImplClazz.setSuperClass(superClazzType);        serviceImplClazz.setVisibility(JavaVisibility.PUBLIC);        serviceImplClazz.addAnnotation("@Service");        FullyQualifiedJavaType baseServiceInstance = FullyQualifiedJavaTypeProxyFactory.getBaseServiceImplInstance();        FullyQualifiedJavaType modelJavaType = new FullyQualifiedJavaType(entityClazzType);        FullyQualifiedJavaType exampleJavaType = new FullyQualifiedJavaType(entityExampleClazzType);        serviceImplClazz                .addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));        serviceImplClazz.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Service"));        serviceImplClazz.addImportedType(baseServiceInstance);        serviceImplClazz.addImportedType(modelJavaType);        serviceImplClazz.addImportedType(exampleJavaType);        serviceImplClazz.addImportedType(implInterfaceType);        FullyQualifiedJavaType logType = new FullyQualifiedJavaType("org.slf4j.Logger");        FullyQualifiedJavaType logFactoryType = new FullyQualifiedJavaType("org.slf4j.LoggerFactory");        Field logField = new Field();        logField.setVisibility(JavaVisibility.PRIVATE);        logField.setStatic(true);        logField.setFinal(true);        logField.setType(logType);        logField.setName("logger");        logField.setInitializationString(                builder.delete(0, builder.length())                        .append("LoggerFactory.getLogger(")                        .append(domainObjectName)                        .append("ServiceImpl.class)")                        .toString()        );        logField.addAnnotation("");        logField.addAnnotation("@SuppressWarnings(\"unused\")");        serviceImplClazz.addField(logField);        serviceImplClazz.addImportedType(logType);        serviceImplClazz.addImportedType(logFactoryType);        String mapperName = builder.delete(0, builder.length())                .append(Character.toLowerCase(domainObjectName.charAt(0)))                .append(domainObjectName.substring(1))                .append("Mapper")                .toString();        FullyQualifiedJavaType JavaMapperType = new FullyQualifiedJavaType(javaMapperType);        Field mapperField = new Field();        mapperField.setVisibility(JavaVisibility.PUBLIC);        mapperField.setType(JavaMapperType);// Mapper.java        mapperField.setName(mapperName);        mapperField.addAnnotation("@Autowired");        serviceImplClazz.addField(mapperField);        serviceImplClazz.addImportedType(JavaMapperType);        Method mapperMethod = new Method();        mapperMethod.setVisibility(JavaVisibility.PUBLIC);        mapperMethod.setName("setMapper");        mapperMethod.addBodyLine("super.setMapper(" + mapperName + ");");        mapperMethod.addAnnotation("@Autowired");        serviceImplClazz.addMethod(mapperMethod);        serviceImplClazz.addFileCommentLine("/*** copyright (c) 2019 Marvis  ***/");        serviceImplClazz                .addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));        this.additionalServiceImplMethods(introspectedTable, serviceImplClazz, mapperName);        return serviceImplClazz;    }    protected void additionalServiceMethods(IntrospectedTable introspectedTable, Interface serviceInterface) {        if (this.notHasBLOBColumns(introspectedTable))            return;        introspectedTable.getGeneratedJavaFiles().stream().filter(file -> file.getCompilationUnit().isJavaInterface()                && file.getCompilationUnit().getType().getShortName().endsWith("Mapper")).map(GeneratedJavaFile::getCompilationUnit).forEach(                compilationUnit -> ((Interface) compilationUnit).getMethods().forEach(                        m -> serviceInterface.addMethod(this.additionalServiceLayerMethod(serviceInterface, m))));    }    protected void additionalServiceImplMethods(IntrospectedTable introspectedTable, TopLevelClass clazz,                                                String mapperName) {        if (this.notHasBLOBColumns(introspectedTable))            return;        introspectedTable.getGeneratedJavaFiles().stream().filter(file -> file.getCompilationUnit().isJavaInterface()                && file.getCompilationUnit().getType().getShortName().endsWith("Mapper")).map(GeneratedJavaFile::getCompilationUnit).forEach(                compilationUnit -> ((Interface) compilationUnit).getMethods().forEach(m -> {                    Method serviceImplMethod = this.additionalServiceLayerMethod(clazz, m);                    serviceImplMethod.addAnnotation("@Override");                    serviceImplMethod.addBodyLine(this.generateBodyForServiceImplMethod(mapperName, m));                    clazz.addMethod(serviceImplMethod);                }));    }    private boolean notHasBLOBColumns(IntrospectedTable introspectedTable) {        return !introspectedTable.hasBLOBColumns();    }    private Method additionalServiceLayerMethod(CompilationUnit compilation, Method m) {        Method method = new Method();        method.setVisibility(JavaVisibility.PUBLIC);        method.setName(m.getName());        List parameters = m.getParameters();        method.getParameters().addAll(parameters.stream().peek(param -> param.getAnnotations().clear()).collect(Collectors.toList()));        method.setReturnType(m.getReturnType());        compilation.addImportedType(                new FullyQualifiedJavaType(m.getReturnType().getFullyQualifiedNameWithoutTypeParameters()));        return method;    }    private String generateBodyForServiceImplMethod(String mapperName, Method m) {        StringBuilder sbf = new StringBuilder("return ");        sbf.append(mapperName).append(".").append(m.getName()).append("(");        boolean singleParam = true;        for (Parameter parameter : m.getParameters()) {            if (singleParam)                singleParam = !singleParam;            else                sbf.append(", ");            sbf.append(parameter.getName());        }        sbf.append(");");        return sbf.toString();    }}

4)ContextOverride

package run.override.service;import java.util.List;import org.mybatis.generator.api.dom.xml.XmlElement;import org.mybatis.generator.config.Context;import org.mybatis.generator.config.ModelType;public class ContextOverride extends Context{    //添加ServiceGeneratorConfiguration    private ServiceGeneratorConfiguration serviceGeneratorConfiguration;    public ContextOverride(ModelType defaultModelType) {        super(defaultModelType);    }    public ServiceGeneratorConfiguration getServiceGeneratorConfiguration() {        return serviceGeneratorConfiguration;    }    public void setServiceGeneratorConfiguration(ServiceGeneratorConfiguration serviceGeneratorConfiguration) {        this.serviceGeneratorConfiguration = serviceGeneratorConfiguration;    }    @Override    public void validate(List errors) {        if(serviceGeneratorConfiguration != null)            serviceGeneratorConfiguration.validate(errors, this.getId());        super.validate(errors);    }    public XmlElement toXmlElement() {        XmlElement xmlElement = super.toXmlElement();        if (serviceGeneratorConfiguration != null)            xmlElement.addElement(serviceGeneratorConfiguration.toXmlElement());        return xmlElement;    }}

5)MyBatisGeneratorConfigurationParserOverride

package run.override.service;import java.util.Properties;import org.mybatis.generator.config.Configuration;import org.mybatis.generator.config.Context;import org.mybatis.generator.config.JavaClientGeneratorConfiguration;import org.mybatis.generator.config.ModelType;import org.mybatis.generator.config.PluginConfiguration;import org.mybatis.generator.config.xml.MyBatisGeneratorConfigurationParser;import org.mybatis.generator.exception.XMLParserException;import org.mybatis.generator.internal.util.StringUtility;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;public class MyBatisGeneratorConfigurationParserOverride extends MyBatisGeneratorConfigurationParser {    public MyBatisGeneratorConfigurationParserOverride(Properties extraProperties) {        super(extraProperties);    }    private void parseJavaServiceGenerator(Context context, Node node) {        ContextOverride contextOverride = ContextOverride.class.cast(context); ////替换Context        ServiceGeneratorConfiguration serviceGeneratorConfiguration = new ServiceGeneratorConfiguration();        contextOverride.setServiceGeneratorConfiguration(serviceGeneratorConfiguration);        Properties attributes = parseAttributes(node);        String targetPackage = attributes.getProperty("targetPackage");        String targetProject = attributes.getProperty("targetProject");        String implementationPackage = attributes.getProperty("implementationPackage");        serviceGeneratorConfiguration.setTargetPackage(targetPackage);        serviceGeneratorConfiguration.setTargetProject(targetProject);        serviceGeneratorConfiguration.setImplementationPackage(implementationPackage);        NodeList nodeList = node.getChildNodes();        for (int i = 0; i < nodeList.getLength(); i++) {            Node childNode = nodeList.item(i);            if (childNode.getNodeType() == Node.ELEMENT_NODE && "property".equals(childNode.getNodeName()))                parseProperty(serviceGeneratorConfiguration, childNode);        }    }    @Override    public Configuration parseConfiguration(Element rootNode) throws XMLParserException {        Configuration configuration = new Configuration();        NodeList nodeList = rootNode.getChildNodes();        for (int i = 0; i < nodeList.getLength(); ++i) {            Node childNode = nodeList.item(i);            if (childNode.getNodeType() != 1) {                continue;            }            if ("properties".equals(childNode.getNodeName()))                parseProperties(configuration, childNode);            else if ("classPathEntry".equals(childNode.getNodeName()))                parseClassPathEntry(configuration, childNode);            else if ("context".equals(childNode.getNodeName())) {                parseContext(configuration, childNode);            }        }        return configuration;    }    private void parseContext(Configuration configuration, Node node) {        Properties attributes = parseAttributes(node);        String defaultModelType = attributes.getProperty("defaultModelType");        String targetRuntime = attributes.getProperty("targetRuntime");        String introspectedColumnImpl = attributes.getProperty("introspectedColumnImpl");        String id = attributes.getProperty("id");        ModelType mt = defaultModelType != null ? ModelType.getModelType(defaultModelType) : null;        Context context = new ContextOverride(mt);        context.setId(id);        if (StringUtility.stringHasValue(introspectedColumnImpl))            context.setIntrospectedColumnImpl(introspectedColumnImpl);        if (StringUtility.stringHasValue(targetRuntime))            context.setTargetRuntime(targetRuntime);        configuration.addContext(context);        NodeList nodeList = node.getChildNodes();        for (int i = 0; i < nodeList.getLength(); i++) {            Node childNode = nodeList.item(i);            if (childNode.getNodeType() != 1)                continue;            if ("property".equals(childNode.getNodeName())) {                parseProperty(context, childNode);                continue;            }            if ("plugin".equals(childNode.getNodeName())) {                parsePlugin(context, childNode);                continue;            }            if ("commentGenerator".equals(childNode.getNodeName())) {                parseCommentGenerator(context, childNode);                continue;            }            if ("jdbcConnection".equals(childNode.getNodeName())) {                parseJdbcConnection(context, childNode);                continue;            }            if ("connectionFactory".equals(childNode.getNodeName())) {                parseConnectionFactory(context, childNode);                continue;            }            if ("javaModelGenerator".equals(childNode.getNodeName())) {                parseJavaModelGenerator(context, childNode);                continue;            }            if ("javaTypeResolver".equals(childNode.getNodeName())) {                parseJavaTypeResolver(context, childNode);                continue;            }            if ("sqlMapGenerator".equals(childNode.getNodeName())) {                parseSqlMapGenerator(context, childNode);                continue;            }            if ("javaClientGenerator".equals(childNode.getNodeName())) {                parseJavaClientGenerator(context, childNode);                continue;            }            if ("javaServiceGenerator".equals(childNode.getNodeName())) {                parseJavaServiceGenerator(context, childNode);                continue;            }            if ("table".equals(childNode.getNodeName()))                parseTable(context, childNode);        }    }    private void parsePlugin(Context context, Node node) {        PluginConfiguration pluginConfiguration = new PluginConfiguration();        context.addPluginConfiguration(pluginConfiguration);        Properties attributes = parseAttributes(node);        String type = attributes.getProperty("type");        pluginConfiguration.setConfigurationType(type);        NodeList nodeList = node.getChildNodes();        for (int i = 0; i < nodeList.getLength(); i++) {            Node childNode = nodeList.item(i);            if (childNode.getNodeType() == 1 && "property".equals(childNode.getNodeName()))                parseProperty(pluginConfiguration, childNode);        }    }    private void parseJavaClientGenerator(Context context, Node node) {        JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();        context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);        Properties attributes = parseAttributes(node);        String type = attributes.getProperty("type");        String targetPackage = attributes.getProperty("targetPackage");        String targetProject = attributes.getProperty("targetProject");        String implementationPackage = attributes.getProperty("implementationPackage");        javaClientGeneratorConfiguration.setConfigurationType(type);        javaClientGeneratorConfiguration.setTargetPackage(targetPackage);        javaClientGeneratorConfiguration.setTargetProject(targetProject);        javaClientGeneratorConfiguration.setImplementationPackage(implementationPackage);        NodeList nodeList = node.getChildNodes();        for (int i = 0; i < nodeList.getLength(); i++) {            Node childNode = nodeList.item(i);            if (childNode.getNodeType() == 1 && "property".equals(childNode.getNodeName()))                parseProperty(javaClientGeneratorConfiguration, childNode);        }    }}

6)ServiceGeneratorConfiguration

package run.override.service;import java.util.List;import org.mybatis.generator.api.dom.xml.Attribute;import org.mybatis.generator.api.dom.xml.XmlElement;import org.mybatis.generator.config.PropertyHolder;import org.mybatis.generator.internal.util.StringUtility;import org.mybatis.generator.internal.util.messages.Messages;public class ServiceGeneratorConfiguration extends PropertyHolder {    private String targetPackage;    private String implementationPackage;    private String targetProject;    /**     *     */    public ServiceGeneratorConfiguration() {        super();    }    public String getTargetPackage() {        return targetPackage;    }    public void setTargetPackage(String targetPackage) {        this.targetPackage = targetPackage;    }    public String getImplementationPackage() {        return implementationPackage;    }    public void setImplementationPackage(String implementationPackage) {        this.implementationPackage = implementationPackage;    }    public String getTargetProject() {        return targetProject;    }    public void setTargetProject(String targetProject) {        this.targetProject = targetProject;    }    public XmlElement toXmlElement() {        XmlElement answer = new XmlElement("javaServiceGenerator");         if (targetPackage != null) {            answer.addAttribute(new Attribute("targetPackage", targetPackage));         }        if (implementationPackage != null) {            answer.addAttribute(new Attribute("implementationPackage", targetPackage));         }        if (targetProject != null) {            answer.addAttribute(new Attribute("targetProject", targetProject));         }        addPropertyXmlElements(answer);        return answer;    }    @SuppressWarnings({ "rawtypes", "unchecked" })    public void validate(List errors, String contextId) {        if (!StringUtility.stringHasValue(getTargetProject()))            errors.add(Messages.getString("ValidationError.102", contextId));        if (!StringUtility.stringHasValue(getTargetPackage()))            errors.add(Messages.getString("ValidationError.112", "ServiceGenerator", contextId));        if (!StringUtility.stringHasValue(getImplementationPackage()))            errors.add(Messages.getString("ValidationError.120", contextId));    }}

7)ConfigurationParserOverride

package run.override.service;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import java.util.ArrayList;import java.util.List;import java.util.Properties;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.mybatis.generator.config.Configuration;import org.mybatis.generator.config.xml.ConfigurationParser;import org.mybatis.generator.config.xml.MyBatisGeneratorConfigurationParser;import org.mybatis.generator.config.xml.ParserEntityResolver;import org.mybatis.generator.config.xml.ParserErrorHandler;import org.mybatis.generator.exception.XMLParserException;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;public class ConfigurationParserOverride extends ConfigurationParser {    private List warnings;    private List parseErrors;    private Properties extraProperties;    public ConfigurationParserOverride(List warnings) {        this(null, warnings);    }    public ConfigurationParserOverride(Properties extraProperties, List warnings) {        super(extraProperties, warnings);        this.extraProperties = extraProperties;        if (warnings == null)            this.warnings = new ArrayList<>();        else {            this.warnings = warnings;        }        this.parseErrors = new ArrayList<>();    }    @Override    public Configuration parseConfiguration(File inputFile) throws IOException, XMLParserException {        FileReader fr = new FileReader(inputFile);        return parseConfiguration(fr);    }    @Override    public Configuration parseConfiguration(InputStream inputStream) throws IOException, XMLParserException {        InputSource is = new InputSource(inputStream);        return parseConfiguration(is);    }    @Override    public Configuration parseConfiguration(Reader reader) throws IOException, XMLParserException {        InputSource is = new InputSource(reader);        return parseConfiguration(is);    }    private Configuration parseConfiguration(InputSource inputSource) throws IOException, XMLParserException {        this.parseErrors.clear();        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();        factory.setValidating(true);        try {            DocumentBuilder builder = factory.newDocumentBuilder();            builder.setEntityResolver(new ParserEntityResolver());            ParserErrorHandler handler = new ParserErrorHandler(this.warnings, this.parseErrors);            builder.setErrorHandler(handler);            Document document = null;            try {                document = builder.parse(inputSource);            } catch (SAXParseException e) {                throw new XMLParserException(this.parseErrors);            } catch (SAXException e) {                if (e.getException() == null)                    this.parseErrors.add(e.getMessage());                else {                    this.parseErrors.add(e.getException().getMessage());                }            }            if (this.parseErrors.size() > 0) {                throw new XMLParserException(this.parseErrors);            }            Element rootNode = document.getDocumentElement();            Configuration config = parseMyBatisGeneratorConfiguration(rootNode);            if (this.parseErrors.size() > 0) {                throw new XMLParserException(this.parseErrors);            }            return config;        } catch (ParserConfigurationException e) {            this.parseErrors.add(e.getMessage());            throw new XMLParserException(this.parseErrors);        }    }    private Configuration parseMyBatisGeneratorConfiguration(Element rootNode) throws XMLParserException {        //替换MyBatisGeneratorConfigurationParser        MyBatisGeneratorConfigurationParser parser = new MyBatisGeneratorConfigurationParserOverride(                this.extraProperties);        return parser.parseConfiguration(rootNode);    }}

七、PluginChain

通过继承,把以上扩展Plugin串起来(SerializablePlugin一些项目中可能不需要,故不加入Chain。同时,其他也可以根据需要对Chain进行更改)。

package run.override;import run.override.service.ServiceLayerPlugin;public class PluginChain extends ServiceLayerPlugin {}

八、generatorConfig.xml

增加javaServiceGenerator相关配置标签。本文使用内部DTD做示例,亦可通过外部DTD或xsd来实现。

1)generatorConfig.xml

 ]  >                                                                                                                                                                                                                                                                   

九、main启动

 package run.generator;import java.io.File;import java.util.ArrayList;import java.util.List;import org.mybatis.generator.api.MyBatisGenerator;import org.mybatis.generator.config.Configuration;import org.mybatis.generator.internal.DefaultShellCallback;import run.override.service.ConfigurationParserOverride;public class Generator {    public void generator() throws Exception{        List warnings = new ArrayList();        boolean overwrite = true;        File configFile = new File("generatorConfig.xml");        //替换ConfigurationParser        ConfigurationParserOverride cp = new ConfigurationParserOverride(warnings);        Configuration config = cp.parseConfiguration(configFile);        DefaultShellCallback callback = new DefaultShellCallback(overwrite);        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);        myBatisGenerator.generate(null);    }     public static void main(String[] args) throws Exception {        try {            Generator generator = new Generator();            generator.generator();        } catch (Exception e) {            e.printStackTrace();        }    }}

关于什么是Mybatis-Generator扩展自定义生成就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0