另一种自己实现的Mybatis-Generator中可进行集成的分页插件代码

/*
原作者代码https://github.com/wucao/mybatis-generator-mysql-plugin
*/
package com.my.mbg;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
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 java.util.List;

public class MySQLLimitPlugin extends PluginAdapter {

	@Override
	public boolean validate(List<String> list) {
		return true;
	}

	/**
	 * 为每个Example类添加limit和offset属性已经set、get方法
	 */
	@Override
	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

		PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper();

		Field limit = new Field();
		limit.setName("limit");
		limit.setVisibility(JavaVisibility.PRIVATE);
		limit.setType(integerWrapper);
		topLevelClass.addField(limit);

		Method setLimit = new Method();
		setLimit.setVisibility(JavaVisibility.PUBLIC);
		setLimit.setName("setLimit");
		setLimit.addParameter(new Parameter(integerWrapper, "limit"));
		setLimit.addBodyLine("this.limit = limit;");
		topLevelClass.addMethod(setLimit);

		Method getLimit = new Method();
		getLimit.setVisibility(JavaVisibility.PUBLIC);
		getLimit.setReturnType(integerWrapper);
		getLimit.setName("getLimit");
		getLimit.addBodyLine("return limit;");
		topLevelClass.addMethod(getLimit);

		Field offset = new Field();
		offset.setName("offset");
		offset.setVisibility(JavaVisibility.PRIVATE);
		offset.setType(integerWrapper);
		topLevelClass.addField(offset);

		Method setOffset = new Method();
		setOffset.setVisibility(JavaVisibility.PUBLIC);
		setOffset.setName("setOffset");
		setOffset.addParameter(new Parameter(integerWrapper, "offset"));
		setOffset.addBodyLine("this.offset = offset;");
		topLevelClass.addMethod(setOffset);

		Method getOffset = new Method();
		getOffset.setVisibility(JavaVisibility.PUBLIC);
		getOffset.setReturnType(integerWrapper);
		getOffset.setName("getOffset");
		getOffset.addBodyLine("return offset;");
		topLevelClass.addMethod(getOffset);

		return true;
	}

	/**
	 * 为Mapper.xml的selectByExample添加limit
	 */
	@Override
	public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
																	 IntrospectedTable introspectedTable) {

		XmlElement ifLimitNotNullElement = new XmlElement("if");
		ifLimitNotNullElement.addAttribute(new Attribute("test", "limit != null"));

		XmlElement ifOffsetNotNullElement = new XmlElement("if");
		ifOffsetNotNullElement.addAttribute(new Attribute("test", "offset != null"));
		ifOffsetNotNullElement.addElement(new TextElement("limit ${offset}, ${limit}"));
		ifLimitNotNullElement.addElement(ifOffsetNotNullElement);

		XmlElement ifOffsetNullElement = new XmlElement("if");
		ifOffsetNullElement.addAttribute(new Attribute("test", "offset == null"));
		ifOffsetNullElement.addElement(new TextElement("limit ${limit}"));
		ifLimitNotNullElement.addElement(ifOffsetNullElement);

		element.addElement(ifLimitNotNullElement);

		return true;
	}
}
/*
新实现方式
*/
package com.my.mbg;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.*;
import org.mybatis.generator.codegen.mybatis3.javamapper.elements.AbstractJavaMapperMethodGenerator;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.elements.AbstractXmlElementGenerator;
import org.mybatis.generator.internal.util.StringUtility;
import org.mybatis.generator.internal.util.messages.Messages;
import org.springframework.util.ReflectionUtils;

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

/**
 * 另一种自己实现的Mybatis-Generator中可进行集成的分页插件代码
 * 优点:参数易于理解
 *
 * 新增功能如下:
 * 1.修改原先生成的*Example类名为*Template
 * 2.修改dao *Mapper的方法中含有example的为template,参数也修改为template
 * 3.修改xml *Mapper的sql中含有example的为template
 * 4.dao *Mapper中加入注解,包引入
 */
public class MBGPlugin extends PluginAdapter {

	/**
	 * 修改xml mapper、dao mapper中的example为另外自定义的命名
	 */
	private static final String QUERY_SUFFIX = "Template";

	private static final String EXAMPLE_SUFFIX = "Example";

	/**
	 * 修改Example类名为自定义的类名,源码拷贝
	 */
	private String searchString="Example$";

	private String replaceString="Template";

	private Pattern pattern;

	@Override
	public boolean validate(List<String> list) {
		boolean valid = StringUtility.stringHasValue(this.searchString) && StringUtility.stringHasValue(this.replaceString);
		if (valid) {
			this.pattern = Pattern.compile(this.searchString);
		} else {
			if (!StringUtility.stringHasValue(this.searchString)) {
				list.add(Messages.getString("ValidationError.18", "RenameExampleClassPlugin", "searchString"));
			}

			if (!StringUtility.stringHasValue(this.replaceString)) {
				list.add(Messages.getString("ValidationError.18", "RenameExampleClassPlugin", "replaceString"));
			}
		}

		return valid;
	}

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

	/**
	 * 修改XML中的Example
	 *
	 * @param document
	 * @param introspectedTable
	 * @return
	 */
	@Override
	public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
		AbstractXmlElementGenerator generator = new AbstractXmlElementGenerator() {

			@Override
			public void addElements(XmlElement parentElement) {
				java.lang.reflect.Field field = null;
				try {
					field = Attribute.class.getDeclaredField("value");
					ReflectionUtils.makeAccessible(field);
				} catch (NoSuchFieldException e) {
					e.printStackTrace();
				}

				replaceExample(field, parentElement.getElements());
			}
		};
		generator.setContext(context);
		generator.setIntrospectedTable(introspectedTable);
		generator.addElements(document.getRootElement());
		return super.sqlMapDocumentGenerated(document, introspectedTable);
	}

	/**
	 * 递归修改XML中的Example
	 *
	 * @param field
	 * @param elements
	 */
	private void replaceExample(java.lang.reflect.Field field, List<Element> elements) {
		if (CollectionUtils.isEmpty(elements)) {
			return;
		}
		for (Element element : elements) {
			if (!(element instanceof XmlElement)) {
				continue;
			}
			XmlElement xmlElement = (XmlElement) element;
			String name = xmlElement.getName();
			switch (name) {
				case "select":
				case "update":
				case "delete":
				case "insert":
				case "sql":
					for (Attribute attribute : xmlElement.getAttributes()) {
						String attributeName = attribute.getName();
						String value = attribute.getValue();
						if (!StringUtils.equals(attributeName, "id") || !StringUtils.contains(value, EXAMPLE_SUFFIX)) {
							continue;
						}
						value = value.replace(EXAMPLE_SUFFIX, QUERY_SUFFIX);
						ReflectionUtils.setField(field, attribute, value);
					}
					break;
				case "foreach":
					for (Attribute attribute : xmlElement.getAttributes()) {
						String attributeName = attribute.getName();
						String value = attribute.getValue();
						if (!StringUtils.equals(attributeName, "collection") || !StringUtils.contains(value, EXAMPLE_SUFFIX.toLowerCase(Locale.ROOT))) {
							continue;
						}
						value = value.replace(EXAMPLE_SUFFIX.toLowerCase(Locale.ROOT), QUERY_SUFFIX.toLowerCase(Locale.ROOT));
						ReflectionUtils.setField(field, attribute, value);
					}
					break;
				case "include":
					for (Attribute attribute : xmlElement.getAttributes()) {
						String attributeName = attribute.getName();
						String value = attribute.getValue();
						if (!StringUtils.equals(attributeName, "refid") || !StringUtils.contains(value, EXAMPLE_SUFFIX)) {
							continue;
						}
						value = value.replace(EXAMPLE_SUFFIX, QUERY_SUFFIX);
						ReflectionUtils.setField(field, attribute, value);
					}
					break;
				default:
					break;
			}
			List<Element> subElements = xmlElement.getElements();
			this.replaceExample(field, subElements);
		}
	}

	/**
	 * mapper层增加注解和包引入
	 * @param interfaze
	 * @param topLevelClass
	 * @param introspectedTable
	 * @return
	 */
	@Override
	public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

		if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
			interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
			interfaze.addAnnotation("@Mapper");
		}

		//仅修改dao mapper中的方法名
		AbstractJavaMapperMethodGenerator generator = new AbstractJavaMapperMethodGenerator() {
			@Override
			public void addInterfaceElements(Interface interfaze) {
				for (Method method : interfaze.getMethods()) {
					String name = method.getName();
					if (!StringUtils.contains(name, EXAMPLE_SUFFIX)) {
						continue;
					}
					// 修改方法名称
					method.setName(name.replace(EXAMPLE_SUFFIX, QUERY_SUFFIX));
					List<Parameter> parameters = method.getParameters();
					for (Parameter parameter : parameters) {
						String parameterName = parameter.getName();
						if (!StringUtils.contains(parameterName, EXAMPLE_SUFFIX.toLowerCase(Locale.ROOT))) {
							continue;
						}
						// 修改变量名称
						try {
							java.lang.reflect.Field nameField = parameter.getClass().getDeclaredField("name");
							ReflectionUtils.makeAccessible(nameField);
							ReflectionUtils.setField(nameField, parameter, parameterName.replace(EXAMPLE_SUFFIX.toLowerCase(Locale.ROOT), QUERY_SUFFIX.toLowerCase(Locale.ROOT)));
						} catch (Exception e) {
							e.printStackTrace();
						}
						// 修改@Param注解value值
						List<String> annotations = parameter.getAnnotations();
						for (int i = 0; i < annotations.size(); i++) {
							String annotation = annotations.get(i);
							if (!StringUtils.contains(annotation, EXAMPLE_SUFFIX.toLowerCase(Locale.ROOT))) {
								continue;
							}
							annotations.set(i, annotation.replace(EXAMPLE_SUFFIX.toLowerCase(Locale.ROOT), QUERY_SUFFIX.toLowerCase(Locale.ROOT)));
						}
					}
				}
			}
		};
		generator.setContext(context);
		generator.setIntrospectedTable(introspectedTable);
		generator.addInterfaceElements(interfaze);

		return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
	}

	/**
	 * 为每个Example类添加必要属性
	 */
	@Override
	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

		PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper();

		Field limit = new Field();
		limit.setName("currentPage");
		limit.setVisibility(JavaVisibility.PRIVATE);
		limit.setType(integerWrapper);
		topLevelClass.addField(limit);

		Field offset = new Field();
		offset.setName("pageSize");
		offset.setVisibility(JavaVisibility.PRIVATE);
		offset.setType(integerWrapper);
		topLevelClass.addField(offset);

		Field pageCalc = new Field();
		pageCalc.setName("pageCalc");
		pageCalc.setVisibility(JavaVisibility.PRIVATE);
		pageCalc.setType(integerWrapper);
		topLevelClass.addField(pageCalc);

		Method pageCalcConstructors = new Method();
		pageCalcConstructors.setVisibility(JavaVisibility.PUBLIC);
		pageCalcConstructors.setConstructor(true);
		pageCalcConstructors.setName(topLevelClass.getType().getShortName());
		pageCalcConstructors.addParameter(new Parameter(integerWrapper, "currentPage"));
		pageCalcConstructors.addParameter(new Parameter(integerWrapper, "pageSize"));
		pageCalcConstructors.addBodyLine("oredCriteria = new ArrayList<Criteria>();");
		pageCalcConstructors.addBodyLine("this.pageSize = pageSize;");
		pageCalcConstructors.addBodyLine("this.currentPage = currentPage;");
		pageCalcConstructors.addBodyLine("this.pageCalc = (currentPage-1)*pageSize;");
		topLevelClass.addMethod(pageCalcConstructors);

		return true;
	}

	/**
	 * 为Mapper.xml的selectByExample添加分页逻辑
	 */
	@Override
	public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
																	 IntrospectedTable introspectedTable) {

		XmlElement ifLimitNotNullElement = new XmlElement("if");
		ifLimitNotNullElement.addAttribute(new Attribute("test", "currentPage != null"));

		XmlElement ifOffsetNotNullElement = new XmlElement("if");
		ifOffsetNotNullElement.addAttribute(new Attribute("test", "pageSize != null"));
		ifOffsetNotNullElement.addElement(new TextElement("limit ${pageSize} offset ${pageCalc}"));
		ifLimitNotNullElement.addElement(ifOffsetNotNullElement);

		element.addElement(ifLimitNotNullElement);

		return true;
	}
}

generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <properties resource="generator.properties"/>
    <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 为模型生成序列化方法-->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!-- 为生成的Java模型创建一个toString方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <!--生成mapper.xml时覆盖原文件-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />

        <plugin type="com.my.mbg.MBGPlugin"></plugin>

        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
            <property name="addRemarkComments" value="false"/>
        </commentGenerator>

        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.connectionURL}"
                        userId="${jdbc.userId}"
                        password="${jdbc.password}">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>

        <javaModelGenerator targetPackage="com.mbg.model" targetProject="src\main\java"/>

        <sqlMapGenerator targetPackage="com.mbg.mapper" targetProject="src\main\resources"/>

        <javaClientGenerator type="XMLMAPPER" targetPackage="com.mbg.mapper"
                             targetProject="src\main\java"/>
        <!--生成全部表tableName设为%-->
        <!--<table tableName="%">-->
        <table tableName="ums_admin">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

mybaties-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 引用db.properties配置文件 -->
    <properties resource="generator.properties"/>
    <!--
     development : 开发模式
     work : 工作模式
  -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.connectionURL}"/>
                <property name="username" value="${jdbc.userId}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/mbg/mapper/UmsAdminMapper.xml"/>
    </mappers>
</configuration>

generator.properties

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://xx:3306/xx?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.userId=root
jdbc.password=root
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值