今天我打算讲如何在生成器的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>
最后总结,这次代码需要有点代码基础才可以比较好理解,所以如果还不懂的童靴可以再试多两次,再次感谢大家的支持