温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-09-13 16:03:55 来源:亿速云 阅读:270 作者:柒染 栏目:MySQL数据库

这篇文章给大家介绍什么是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()+ "<p/>");         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()+ "<p/>");         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()+ "<p/>");         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 + "<p/>");         topLevelClass.addJavaDocLine(" * " + table.toString() + "<p/>");         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<String> 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<T, Example, ID> {     long countByExample(Example example);     int deleteByExample(Example example);     int deleteByPrimaryKey(ID id);     int insert(T record);     int insertSelective(T record);     List<T> 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      * <p/>      * 页数从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<Method> 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<String> 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<T, Example extends BaseExample, ID> {     long countByExample(Example example);     int deleteByExample(Example example);     int deleteByPrimaryKey(ID id);     int insert(T record);     int insertSelective(T record);     List<T> 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<p/>      * then return result of selectByExample(example)      * @author Marvis      * @date Jul 13, 2017 5:24:35 PM      * @param example      * @param pageInfo      * @return      */     List<T> 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<T, Example extends BaseExample, ID> implements BaseService<T, Example, ID> {     private BaseMapper<T, Example, ID> mapper;     public void setMapper(BaseMapper<T, Example, ID> 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<T> selectByExample(Example example) {         return mapper.selectByExample(example);     }     @Override     public T selectByCondition(Example example) {         List<T> datas = selectByExample(example);         return datas != null && datas.size() == 0 ? null : datas.get(0);     }     @Override     public List<T> 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<GeneratedJavaFile> 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<GeneratedJavaFile> 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<Parameter> 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<String> 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<String> warnings;     private List<String> parseErrors;     private Properties extraProperties;     public ConfigurationParserOverride(List<String> warnings) {         this(null, warnings);     }     public ConfigurationParserOverride(Properties extraProperties, List<String> 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

<?xml version="1.0" encoding="UTF-8"?> <!-- 内部DTD 亦可通过外部DTD来实现--> <!DOCTYPE generatorConfiguration   [ <!ELEMENT generatorConfiguration (properties?, classPathEntry*, context+)> <!ELEMENT properties EMPTY> <!ATTLIST properties   resource CDATA #IMPLIED   url CDATA #IMPLIED> <!--     括号里是声明出现的次序:     *: 出现任意次,包括0次     ?: 出现最多一次     |:选择之一     +: 出现最少1次     如果没有上述符号:必须且只能出现一次  --> <!ELEMENT context (property*, plugin*, commentGenerator?, (connectionFactory | jdbcConnection), javaTypeResolver?,                          javaModelGenerator, sqlMapGenerator, javaClientGenerator, javaServiceGenerator,table+)> <!ATTLIST context id ID #REQUIRED   defaultModelType CDATA #IMPLIED   targetRuntime CDATA #IMPLIED   introspectedColumnImpl CDATA #IMPLIED> <!ELEMENT connectionFactory (property*)> <!ATTLIST connectionFactory   type CDATA #IMPLIED> <!ELEMENT jdbcConnection (property*)> <!ATTLIST jdbcConnection    driverClass CDATA #REQUIRED   connectionURL CDATA #REQUIRED   userId CDATA #IMPLIED   password CDATA #IMPLIED> <!ELEMENT classPathEntry EMPTY> <!ATTLIST classPathEntry   location CDATA #REQUIRED> <!ELEMENT property EMPTY> <!ATTLIST property   name CDATA #REQUIRED   value CDATA #REQUIRED> <!ELEMENT plugin (property*)> <!ATTLIST plugin   type CDATA #REQUIRED> <!ELEMENT javaModelGenerator (property*)> <!ATTLIST javaModelGenerator   targetPackage CDATA #REQUIRED   targetProject CDATA #REQUIRED> <!ELEMENT javaTypeResolver (property*)> <!ATTLIST javaTypeResolver   type CDATA #IMPLIED> <!ELEMENT sqlMapGenerator (property*)> <!ATTLIST sqlMapGenerator   targetPackage CDATA #REQUIRED   targetProject CDATA #REQUIRED> <!ELEMENT javaClientGenerator (property*)> <!ATTLIST javaClientGenerator   type CDATA #REQUIRED   targetPackage CDATA #REQUIRED   targetProject CDATA #REQUIRED   implementationPackage CDATA #IMPLIED> <!ELEMENT javaServiceGenerator (property*)> <!ATTLIST javaServiceGenerator         targetPackage CDATA #REQUIRED         implementationPackage CDATA #REQUIRED         targetProject CDATA #REQUIRED> <!ELEMENT table (property*, generatedKey?, domainObjectRenamingRule?, columnRenamingRule?, (columnOverride | ignoreColumn | ignoreColumnsByRegex)*) > <!ATTLIST table   catalog CDATA #IMPLIED   schema CDATA #IMPLIED   tableName CDATA #REQUIRED   alias CDATA #IMPLIED   domainObjectName CDATA #IMPLIED   mapperName CDATA #IMPLIED   sqlProviderName CDATA #IMPLIED   enableInsert CDATA #IMPLIED   enableSelectByPrimaryKey CDATA #IMPLIED   enableSelectByExample CDATA #IMPLIED   enableUpdateByPrimaryKey CDATA #IMPLIED   enableDeleteByPrimaryKey CDATA #IMPLIED   enableDeleteByExample CDATA #IMPLIED   enableCountByExample CDATA #IMPLIED   enableUpdateByExample CDATA #IMPLIED   selectByPrimaryKeyQueryId CDATA #IMPLIED   selectByExampleQueryId CDATA #IMPLIED   modelType CDATA #IMPLIED   escapeWildcards CDATA #IMPLIED   delimitIdentifiers CDATA #IMPLIED   delimitAllColumns CDATA #IMPLIED> <!ELEMENT columnOverride (property*)> <!ATTLIST columnOverride   column CDATA #REQUIRED   property CDATA #IMPLIED   javaType CDATA #IMPLIED   jdbcType CDATA #IMPLIED   typeHandler CDATA #IMPLIED   isGeneratedAlways CDATA #IMPLIED   delimitedColumnName CDATA #IMPLIED> <!ELEMENT ignoreColumn EMPTY> <!ATTLIST ignoreColumn   column CDATA #REQUIRED   delimitedColumnName CDATA #IMPLIED> <!ELEMENT ignoreColumnsByRegex (except*)> <!ATTLIST ignoreColumnsByRegex   pattern CDATA #REQUIRED> <!ELEMENT except EMPTY> <!ATTLIST except   column CDATA #REQUIRED   delimitedColumnName CDATA #IMPLIED> <!ELEMENT generatedKey EMPTY> <!ATTLIST generatedKey   column CDATA #REQUIRED   sqlStatement CDATA #REQUIRED   identity CDATA #IMPLIED   type CDATA #IMPLIED> <!ELEMENT domainObjectRenamingRule EMPTY> <!ATTLIST domainObjectRenamingRule   searchString CDATA #REQUIRED   replaceString CDATA #IMPLIED> <!ELEMENT columnRenamingRule EMPTY> <!ATTLIST columnRenamingRule   searchString CDATA #REQUIRED   replaceString CDATA #IMPLIED> <!ELEMENT commentGenerator (property*)> <!ATTLIST commentGenerator   type CDATA #IMPLIED>  ]   > <generatorConfiguration>      <context id="ables" targetRuntime="MyBatis3">                 <!--                     添加Plugin                -->         <plugin type="run.override.PluginChain" />         <plugin type="run.override.SerializablePlugin" />         <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />         <commentGenerator type="run.override.CommentGenerator"/>         <jdbcConnection driverClass="com.mysql.jdbc.Driver"             connectionURL="jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxx?characterEncoding=utf8"             userId="xxx" password="xxx">         </jdbcConnection>         <javaTypeResolver>             <property name="forceBigDecimals" value="false" />         </javaTypeResolver>         <javaModelGenerator targetPackage="cn.xxx.elecsign.model" targetProject=".\src">             <property name="enableSubPackages" value="false" />             <property name="trimStrings" value="true" />         </javaModelGenerator>         <sqlMapGenerator targetPackage="mapper.cn.xxx.elecsign.dao" targetProject=".\src">             <property name="enableSubPackages" value="false" />         </sqlMapGenerator>         <javaClientGenerator type="XMLMAPPER" targetPackage="cn.xxx.elecsign.dao" targetProject=".\src">             <property name="enableSubPackages" value="false" />         </javaClientGenerator>               <!-- javaServiceGenerator  -->         <javaServiceGenerator  targetPackage="cn.xxx.elecsign.dly.service"                  implementationPackage = "cn.xxx.elecsign.dly.service.impl" targetProject=".\src">             <property name="enableSubPackages" value="false" />         </javaServiceGenerator>         <!-- 批次表,针对批量的异步操作 -->         <table tableName="table" domainObjectName="Table"              alias="table">             <generatedKey column="id" sqlStatement="MySql" identity="true" />         </table>     </context> </generatorConfiguration>

九、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<String> warnings = new ArrayList<String>();         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扩展自定义生成就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI