iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >代码演示Mybatis-Generator 扩展自定义生成
  • 544
分享到

代码演示Mybatis-Generator 扩展自定义生成

代码演示Mybatis-Generator扩展自定义生成 2020-05-21 23:05:44 544人浏览 猪猪侠
摘要

生成的注释不是我们想要的,我们期望的是根据数据库表、字段生成不同的注释; 分页代码生成缺失,每个公司的分页方式不同,尤其是老久项目或已发布api,不能随意变动,那么如何自适应分页代码生成; Mapper.xml没有group by相关代码

代码演示Mybatis-Generator 扩展自定义生成

  • 生成的注释不是我们想要的,我们期望的是根据数据库表、字段生成不同的注释;
  • 分页代码生成缺失,每个公司的分页方式不同,尤其是老久项目或已发布api,不能随意变动,那么如何自适应分页代码生成;
  • Mapper.xml没有group by相关代码生成;
  • 重复生成代码时,Mapper.xml并不是覆盖原代码,而是对内容进行了追加;
  • 序列化,mybatis-generator内置了SerializablePlugin,但仅对Model,并没有对 Example序列化,在一些开发中是不够的;
  • 对Service Layer代码没有生成。

实际上,mybatis-generator提供了PluginAdapter供我们来继承,进行个性化的一些扩展(Plugin的相关内容是阅读本文的前置条件)如果不熟悉的同学,请自行补充,本文不对其进行相关介绍)。同时,本文不可能涵盖所有业务所需的扩展点,但是基本样板已有,可参考本文代码继续进行扩展。

一、注释的自定义生成

根据数据库表或字段的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;

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("");
	}
	
	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();
	}
	
	public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
		if (this.suppressAllComments) {
			return;
		}

		innerClass.addJavaDocLine("");
	}

	public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
		if (this.suppressAllComments) {
			return;
		}

		StringBuilder sb = new StringBuilder();

		innerEnum.addJavaDocLine("");
	}
	
	public void addFieldComment(Field field, IntrospectedTable introspectedTable,
			IntrospectedColumn introspectedColumn) {
		if (this.suppressAllComments) {
			return;
		}

//		if(introspectedColumn.getRemarks() != null && !introspectedColumn.getRemarks().trim().equals(""))
		
		field.addJavaDocLine("");
	}
	
	public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
		if (this.suppressAllComments) {
			return;
		}
		field.addJavaDocLine("");
	}
	
	public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
		if (this.suppressAllComments) {
			return;
		}
	}
	
	public void addGetterComment(Method method, IntrospectedTable introspectedTable,
			IntrospectedColumn introspectedColumn) {
		if (this.suppressAllComments) {
			return;
		}
		method.addJavaDocLine("");
	}

	public void addSetterComment(Method method, IntrospectedTable introspectedTable,
			IntrospectedColumn introspectedColumn) {
		if (this.suppressAllComments) {
			return;
		}

		StringBuilder sb = new StringBuilder();

		method.addJavaDocLine("");
	}
	
	
	public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
		if (this.suppressAllComments) {
			return;
		}

		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;


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("");
	}

	
	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;
	}
	
	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();
				}
			}
		}
	}
	
	@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;

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;


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;

	
	private Integer pageBeginId = null;

	public static final String PageQuery_classname = "pageInfo";

	
	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;
	}

	
	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;
	}

	
	@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;


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")");
			
		}
	}
	
	
	@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);
	
	
	T selectByCondition(Example example);
	
	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 {
    
    @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("");


        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("");

        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的扩展生成代码完成。

来源:宜信技术学院

作者:马伟伟

您可能感兴趣的文档:

--结束END--

本文标题: 代码演示Mybatis-Generator 扩展自定义生成

本文链接: https://www.lsjlt.com/news/4606.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作