修改generator源码之xml添加新的sql元素
背景:我发现我要用到一个批量添加的方法,但是generator并没有提供,要是每次都自己去写一遍又很麻烦,然后就各种尝试,最后决定改generator的源码(第一次修改别人的源码,尝试了10次才成功,历时4个小时) 此篇以mybatis-generator-core-1.3.2这个版本作为工具,如果你的版本不一样请自己注意别直接拷贝拷错了 准备工作:随便创建个maven项目,然后在pom.xml里面将相关的依赖加入 <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.8.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> 有上面两个依赖,(其实那个log4j的依赖到底要不要我也不知道,只是之前忘记为什么加上去的了) 然后使用maven 的Download Sources 将generator 的源码包下载下来, 然后在你的maven的jar包仓库就可以看到源码包了:如图 绿线是我的maven仓库的jar包位置,至于你的位子你自己自己知道 源码包是我画红箭头的那个包,然后使用解压工具将这个解压就可以了 解压出来有两个包,一个是org包,一个是META-INF包 将整个org文件夹拖进工程里 导入后如下图: 导入org包完成后要把pom.xml里的generaotr依赖删除(重要) 准备工作结束; 开始改源码:第一步:需要改动的地方,先看图 第一个红箭头对应的那个类 XMLMapperGenerator 这个类是管你的SQL.xml文件内到底要加载多少个sql元素的,直白点说,就是你的sql文件要放几个insert 几个select 几个update 第二个红箭头指向的是那个包:这个包里面放的全部都是生成sql的java文件 第三个红箭头是我加进去的java文件 接下来看下XMLMapperGenerator 这个类改动的具体位置 还是看图吧 先在这个类里面添加个方法 自己改下方法名,以及该方法调用哪个类 然后看下图中 要记得调用该方法,这样你的新sql才会进去 第二步:写自己需要的类下面是我添加的那个生产sql的类 package org.mybatis.generator.codegen.mybatis3.xmlmapper.elements; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.dom.OutputUtilities; 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 static org.mybatis.generator.internal.util.StringUtility.escapeStringForJava; import static org.mybatis.generator.internal.util.StringUtility.stringHasValue; public class InsertBatchGenerator extends AbstractXmlElementGenerator { @Override public void addElements(XmlElement parentElement) { XmlElement answer = new XmlElement("insert"); answer.addAttribute(new Attribute("id","insertBatch")); answer.addAttribute(new Attribute("parameterType","java.lang.List")); XmlElement foreach = new XmlElement("foreach"); foreach.addAttribute(new Attribute("collection","list")); foreach.addAttribute(new Attribute("index","i")); foreach.addAttribute(new Attribute("item","o")); foreach.addAttribute(new Attribute("separator",",")); context.getCommentGenerator().addComment(answer); StringBuilder insertClause = new StringBuilder(); StringBuilder valuesClause = new StringBuilder(); insertClause.append("insert into "); insertClause.append(introspectedTable.getFullyQualifiedTableNameAtRuntime()); insertClause.append(" ("); valuesClause.append(" ("); List<String> valuesClauses = new ArrayList<String>(); Iterator<IntrospectedColumn> iter = introspectedTable.getAllColumns().iterator(); while (iter.hasNext()) { IntrospectedColumn introspectedColumn = iter.next(); if (introspectedColumn.isIdentity()) { // cannot set values on identity fields continue; } insertClause.append(getEscapedColumnName(introspectedColumn)); valuesClause.append(getParameterClause(introspectedColumn)); if (iter.hasNext()) { insertClause.append(","); //$NON-NLS-1$ valuesClause.append(","); //$NON-NLS-1$ } if (valuesClause.length() > 80) { answer.addElement(new TextElement(insertClause.toString())); insertClause.setLength(0); OutputUtilities.xmlIndent(insertClause,1); valuesClauses.add(valuesClause.toString()); valuesClause.setLength(0); OutputUtilities.xmlIndent(valuesClause,1); } } insertClause.append(") values "); answer.addElement(new TextElement(insertClause.toString())); valuesClause.append(')'); for (String clause : valuesClauses) { foreach.addElement(new TextElement(clause)); } foreach.addElement(new TextElement(valuesClause.toString())); answer.addElement(foreach); if (context.getPlugins().sqlMapInsertElementGenerated(answer,introspectedTable)) { parentElement.addElement(answer); } } /* * Copyright 2009 The Apache Software Foundation * * Licensed under the Apache License,Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain a * copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing,software * distributed under the License is distributed on an "AS IS" BASIS,WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ public static String getParameterClause(IntrospectedColumn introspectedColumn) { return getParameterClause(introspectedColumn,null); } public static String getParameterClause(IntrospectedColumn introspectedColumn,String prefix) { StringBuilder sb = new StringBuilder(); sb.append("#{"); //$NON-NLS-1$ sb.append("o."); sb.append(introspectedColumn.getJavaProperty(prefix)); sb.append(",jdbcType="); //$NON-NLS-1$ sb.append(introspectedColumn.getJdbcTypeName()); if (stringHasValue(introspectedColumn.getTypeHandler())) { sb.append(",typeHandler="); //$NON-NLS-1$ sb.append(introspectedColumn.getTypeHandler()); } sb.append('}'); return sb.toString(); } /** * The phrase to use in a select list. If there is a table alias,the value * will be "alias.columnName as alias_columnName" * * @return the proper phrase */ public static String getSelectListPhrase(IntrospectedColumn introspectedColumn) { if (stringHasValue(introspectedColumn.getTableAlias())) { StringBuilder sb = new StringBuilder(); sb.append(getAliasedEscapedColumnName(introspectedColumn)); sb.append(" as "); //$NON-NLS-1$ if (introspectedColumn.isColumnNameDelimited()) { sb.append(introspectedColumn.getContext().getBeginningDelimiter()); } sb.append(introspectedColumn.getTableAlias()); sb.append('_'); sb.append(escapeStringForMyBatis3(introspectedColumn.getActualColumnName())); if (introspectedColumn.isColumnNameDelimited()) { sb.append(introspectedColumn.getContext().getEndingDelimiter()); } return sb.toString(); } else { return getEscapedColumnName(introspectedColumn); } } public static String getEscapedColumnName(IntrospectedColumn introspectedColumn) { StringBuilder sb = new StringBuilder(); sb.append(escapeStringForMyBatis3(introspectedColumn.getActualColumnName())); if (introspectedColumn.isColumnNameDelimited()) { sb.insert(0,introspectedColumn.getContext().getBeginningDelimiter()); sb.append(introspectedColumn.getContext().getEndingDelimiter()); } return sb.toString(); } /** * Calculates the string to use in select phrases in SqlMaps. * * @return the aliased escaped column name */ public static String getAliasedEscapedColumnName(IntrospectedColumn introspectedColumn) { if (stringHasValue(introspectedColumn.getTableAlias())) { StringBuilder sb = new StringBuilder(); sb.append(introspectedColumn.getTableAlias()); sb.append('.'); sb.append(getEscapedColumnName(introspectedColumn)); return sb.toString(); } else { return getEscapedColumnName(introspectedColumn); } } /** * The aliased column name for a select statement generated by the example * clauses. This is not appropriate for selects in SqlMaps because the * column is not escaped for MyBatis. If there is a table alias,the value * will be alias.columnName. * * This method is used in the Example classes and the returned value will be * in a Java string. So we need to escape double quotes if they are the * delimiters. * * @return the aliased column name */ public static String getAliasedActualColumnName(IntrospectedColumn introspectedColumn) { StringBuilder sb = new StringBuilder(); if (stringHasValue(introspectedColumn.getTableAlias())) { sb.append(introspectedColumn.getTableAlias()); sb.append('.'); } if (introspectedColumn.isColumnNameDelimited()) { sb.append(escapeStringForJava(introspectedColumn.getContext().getBeginningDelimiter())); } sb.append(introspectedColumn.getActualColumnName()); if (introspectedColumn.isColumnNameDelimited()) { sb.append(escapeStringForJava(introspectedColumn.getContext().getEndingDelimiter())); } return sb.toString(); } /** * The renamed column name for a select statement. If there is a table * alias,the value will be alias_columnName. This is appropriate for use in * a result map. * * @return the renamed column name */ public static String getRenamedColumnNameForResultMap(IntrospectedColumn introspectedColumn) { if (stringHasValue(introspectedColumn.getTableAlias())) { StringBuilder sb = new StringBuilder(); sb.append(introspectedColumn.getTableAlias()); sb.append('_'); sb.append(introspectedColumn.getActualColumnName()); return sb.toString(); } else { return introspectedColumn.getActualColumnName(); } } public static String escapeStringForMyBatis3(String s) { // nothing to do for MyBatis3 so far return s; } } 修改源码的时候尽量不要去动原来的代码,不然可能会影响到一些你不知道的功能的使用 我是将需要用的源码拷贝到我的类里面直接写成方法来调用的,这样就能即添加了自己的所需,又不用担心影响到久的方法或者功能的使用, 至于我的InsertBatchGenerator这个类是怎么写出来的就不详细打注释了,你可以去参考一下里面那些类就知道了记得自己写的生产sql的类要继承AbstractXmlElementGenerator这个类哦 最后:直接将整个项目导出,记得导成jar包哦,然后丢回自己的maven仓库,把名字久的mybatis-generator-core-1.3.2.jar删除 然后吧自己的jar改成这个名字就可以用了 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |