第一步:准备需要的jar包。由于maven只要配置pom.xml就可以从仓库下载jar包。因此我们首先配置pom.xml。
注意com.microsoft.sqlserver需要自己加入maven仓库的。
......
org.mybatis
mybatis
3.2.3
com.microsoft.sqlserver
sqljdbc4
4.0
org.mybatis.generator
mybatis-generator-core
1.3.2
......
......
......
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.2
true
true
com.microsoft.sqlserver
sqljdbc4
4.0
com.montnets.edusun
mybatis-user-defined-plugin
0.1
第二步:配置generatorConfig.xml文件。在src/main/resources文件夹下新建generatorConfig.xml文件,配置文件如下代码所示。
对应的datasource.properties如下所示
#sql server database settings
jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=test
jdbc.username=sa
jdbc.password=******
-----------------------------------------------------------------------------------------------------------------------
下面介绍一下自定义的两个插件:InsertAndUpdateBatch和PaginationPlugin。这两个插件都被封装在mybatis-user-defined-plugin.jar包中。需要在maven的仓库中注册该jar包,pom.xml和generatorConfig.xml里的配置方式已经在前面有了。
InsertAndUpdateBatch: 配置后在生成代码时,会在接口和sqlmap文件中生成updateBySelectiveBatch、updateBatch、insertBatch三个方法和对应的sql语句。
PaginationPlugin:配置后在生成代码时,会在接口和sqlmap文件中生成countTotalData、pageQuery两个方法和对应的sql语句。需要注意的是该插件的四个参数,前三个参数为必需的,后一个参数为非必需的。
pageQualifiedName——分页类的全路径
fromIndex——分页查询中需要用到的起始索引名称
toIndex——分页查询中需要用到的结束索引名称
myBatisRepository——接口为mybatis提供的扫描注解类的全名。
源代码如下:
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.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
/**
* @author 罗勇
* @date 2013年11月6日 下午2:45:26
*/
public class PaginationPlugin extends PluginAdapter {
private String pageQualifiedName; //分页类的全名
private String fromIndex; //Page对象中,查询起始位置的属性名称
private String toIndex; //Page对象中,查询结束位置的属性名称
private String myBatisRepository; //接口注解全名
/**
* 验证插件的配置是否正确
*/
public boolean validate(List warnings) {
pageQualifiedName = properties.getProperty("pageQualifiedName");
fromIndex = properties.getProperty("fromIndex");
toIndex = properties.getProperty("toIndex");
myBatisRepository = properties.getProperty("myBatisRepository");
if (!stringHasValue(pageQualifiedName)) {
warnings.add(getString("ValidationError.18", "PaginationPlugin", "pageQualifiedName"));
return false;
}
if (!stringHasValue(fromIndex)) {
warnings.add(getString("ValidationError.18", "PaginationPlugin", "fromIndex"));
return false;
}
if (!stringHasValue(toIndex)) {
warnings.add(getString("ValidationError.18", "PaginationPlugin", "toIndex"));
return false;
}
return true;
}
/**
* 在接口中添加方法
*/
@Override
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
String objectName = introspectedTable.getTableConfiguration().getDomainObjectName();//对象名称
interfaze.addImportedType(new FullyQualifiedJavaType("java.util.List"));
interfaze.addImportedType(new FullyQualifiedJavaType(pageQualifiedName));
if (stringHasValue(myBatisRepository) && myBatisRepository.contains(".")) {
int index = myBatisRepository.lastIndexOf('.');
interfaze.addImportedType(new FullyQualifiedJavaType(myBatisRepository));
interfaze.addAnnotation("@" + myBatisRepository.substring(index + 1));//接口添加注解
}
Method method = new Method();//统计记录总条数方法
method.setName("countTotalData");
method.setReturnType(new FullyQualifiedJavaType("int"));
interfaze.addMethod(method);
method = new Method();//分页查询方法
method.setName("pageQuery");
method.addParameter(new Parameter(new FullyQualifiedJavaType(pageQualifiedName), "page"));
method.setReturnType(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"));
interfaze.addMethod(method);
return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
}
/**
* 在xml文件中添加需要的元素
*/
@Override
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
XmlElement parentElement = document.getRootElement();
String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();//数据库表名
// 产生统计记录数查询
XmlElement countTotalDataElement = new XmlElement("select");
countTotalDataElement.addAttribute(new Attribute("id", "countTotalData"));
countTotalDataElement.addAttribute(new Attribute("resultType", "java.lang.Integer"));
countTotalDataElement.addElement(new TextElement("select count(1) from " + tableName));
parentElement.addElement(countTotalDataElement);
// 产生分页查询语句
XmlElement pageQueryElement = new XmlElement("select");
pageQueryElement.addAttribute(new Attribute("id", "pageQuery"));
pageQueryElement.addAttribute(new Attribute("resultMap", "BaseResultMap"));
pageQueryElement.addAttribute(new Attribute("parameterType", pageQualifiedName));
XmlElement queryStart = new XmlElement("include");
queryStart.addAttribute(new Attribute("refid", "PageQueryPrefix"));
pageQueryElement.addElement(queryStart);
pageQueryElement.addElement(new TextElement("select "));
XmlElement query = new XmlElement("include");
query.addAttribute(new Attribute("refid", "Base_Column_List"));
pageQueryElement.addElement(query);
pageQueryElement.addElement(new TextElement("from " + tableName));
XmlElement queryEnd = new XmlElement("include");
queryEnd.addAttribute(new Attribute("refid", "PageQuerySuffix"));
pageQueryElement.addElement(queryEnd);
parentElement.addElement(pageQueryElement);
// 产生分页语句前半部分
XmlElement paginationPrefixElement = new XmlElement("sql");
paginationPrefixElement.addAttribute(new Attribute("id", "PageQueryPrefix"));
XmlElement pageStart = new XmlElement("if");
pageStart.addAttribute(new Attribute("test", "fromIndex != null and toIndex != null"));
pageStart.addElement(new TextElement("select * from (select row_number() over (order by id desc) as rownum,* from( "));
paginationPrefixElement.addElement(pageStart);
parentElement.addElement(paginationPrefixElement);
// 产生分页语句后半部分
XmlElement paginationSuffixElement = new XmlElement("sql");
paginationSuffixElement.addAttribute(new Attribute("id", "PageQuerySuffix"));
XmlElement pageEnd = new XmlElement("if");
pageEnd.addAttribute(new Attribute("test", "fromIndex != null and toIndex != null"));
pageEnd.addElement(new TextElement("= #{" + fromIndex + "} ]]>"));
paginationSuffixElement.addElement(pageEnd);
parentElement.addElement(paginationSuffixElement);
return super.sqlMapDocumentGenerated(document, introspectedTable);
}
/**
* 在Example配置为true时,在Example对象中添加get/set方法
*/
@Override
public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
String name = "page";
topLevelClass.addImportedType(new FullyQualifiedJavaType(pageQualifiedName));
Field field = new Field();
field.setVisibility(JavaVisibility.PROTECTED);
field.setType(new FullyQualifiedJavaType(pageQualifiedName));
field.setName(name);
topLevelClass.addField(field);
char c = name.charAt(0);
String camel = Character.toUpperCase(c) + name.substring(1);
Method method = new Method();
method.setVisibility(JavaVisibility.PUBLIC);
method.setName("set" + camel);
method.addParameter(new Parameter(new FullyQualifiedJavaType(pageQualifiedName), name));
method.addBodyLine("this." + name + "=" + name + ";");
topLevelClass.addMethod(method);
method = new Method();
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(new FullyQualifiedJavaType(pageQualifiedName));
method.setName("get" + camel);
method.addBodyLine("return " + name + ";");
topLevelClass.addMethod(method);
return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
}
/**
* 在Example配置为true时,对生成的排除了大字段Example查询语句添加分页语句
*/
@Override
public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
XmlElement pageStart = new XmlElement("include");
pageStart.addAttribute(new Attribute("refid", "PageQueryPrefix"));
element.getElements().add(0, pageStart);
XmlElement isNotNullElement = new XmlElement("include");
isNotNullElement.addAttribute(new Attribute("refid", "PageQuerySuffix"));
element.getElements().add(isNotNullElement);
return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.OutputUtilities;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
/**
*
* @author 罗勇
* @date 2013年11月19日 下午3:47:25
*/
public class InsertAndUpdateBatch extends PluginAdapter {
private String item = "item";
/**
* 验证插件的配置是否正确
*/
public boolean validate(List warnings) {
return true;
}
/**
* 在接口中添加方法
*/
@Override
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
String objectName = introspectedTable.getTableConfiguration().getDomainObjectName();//对象名称
interfaze.addImportedType(new FullyQualifiedJavaType("java.util.List"));
Method method = new Method();//
method.addJavaDocLine("/**");
method.addJavaDocLine(" * Batch update or insert. Parameters can not be more than 2100");
method.addJavaDocLine(" * list of size not greater than 1000");
method.addJavaDocLine(" */");
method.setName("updateBySelectiveBatch");
method.addParameter(new Parameter(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"), "list"));
method.setReturnType(new FullyQualifiedJavaType("void"));
/*该行代码的作用:当commentGenerator配置为false时,接口可以生成注释代码。
没有意义,所以注释,其他新加的方法已经删除*/
//context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);
interfaze.addMethod(method);
method = new Method();//
method.setName("updateBatch");
method.addParameter(new Parameter(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"), "list"));
method.setReturnType(new FullyQualifiedJavaType("void"));
interfaze.addMethod(method);
method = new Method();//
method.setName("insertBatch");
method.addParameter(new Parameter(new FullyQualifiedJavaType("java.util.List<" + objectName + ">"), "list"));
method.setReturnType(new FullyQualifiedJavaType("void"));
interfaze.addMethod(method);
return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
}
/**
* 在xml文件中添加需要的元素
*/
@Override
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
XmlElement parentElement = document.getRootElement();
String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();//数据库表名
parentElement.addElement(getUpdateBatchBySelectiveElement(introspectedTable, tableName));
parentElement.addElement(getUpdateBatchElement(introspectedTable, tableName));//批量更新
parentElement.addElement(getInsertBatchElement(introspectedTable, tableName));//批量插入
return super.sqlMapDocumentGenerated(document, introspectedTable);
}
/**
* 批量修改BySelective
* @param introspectedTable
* @param tableName
* @return
*/
public XmlElement getUpdateBatchBySelectiveElement(IntrospectedTable introspectedTable, String tableName) {
XmlElement updateBatchElement = new XmlElement("update");
updateBatchElement.addAttribute(new Attribute("id", "updateBySelectiveBatch"));
XmlElement foreachElement = NewForeachElement();
XmlElement ifElement = NewIfElement(introspectedTable.getPrimaryKeyColumns());
/*该行代码的作用:当commentGenerator配置为false时,sql可以生成注释代码。
没有意义,所以注释,其他新加的方法已经删除*/
//context.getCommentGenerator().addComment(updateBatchElement);
StringBuilder sb = new StringBuilder();
sb.append("update ").append(tableName);
ifElement.addElement(new TextElement(sb.toString()));
XmlElement dynamicElement = new XmlElement("set");
ifElement.addElement(dynamicElement);
for (IntrospectedColumn introspectedColumn : introspectedTable.getNonPrimaryKeyColumns()) {
XmlElement isNotNullElement = new XmlElement("if");
isNotNullElement.addAttribute(new Attribute("test", introspectedColumn.getJavaProperty(item + ".") + " != null"));
dynamicElement.addElement(isNotNullElement);
sb.setLength(0);
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + "."));
sb.append(',');
isNotNullElement.addElement(new TextElement(sb.toString()));
}
boolean and = false;
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
sb.setLength(0);
if (and) {
sb.append(" and ");
} else {
sb.append("where ");
and = true;
}
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + "."));
ifElement.addElement(new TextElement(sb.toString()));
}
foreachElement.addElement(ifElement);
updateBatchElement.addElement(foreachElement);
return updateBatchElement;
}
/**
* 批量修改
* @param introspectedTable
* @param tableName
* @return
*/
public XmlElement getUpdateBatchElement(IntrospectedTable introspectedTable, String tableName) {
XmlElement updateBatchElement = new XmlElement("update");
updateBatchElement.addAttribute(new Attribute("id", "updateBatch"));
XmlElement foreachElement = NewForeachElement();
XmlElement ifElement = NewIfElement(introspectedTable.getPrimaryKeyColumns());
StringBuilder sb = new StringBuilder();
sb.append("update ").append(tableName);
ifElement.addElement(new TextElement(sb.toString()));
// set up for first column
sb.setLength(0);
sb.append("set ");
Iterator iter = introspectedTable.getNonPrimaryKeyColumns().iterator();
while (iter.hasNext()) {
IntrospectedColumn introspectedColumn = iter.next();
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(introspectedColumn));
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + "."));
if (iter.hasNext()) {
sb.append(',');
}
ifElement.addElement(new TextElement(sb.toString()));
// set up for the next column
if (iter.hasNext()) {
sb.setLength(0);
OutputUtilities.xmlIndent(sb, 1);
}
}
boolean and = false;
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
sb.setLength(0);
if (and) {
sb.append(" and ");
} else {
sb.append("where ");
and = true;
}
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + "."));
ifElement.addElement(new TextElement(sb.toString()));
}
foreachElement.addElement(ifElement);
updateBatchElement.addElement(foreachElement);
return updateBatchElement;
}
/**
* 批量添加
* @param introspectedTable
* @param tableName
* @return
*/
public XmlElement getInsertBatchElement(IntrospectedTable introspectedTable, String tableName) {
XmlElement insertBatchElement = new XmlElement("insert");
insertBatchElement.addAttribute(new Attribute("id", "insertBatch"));
XmlElement foreachElement = NewForeachElement();
StringBuilder insertClause = new StringBuilder();
StringBuilder valuesClause = new StringBuilder();
insertClause.append("insert into ");
insertClause.append(tableName);
insertClause.append(" (");
valuesClause.append("values (");
List valuesClauses = new ArrayList();
Iterator iter = introspectedTable.getAllColumns().iterator();
while (iter.hasNext()) {
IntrospectedColumn introspectedColumn = iter.next();
if (introspectedColumn.isIdentity()) {
// cannot set values on identity fields
continue;
}
insertClause.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
valuesClause.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, item + "."));
if (iter.hasNext()) {
insertClause.append(", ");
valuesClause.append(", ");
}
if (valuesClause.length() > 80) {
foreachElement.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(')');
foreachElement.addElement(new TextElement(insertClause.toString()));
valuesClause.append(')');
valuesClauses.add(valuesClause.toString());
for (String clause : valuesClauses) {
foreachElement.addElement(new TextElement(clause));
}
insertBatchElement.addElement(foreachElement);
return insertBatchElement;
}
/**
* @return
*/
public XmlElement NewForeachElement(){
XmlElement foreachElement = new XmlElement("foreach");
foreachElement.addAttribute(new Attribute("collection", "list"));
foreachElement.addAttribute(new Attribute("item", item));
foreachElement.addAttribute(new Attribute("index", "index"));
foreachElement.addAttribute(new Attribute("separator", ";"));
return foreachElement;
}
/**
* @param primaryKeyColumns
* @return
*/
public XmlElement NewIfElement(List primaryKeyColumns){
StringBuilder sb = new StringBuilder();
boolean flag = false;
for (IntrospectedColumn introspectedColumn : primaryKeyColumns) {
if (flag) {
sb.append(" and ");
sb.append(item).append(".");
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(" != null");
} else {
sb.append(item).append(".");
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(" != null");
flag = true;
}
}
XmlElement ifElement = new XmlElement("if");
ifElement.addAttribute(new Attribute("test", sb.toString()));
return ifElement;
}
}