背景:
我发现我要用到一个批量添加的方法,但是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改成这个名字就可以用了