1. 程式人生 > >mybatis-generator擴充套件教程系列 -- 自定義generatorConfig.xml引數

mybatis-generator擴充套件教程系列 -- 自定義generatorConfig.xml引數

        今天我打算講如何在生成器的xml配置檔案里加入自定義的引數,真實很多場景我們會遇到需要自定義BaseDAO,BaseService類路徑,所以這個時候為了擴充套件我們會考慮把這些引數放到xml配置,下面就延續使用上一篇的教程專案來做程式碼示例(如果沒有看過之前的環境搭建入門篇可以到文章目錄點選進入)

1.大家可以先直接開啟MyBatisGeneratorConfigurationParser.java這個類,其中下面兩段程式碼即是讀取xml配置的節點並填充到Context物件(,我們可以在這裡照著模版加入自己的資料節點)

private void parseContext(Configuration configuration, Node node) {

        Properties attributes = parseAttributes(node);
        String defaultModelType = attributes.getProperty("defaultModelType"); //$NON-NLS-1$
        String targetRuntime = attributes.getProperty("targetRuntime"); //$NON-NLS-1$
        String introspectedColumnImpl = attributes
                .getProperty("introspectedColumnImpl"); //$NON-NLS-1$
        String id = attributes.getProperty("id"); //$NON-NLS-1$

        ModelType mt = defaultModelType == null ? null : ModelType
                .getModelType(defaultModelType);

        Context context = new Context(mt);
        context.setId(id);
        if (stringHasValue(introspectedColumnImpl)) {
            context.setIntrospectedColumnImpl(introspectedColumnImpl);
        }
        if (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() != Node.ELEMENT_NODE) {
                continue;
            }

            if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseProperty(context, childNode);
            } else if ("plugin".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parsePlugin(context, childNode);
            } else if ("commentGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseCommentGenerator(context, childNode);
            } else if ("jdbcConnection".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJdbcConnection(context, childNode);
            } else if ("connectionFactory".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseConnectionFactory(context, childNode);
            } else if ("javaModelGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaModelGenerator(context, childNode);
            } else if ("javaTypeResolver".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaTypeResolver(context, childNode);
            } else if ("sqlMapGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseSqlMapGenerator(context, childNode);
            } else if ("javaClientGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaClientGenerator(context, childNode);
            } else if ("table".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseTable(context, childNode);
            }
        }
    }

private void parseJavaClientGenerator(Context context, Node node) {
        JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();

        context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);

        Properties attributes = parseAttributes(node);
        String type = attributes.getProperty("type"); //$NON-NLS-1$
        String targetPackage = attributes.getProperty("targetPackage"); //$NON-NLS-1$
        String targetProject = attributes.getProperty("targetProject"); //$NON-NLS-1$
        String implementationPackage = attributes
                .getProperty("implementationPackage"); //$NON-NLS-1$

        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() != Node.ELEMENT_NODE) {
                continue;
            }

            if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseProperty(javaClientGeneratorConfiguration, childNode);
            }
        }
    }


2.通過上面的方法我們看到有一個JavaClientGeneratorConfiguration物件接受xml資料,所以我們也copy一份JavaClientGeneratorConfiguration改造成適合自己業務的物件
package org.mybatis.generator.config;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import static org.mybatis.generator.internal.util.messages.Messages.getString;

import java.util.List;

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

/**
 * @author shadow
 */
public class JavaParamConfiguration extends TypedPropertyHolder {
	
    private String baseDAO; // baseDAO類路徑
    private String baseService; //baseService類路徑
    private String buildType; // 1.dao層 2.service層 3.control層

    public JavaParamConfiguration() {
        super();
    }

    public String getBaseDAO() {
		return baseDAO;
	}

	public void setBaseDAO(String baseDAO) {
		this.baseDAO = baseDAO;
	}

	public String getBaseService() {
		return baseService;
	}

	public void setBaseService(String baseService) {
		this.baseService = baseService;
	}

	public String getBuildType() {
		return buildType;
	}

	public void setBuildType(String buildType) {
		this.buildType = buildType;
	}

	public XmlElement toXmlElement() {
        XmlElement answer = new XmlElement("javaParam"); //$NON-NLS-1$
        
        if (baseDAO != null) {
            answer.addAttribute(new Attribute("baseDAO", baseDAO)); //$NON-NLS-1$
        }

        if (baseService != null) {
            answer.addAttribute(new Attribute("baseService", baseService)); //$NON-NLS-1$
        }
        
        if (buildType != null) {
            answer.addAttribute(new Attribute("buildType", buildType)); //$NON-NLS-1$
        }

        addPropertyXmlElements(answer);

        return answer;
    }

    public void validate(List<String> errors, String contextId) {

        if (!stringHasValue(baseDAO)) {
            errors.add(getString("ValidationError.12", //$NON-NLS-1$
                    "JavaParamConfiguration", contextId)); //$NON-NLS-1$
        }
        
        if (!stringHasValue(baseService)) {
            errors.add(getString("ValidationError.13", //$NON-NLS-1$
                    "JavaParamConfiguration", contextId)); //$NON-NLS-1$
        }
        
        if (!stringHasValue(buildType)) {
            errors.add(getString("ValidationError.14", //$NON-NLS-1$
                    "JavaParamConfiguration", contextId)); //$NON-NLS-1$
        }

    }
}


3.配置物件已經寫好了,那就在Context物件最頂部加入我們剛剛新建的配置物件

package org.mybatis.generator.config;

import static org.mybatis.generator.internal.util.StringUtility.composeFullyQualifiedTableName;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;


/**
 * The Class Context.
 *
 * @author Jeff Butler
 */
public class Context extends PropertyHolder {
    
	/** 自定義配置引數 */
    private JavaParamConfiguration javaParamConfiguration;
    
    public JavaParamConfiguration getJavaParamConfiguration() {
		return javaParamConfiguration;
	}

	public void setJavaParamConfiguration(JavaParamConfiguration javaParamConfiguration) {
		this.javaParamConfiguration = javaParamConfiguration;
	}


4.下一步就在MyBatisGeneratorConfigurationParser.java加入下面一段方法,增加一行else if分支呼叫該方法

private void parseJavaParam(Context context, Node node) { // 自定義填充xml引數方法
        JavaParamConfiguration javaParamConfiguration = new JavaParamConfiguration();

        context.setJavaParamConfiguration(javaParamConfiguration);

        Properties attributes = parseAttributes(node);
        String baseDAO = attributes.getProperty("baseDAO"); //$NON-NLS-1$
        String baseService = attributes.getProperty("baseService"); //$NON-NLS-1$
        String buildType = attributes.getProperty("buildType"); //$NON-NLS-1$

        javaParamConfiguration.setBaseDAO(baseDAO);
        javaParamConfiguration.setBaseService(baseService);
        javaParamConfiguration.setBuildType(buildType);

        NodeList nodeList = node.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node childNode = nodeList.item(i);

            if (childNode.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }

            if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseProperty(javaParamConfiguration, childNode);
            }
        }
    }

private void parseContext(Configuration configuration, Node node) {

        Properties attributes = parseAttributes(node);
        String defaultModelType = attributes.getProperty("defaultModelType"); //$NON-NLS-1$
        String targetRuntime = attributes.getProperty("targetRuntime"); //$NON-NLS-1$
        String introspectedColumnImpl = attributes
                .getProperty("introspectedColumnImpl"); //$NON-NLS-1$
        String id = attributes.getProperty("id"); //$NON-NLS-1$

        ModelType mt = defaultModelType == null ? null : ModelType
                .getModelType(defaultModelType);

        Context context = new Context(mt);
        context.setId(id);
        if (stringHasValue(introspectedColumnImpl)) {
            context.setIntrospectedColumnImpl(introspectedColumnImpl);
        }
        if (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() != Node.ELEMENT_NODE) {
                continue;
            }

            if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseProperty(context, childNode);
            } else if ("plugin".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parsePlugin(context, childNode);
            } else if ("commentGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseCommentGenerator(context, childNode);
            } else if ("jdbcConnection".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJdbcConnection(context, childNode);
            } else if ("connectionFactory".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseConnectionFactory(context, childNode);
            } else if ("javaModelGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaModelGenerator(context, childNode);
            } else if ("javaTypeResolver".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaTypeResolver(context, childNode);
            } else if ("sqlMapGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseSqlMapGenerator(context, childNode);
            } else if ("javaClientGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaClientGenerator(context, childNode);
            }else if ("javaParam".equals(childNode.getNodeName())) { // 新增自定義引數填充分支
                parseJavaParam(context, childNode);
            } else if ("table".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseTable(context, childNode);
            }
        }
    }

5.然後在配置檔案增加我們的節點,還需要修改mybatis-generator-config_1_0.dtd識別我們新增加的節點名稱(javaParam?)

注意事項,請把按dtd的節點順序排列配置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>

    <!-- 資料庫驅動 -->
    <classPathEntry location="lib/mysql-connector-java-5.1.18.jar" />
    
    <context id="MySQLTables" targetRuntime="MyBatis3">
    
        <commentGenerator>
            <property name="suppressDate" value="true" />
            <!-- 是否去除自動生成的註釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="false" />
        </commentGenerator>
        
        <!--資料庫連結URL,使用者名稱、密碼 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://127.0.0.1:3306/qfd" userId="admin"
            password="admin">
        </jdbcConnection>
        
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        
        <!-- 生成模型的包名和位置 -->
        <javaModelGenerator targetPackage="com.test.domain"
            targetProject="project">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        
        <!-- 生成對映檔案的包名和位置 -->
        <sqlMapGenerator targetPackage="com.test.dao.mapper"
            targetProject="project">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        
        <!-- 生成DAO的包名和位置 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="com.test.dao" targetProject="project">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        
        <!--自定義XML引數配置 -->
        <javaParam baseDAO="com.test.BaseDAO" baseService="com.test.BaseService" buildType="1,2" >
        </javaParam>
        
        <!-- 配置生成表 -->
        <table tableName="qfd_sketch" enableCountByExample="false"
            enableDeleteByExample="false" enableSelectByExample="false"
            enableUpdateByExample="false">
            <property name="modelOnly" value="false" />
        </table>
        
    </context>
    
</generatorConfiguration>   
<!--
  The context element is used to describe a context for generating files, and the source
  tables.
-->
<!ELEMENT context (property*, plugin*, commentGenerator?, (connectionFactory | jdbcConnection), javaTypeResolver?,
                         javaModelGenerator, sqlMapGenerator?, javaClientGenerator?, javaParam?, table+)>
<!ATTLIST context id ID #REQUIRED
  defaultModelType CDATA #IMPLIED
  targetRuntime CDATA #IMPLIED
  introspectedColumnImpl CDATA #IMPLIED>

<!-- 自定義XML節點 -->
<!ELEMENT javaParam (property*)>
<!ATTLIST javaParam
  baseDAO CDATA #REQUIRED
  baseService CDATA #REQUIRED
  buildType CDATA #REQUIRED>

最後總結,這次程式碼需要有點程式碼基礎才可以比較好理解,所以如果還不懂的童靴可以再試多兩次,再次感謝大家的支援