Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d645bff7c0 | ||
|
|
571ba8268c | ||
|
|
9d0068df0f | ||
|
|
3809307502 | ||
|
|
e4187813bd |
@@ -12,6 +12,7 @@
|
||||
* 批量插入插件(BatchInsertPlugin)
|
||||
* 逻辑删除插件(LogicalDeletePlugin)
|
||||
* 数据Model属性对应Column获取插件(ModelColumnPlugin)
|
||||
* 存在即更新插件(UpsertPlugin)
|
||||
|
||||
---------------------------------------
|
||||
Maven引用:
|
||||
@@ -19,7 +20,7 @@ Maven引用:
|
||||
<dependency>
|
||||
<groupId>com.itfsw</groupId>
|
||||
<artifactId>mybatis-generator-plugin</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<version>1.0.6</version>
|
||||
</dependency>
|
||||
```
|
||||
---------------------------------------
|
||||
@@ -252,8 +253,10 @@ Mybatis Generator 插件默认把Model类和Example类都生成到一个包下
|
||||
</plugin>
|
||||
```
|
||||
### 6. 批量插入插件
|
||||
提供了一个批量插入batchInsert方法,因为方法使用了使用了JDBC的getGenereatedKeys方法返回插入主键,所以只能在MYSQL和SQLServer下使用。
|
||||
建议配合数据Model属性对应Column获取插件(ModelColumnPlugin)插件使用,会把批量插入方法从batchInsert(@Param("list") List<Tb> list)增强为batchInsert(@Param("list") List<Tb> list, @Param("insertColumns") Tb.Column ... insertColumns),实现类似于insertSelective插入列!
|
||||
提供了批量插入batchInsert和batchInsertSelective方法,因为方法使用了使用了JDBC的getGenereatedKeys方法返回插入主键,所以只能在MYSQL和SQLServer下使用。
|
||||
需配合数据Model属性对应Column获取插件(ModelColumnPlugin)插件使用,实现类似于insertSelective插入列!
|
||||
PS:为了和Mybatis官方代码风格保持一致,1.0.5+版本把批量插入方法分开了,基于老版本1.0.5-版本生成的代码请继续使用“com.itfsw.mybatis.generator.plugins.BatchInsertOldPlugin”不影响使用
|
||||
PS:继续PS,本来想继续保留老版本代码,不影响老版本已经生成代码使用的,但是始终没有绕过BindingException,只能把代码移入BatchInsertOldPlugin类~~~~~
|
||||
插件:
|
||||
```xml
|
||||
<!-- 批量插入插件 -->
|
||||
@@ -284,7 +287,7 @@ public class Test {
|
||||
// 普通插入,插入所有列
|
||||
this.tbMapper.batchInsert(list);
|
||||
// !!!下面按需插入指定列(类似于insertSelective),需要数据Model属性对应Column获取插件(ModelColumnPlugin)插件
|
||||
this.tbMapper.batchInsert(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);
|
||||
this.tbMapper.batchInsertSelective(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -341,7 +344,7 @@ public class Test {
|
||||
### 8. 数据Model属性对应Column获取插件
|
||||
项目中我们有时需要获取数据Model对应数据库字段的名称,一般直接根据数据Model的属性就可以猜出数据库对应column的名字,可是有的时候当column使用了columnOverride或者columnRenamingRule时就需要去看数据库设计了,所以提供了这个插件获取model对应的数据库Column。
|
||||
* 配合Example Criteria 增强插件(ExampleEnhancedPlugin)使用,这个插件还提供了asc()和desc()方法配合Example的orderBy方法效果更佳。
|
||||
* 配合批量插入插件(BatchInsertPlugin)使用,批量插入会被增强成batchInsert(@Param("list") List<XXX> list, @Param("insertColumns") XXX.Column ... insertColumns)。
|
||||
* 配合批量插入插件(BatchInsertPlugin)使用,batchInsertSelective(@Param("list") List<XXX> list, @Param("selective") XXX.Column ... insertColumns)。
|
||||
|
||||
插件:
|
||||
```xml
|
||||
@@ -395,7 +398,41 @@ public class Test {
|
||||
// 这个会插入表所有列
|
||||
this.tbMapper.batchInsert(list);
|
||||
// 下面按需插入指定列(类似于insertSelective)
|
||||
this.tbMapper.batchInsert(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);
|
||||
this.tbMapper.batchInsertSelective(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);
|
||||
}
|
||||
}
|
||||
```
|
||||
### 9. 存在即更新插件
|
||||
使用MySQL的[“insert ... on duplicate key update”](https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html)实现存在即更新操作,简化数据入库操作([[issues#2]](https://github.com/itfsw/mybatis-generator-plugin/issues/2))。
|
||||
|
||||
插件:
|
||||
```xml
|
||||
<!-- 存在即更新插件 -->
|
||||
<plugin type="com.itfsw.mybatis.generator.plugins.UpsertPlugin"/>
|
||||
```
|
||||
使用:
|
||||
```java
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
// 1. 未入库数据入库,执行insert
|
||||
Tb tb = new Tb.Builder()
|
||||
.field1(1)
|
||||
.field2("xx0")
|
||||
.delFlag((short)0)
|
||||
.build();
|
||||
int k0 = this.tbMapper.upsert(tb);
|
||||
// 2. 已入库数据再次入库,执行update(!!需要注意如触发update其返回的受影响行数为2)
|
||||
tb.setField2("xx1");
|
||||
int k1 = this.tbMapper.upsert(tb);
|
||||
|
||||
// 3. 类似insertSelective实现选择入库
|
||||
Tb tb1 = new Tb.Builder()
|
||||
.field1(1)
|
||||
.field2("xx0")
|
||||
.build();
|
||||
int k2 = this.tbMapper.upsertSelective(tb1);
|
||||
tb1.setField2("xx1");
|
||||
int k3 = this.tbMapper.upsertSelective(tb1);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<groupId>com.itfsw</groupId>
|
||||
<artifactId>mybatis-generator-plugin</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<version>1.0.6</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.groupId}:${project.artifactId}</name>
|
||||
@@ -175,7 +175,7 @@
|
||||
<connection>scm:git:https://github.com/itfsw/mybatis-generator-plugin.git</connection>
|
||||
<developerConnection>scm:git:https://github.com/itfsw/mybatis-generator-plugin.git</developerConnection>
|
||||
<url>https://github.com/itfsw/mybatis-generator-plugin</url>
|
||||
<tag>v1.0.5</tag>
|
||||
<tag>v1.0.6</tag>
|
||||
</scm>
|
||||
|
||||
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++distribution++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) 2017.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.itfsw.mybatis.generator.plugins;
|
||||
|
||||
import com.itfsw.mybatis.generator.plugins.utils.CommTools;
|
||||
import com.itfsw.mybatis.generator.plugins.utils.CommentTools;
|
||||
import org.mybatis.generator.api.IntrospectedColumn;
|
||||
import org.mybatis.generator.api.IntrospectedTable;
|
||||
import org.mybatis.generator.api.PluginAdapter;
|
||||
import org.mybatis.generator.api.dom.java.*;
|
||||
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.ListUtilities;
|
||||
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
|
||||
import org.mybatis.generator.config.Context;
|
||||
import org.mybatis.generator.config.PluginConfiguration;
|
||||
import org.mybatis.generator.internal.util.StringUtility;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------------------
|
||||
* 批量插入插件
|
||||
* ---------------------------------------------------------------------------
|
||||
* @author: hewei
|
||||
* @time:2017/1/13 9:33
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
@Deprecated
|
||||
public class BatchInsertOldPlugin extends PluginAdapter {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BatchInsertOldPlugin.class);
|
||||
public static final String METHOD_BATCH_INSERT = "batchInsert"; // 方法名
|
||||
private boolean hasModelBuilderPlugin; // 是否配置了ModelBuilderPlugin插件
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean validate(List<String> warnings) {
|
||||
// 插件使用前提是targetRuntime为MyBatis3
|
||||
if (StringUtility.stringHasValue(getContext().getTargetRuntime()) && "MyBatis3".equalsIgnoreCase(getContext().getTargetRuntime()) == false) {
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "要求运行targetRuntime必须为MyBatis3!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 插件使用前提是数据库为MySQL或者SQLserver,因为返回主键使用了JDBC的getGenereatedKeys方法获取主键
|
||||
if ("com.mysql.jdbc.Driver".equalsIgnoreCase(this.getContext().getJdbcConnectionConfiguration().getDriverClass()) == false
|
||||
&& "com.microsoft.jdbc.sqlserver.SQLServer".equalsIgnoreCase(this.getContext().getJdbcConnectionConfiguration().getDriverClass()) == false
|
||||
&& "com.microsoft.sqlserver.jdbc.SQLServerDriver".equalsIgnoreCase(this.getContext().getJdbcConnectionConfiguration().getDriverClass()) == false){
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "插件使用前提是数据库为MySQL或者SQLserver,因为返回主键使用了JDBC的getGenereatedKeys方法获取主键!");
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "插件已过期,不再维护请使用com.itfsw.mybatis.generator.plugins.BatchInsertPlugin区分batchInsert和batchInsertSelective!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void initialized(IntrospectedTable introspectedTable) {
|
||||
// 插件使用前提是使用了ModelColumnPlugin插件
|
||||
Context ctx = getContext();
|
||||
// 利用反射获取pluginConfigurations属性
|
||||
try {
|
||||
java.lang.reflect.Field field = Context.class.getDeclaredField("pluginConfigurations");
|
||||
field.setAccessible(true);
|
||||
List<PluginConfiguration> list = (List<PluginConfiguration>) field.get(ctx);
|
||||
// 检查是否配置了ModelColumnPlugin插件
|
||||
for (PluginConfiguration config: list) {
|
||||
if (ModelColumnPlugin.class.getName().equals(config.getConfigurationType())){
|
||||
this.hasModelBuilderPlugin = true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Java Client Methods 生成
|
||||
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
|
||||
*
|
||||
* @param interfaze
|
||||
* @param topLevelClass
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
|
||||
if (hasModelBuilderPlugin){
|
||||
// 方法生成
|
||||
Method method = new Method(METHOD_BATCH_INSERT);
|
||||
// 返回值类型
|
||||
method.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
FullyQualifiedJavaType type = FullyQualifiedJavaType.getNewListInstance();
|
||||
type.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass());
|
||||
method.addParameter(new Parameter(type, "list", "@Param(\"list\")"));
|
||||
FullyQualifiedJavaType type1 = new FullyQualifiedJavaType(introspectedTable.getRules().calculateAllFieldsClass().getShortName()+"."+ModelColumnPlugin.ENUM_NAME);
|
||||
method.addParameter(new Parameter(type1, "insertColumns", "@Param(\"insertColumns\")", true));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(method, introspectedTable);
|
||||
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(method);
|
||||
logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。");
|
||||
} else {
|
||||
// 方法生成
|
||||
Method method = new Method(METHOD_BATCH_INSERT);
|
||||
// 方法可见性 interface会忽略
|
||||
// method.setVisibility(JavaVisibility.PUBLIC);
|
||||
// 返回值类型
|
||||
method.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
FullyQualifiedJavaType type = FullyQualifiedJavaType.getNewListInstance();
|
||||
type.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass());
|
||||
method.addParameter(new Parameter(type, "list", "@Param(\"list\")"));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(method, introspectedTable);
|
||||
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(method);
|
||||
logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL Map Methods 生成
|
||||
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
|
||||
*
|
||||
* @param document
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
|
||||
if (hasModelBuilderPlugin){
|
||||
XmlElement element = new XmlElement("insert");
|
||||
element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT));
|
||||
// 参数类型
|
||||
element.addAttribute(new Attribute("parameterType", "map"));
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(element);
|
||||
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
CommTools.useGeneratedKeys(element, introspectedTable);
|
||||
|
||||
// choose 节点
|
||||
XmlElement choose = new XmlElement("choose");
|
||||
// when 节点
|
||||
XmlElement when = new XmlElement("when");
|
||||
when.addAttribute(new Attribute("test", "insertColumns.length != 0"));
|
||||
when.addElement(new TextElement("insert into "+introspectedTable.getFullyQualifiedTableNameAtRuntime()+" ("));
|
||||
|
||||
XmlElement foreachInsertColumns = new XmlElement("foreach");
|
||||
foreachInsertColumns.addAttribute(new Attribute("collection", "insertColumns"));
|
||||
foreachInsertColumns.addAttribute(new Attribute("item", "column"));
|
||||
foreachInsertColumns.addAttribute(new Attribute("separator", ","));
|
||||
foreachInsertColumns.addElement(new TextElement("${column.value}"));
|
||||
|
||||
when.addElement(foreachInsertColumns);
|
||||
|
||||
when.addElement(new TextElement(")"));
|
||||
|
||||
// values
|
||||
when.addElement(new TextElement("values"));
|
||||
|
||||
// foreach values
|
||||
XmlElement foreachValues = new XmlElement("foreach");
|
||||
foreachValues.addAttribute(new Attribute("collection", "list"));
|
||||
foreachValues.addAttribute(new Attribute("item", "item"));
|
||||
foreachValues.addAttribute(new Attribute("separator", ","));
|
||||
|
||||
foreachValues.addElement(new TextElement("("));
|
||||
|
||||
// foreach 所有插入的列,比较是否存在
|
||||
XmlElement foreachInsertColumnsCheck = new XmlElement("foreach");
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("collection", "insertColumns"));
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("item", "column"));
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("separator", ","));
|
||||
|
||||
// 所有表字段
|
||||
List<IntrospectedColumn> columns = ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns());
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
IntrospectedColumn introspectedColumn = columns.get(i);
|
||||
XmlElement check = new XmlElement("if");
|
||||
check.addAttribute(new Attribute("test", "'"+introspectedColumn.getActualColumnName()+"' == column.value"));
|
||||
check.addElement(new TextElement(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, "item.")));
|
||||
|
||||
foreachInsertColumnsCheck.addElement(check);
|
||||
}
|
||||
foreachValues.addElement(foreachInsertColumnsCheck);
|
||||
|
||||
foreachValues.addElement(new TextElement(")"));
|
||||
|
||||
when.addElement(foreachValues);
|
||||
choose.addElement(when);
|
||||
|
||||
// 普通不带insertColumns参数实现
|
||||
XmlElement otherwise = new XmlElement("otherwise");
|
||||
this.addNormalBatchInsertXml(otherwise, introspectedTable);
|
||||
choose.addElement(otherwise);
|
||||
|
||||
element.addElement(choose);
|
||||
if (context.getPlugins().sqlMapInsertElementGenerated(element, introspectedTable)) {
|
||||
document.getRootElement().addElement(element);
|
||||
logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。");
|
||||
}
|
||||
} else {
|
||||
XmlElement element = new XmlElement("insert"); //$NON-NLS-1$
|
||||
|
||||
element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT)); //$NON-NLS-1$
|
||||
|
||||
// 参数类型
|
||||
element.addAttribute(new Attribute("parameterType", FullyQualifiedJavaType.getNewListInstance().getFullyQualifiedName()));
|
||||
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(element);
|
||||
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
CommTools.useGeneratedKeys(element, introspectedTable);
|
||||
|
||||
// 普通插入语句
|
||||
this.addNormalBatchInsertXml(element, introspectedTable);
|
||||
|
||||
document.getRootElement().addElement(element);
|
||||
logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通不带insertColumns的插入语句Xml实现
|
||||
*
|
||||
* @param element
|
||||
* @param introspectedTable
|
||||
*/
|
||||
private void addNormalBatchInsertXml(XmlElement element, IntrospectedTable introspectedTable) {
|
||||
|
||||
StringBuilder insertClause = new StringBuilder();
|
||||
StringBuilder valuesClause = new StringBuilder();
|
||||
|
||||
insertClause.append("insert into "); //$NON-NLS-1$
|
||||
insertClause.append(introspectedTable.getFullyQualifiedTableNameAtRuntime());
|
||||
insertClause.append(" ("); //$NON-NLS-1$
|
||||
|
||||
valuesClause.append(" ("); //$NON-NLS-1$
|
||||
|
||||
List<String> valuesClauses = new ArrayList<String>();
|
||||
List<IntrospectedColumn> columns = ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns());
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
IntrospectedColumn introspectedColumn = columns.get(i);
|
||||
|
||||
insertClause.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
|
||||
|
||||
// 生成foreach下插入values
|
||||
valuesClause.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, "item."));
|
||||
if (i + 1 < columns.size()) {
|
||||
insertClause.append(", "); //$NON-NLS-1$
|
||||
valuesClause.append(", "); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
insertClause.append(')');
|
||||
element.addElement(new TextElement(insertClause.toString()));
|
||||
|
||||
valuesClause.append(')');
|
||||
valuesClauses.add(valuesClause.toString());
|
||||
|
||||
|
||||
// 添加foreach节点
|
||||
XmlElement foreachElement = new XmlElement("foreach");
|
||||
foreachElement.addAttribute(new Attribute("collection", "list"));
|
||||
foreachElement.addAttribute(new Attribute("item", "item"));
|
||||
foreachElement.addAttribute(new Attribute("separator", ","));
|
||||
|
||||
for (String clause : valuesClauses) {
|
||||
foreachElement.addElement(new TextElement(clause));
|
||||
}
|
||||
|
||||
// values 构建
|
||||
element.addElement(new TextElement("values"));
|
||||
element.addElement(foreachElement);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.itfsw.mybatis.generator.plugins;
|
||||
|
||||
import com.itfsw.mybatis.generator.plugins.utils.CommTools;
|
||||
import com.itfsw.mybatis.generator.plugins.utils.CommentTools;
|
||||
import org.mybatis.generator.api.IntrospectedColumn;
|
||||
import org.mybatis.generator.api.IntrospectedTable;
|
||||
@@ -28,7 +29,6 @@ import org.mybatis.generator.api.dom.xml.XmlElement;
|
||||
import org.mybatis.generator.codegen.mybatis3.ListUtilities;
|
||||
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
|
||||
import org.mybatis.generator.config.Context;
|
||||
import org.mybatis.generator.config.GeneratedKey;
|
||||
import org.mybatis.generator.config.PluginConfiguration;
|
||||
import org.mybatis.generator.internal.util.StringUtility;
|
||||
import org.slf4j.Logger;
|
||||
@@ -48,7 +48,7 @@ import java.util.List;
|
||||
public class BatchInsertPlugin extends PluginAdapter {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BatchInsertPlugin.class);
|
||||
public static final String METHOD_BATCH_INSERT = "batchInsert"; // 方法名
|
||||
private boolean hasModelBuilderPlugin; // 是否配置了ModelBuilderPlugin插件
|
||||
public static final String METHOD_BATCH_INSERT_SELECTIVE = "batchInsertSelective"; // 方法名
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@@ -68,36 +68,40 @@ public class BatchInsertPlugin extends PluginAdapter {
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "插件使用前提是数据库为MySQL或者SQLserver,因为返回主键使用了JDBC的getGenereatedKeys方法获取主键!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void initialized(IntrospectedTable introspectedTable) {
|
||||
|
||||
// 插件使用前提是使用了ModelColumnPlugin插件
|
||||
Context ctx = getContext();
|
||||
// 利用反射获取pluginConfigurations属性
|
||||
try {
|
||||
Context ctx = getContext();
|
||||
// 利用反射获取pluginConfigurations属性
|
||||
java.lang.reflect.Field field = Context.class.getDeclaredField("pluginConfigurations");
|
||||
field.setAccessible(true);
|
||||
List<PluginConfiguration> list = (List<PluginConfiguration>) field.get(ctx);
|
||||
// 检查是否配置了ModelColumnPlugin插件
|
||||
boolean unFind = true;
|
||||
for (PluginConfiguration config: list) {
|
||||
if (ModelColumnPlugin.class.getName().equals(config.getConfigurationType())){
|
||||
this.hasModelBuilderPlugin = true;
|
||||
unFind = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 建议使用ModelColumnPlugin插件
|
||||
if (unFind){
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "插件需配合com.itfsw.mybatis.generator.plugins.ModelColumnPlugin插件使用!");
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
// TODO
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "插件如之前使用1.0.5-的插件可继续使用com.itfsw.mybatis.generator.plugins.BatchInsertOldPlugin或者修改batchInsert(@Param(\"list\") List<Tb> list, @Param(\"insertColumns\") Tb.Column ... selective)调用为batchInsertSelective!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Java Client Methods 生成
|
||||
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
|
||||
@@ -109,41 +113,31 @@ public class BatchInsertPlugin extends PluginAdapter {
|
||||
*/
|
||||
@Override
|
||||
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
|
||||
if (hasModelBuilderPlugin){
|
||||
// 方法生成
|
||||
Method method = new Method(METHOD_BATCH_INSERT);
|
||||
// 返回值类型
|
||||
method.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
FullyQualifiedJavaType type = FullyQualifiedJavaType.getNewListInstance();
|
||||
type.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass());
|
||||
method.addParameter(new Parameter(type, "list", "@Param(\"list\")"));
|
||||
FullyQualifiedJavaType type1 = new FullyQualifiedJavaType(introspectedTable.getRules().calculateAllFieldsClass().getShortName()+"."+ModelColumnPlugin.ENUM_NAME);
|
||||
method.addParameter(new Parameter(type1, "insertColumns", "@Param(\"insertColumns\")", true));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(method, introspectedTable);
|
||||
// 1. batchInsert
|
||||
Method mBatchInsert = new Method(METHOD_BATCH_INSERT);
|
||||
mBatchInsert.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
FullyQualifiedJavaType tList = FullyQualifiedJavaType.getNewListInstance();
|
||||
tList.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass());
|
||||
mBatchInsert.addParameter(new Parameter(tList, "list", "@Param(\"list\")"));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(mBatchInsert, introspectedTable);
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(mBatchInsert);
|
||||
logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。");
|
||||
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(method);
|
||||
logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。");
|
||||
} else {
|
||||
// 方法生成
|
||||
Method method = new Method(METHOD_BATCH_INSERT);
|
||||
// 方法可见性 interface会忽略
|
||||
// method.setVisibility(JavaVisibility.PUBLIC);
|
||||
// 返回值类型
|
||||
method.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
FullyQualifiedJavaType type = FullyQualifiedJavaType.getNewListInstance();
|
||||
type.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass());
|
||||
method.addParameter(new Parameter(type, "list", "@Param(\"list\")"));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(method, introspectedTable);
|
||||
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(method);
|
||||
logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。");
|
||||
}
|
||||
// 2. batchInsertSelective
|
||||
Method mBatchInsertSelective = new Method(METHOD_BATCH_INSERT_SELECTIVE);
|
||||
mBatchInsertSelective.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
FullyQualifiedJavaType tSelective = new FullyQualifiedJavaType(introspectedTable.getRules().calculateAllFieldsClass().getShortName()+"."+ModelColumnPlugin.ENUM_NAME);
|
||||
mBatchInsertSelective.addParameter(new Parameter(tList, "list", "@Param(\"list\")"));
|
||||
mBatchInsertSelective.addParameter(new Parameter(tSelective, "selective", "@Param(\"selective\")", true));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(mBatchInsertSelective, introspectedTable);
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(mBatchInsertSelective);
|
||||
logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsertSelective方法。");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -158,128 +152,16 @@ public class BatchInsertPlugin extends PluginAdapter {
|
||||
*/
|
||||
@Override
|
||||
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
|
||||
if (hasModelBuilderPlugin){
|
||||
XmlElement element = new XmlElement("insert");
|
||||
element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT));
|
||||
// 参数类型
|
||||
element.addAttribute(new Attribute("parameterType", "map"));
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(element);
|
||||
// 1. batchInsert
|
||||
XmlElement batchInsertEle = new XmlElement("insert");
|
||||
batchInsertEle.addAttribute(new Attribute("id", METHOD_BATCH_INSERT));
|
||||
// 参数类型
|
||||
batchInsertEle.addAttribute(new Attribute("parameterType", "map"));
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(batchInsertEle);
|
||||
|
||||
GeneratedKey gk = introspectedTable.getGeneratedKey();
|
||||
if (gk != null) {
|
||||
IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn());
|
||||
// if the column is null, then it's a configuration error. The
|
||||
// warning has already been reported
|
||||
if (introspectedColumn != null) {
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
element.addAttribute(new Attribute("useGeneratedKeys", "true")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
element.addAttribute(new Attribute("keyProperty", introspectedColumn.getJavaProperty())); //$NON-NLS-1$
|
||||
element.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
// choose 节点
|
||||
XmlElement choose = new XmlElement("choose");
|
||||
// when 节点
|
||||
XmlElement when = new XmlElement("when");
|
||||
when.addAttribute(new Attribute("test", "insertColumns.length != 0"));
|
||||
when.addElement(new TextElement("insert into "+introspectedTable.getFullyQualifiedTableNameAtRuntime()+" ("));
|
||||
|
||||
XmlElement foreachInsertColumns = new XmlElement("foreach");
|
||||
foreachInsertColumns.addAttribute(new Attribute("collection", "insertColumns"));
|
||||
foreachInsertColumns.addAttribute(new Attribute("item", "column"));
|
||||
foreachInsertColumns.addAttribute(new Attribute("separator", ","));
|
||||
foreachInsertColumns.addElement(new TextElement("${column.value}"));
|
||||
|
||||
when.addElement(foreachInsertColumns);
|
||||
|
||||
when.addElement(new TextElement(")"));
|
||||
|
||||
// values
|
||||
when.addElement(new TextElement("values"));
|
||||
|
||||
// foreach values
|
||||
XmlElement foreachValues = new XmlElement("foreach");
|
||||
foreachValues.addAttribute(new Attribute("collection", "list"));
|
||||
foreachValues.addAttribute(new Attribute("item", "item"));
|
||||
foreachValues.addAttribute(new Attribute("separator", ","));
|
||||
|
||||
foreachValues.addElement(new TextElement("("));
|
||||
|
||||
// foreach 所有插入的列,比较是否存在
|
||||
XmlElement foreachInsertColumnsCheck = new XmlElement("foreach");
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("collection", "insertColumns"));
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("item", "column"));
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("separator", ","));
|
||||
|
||||
// 所有表字段
|
||||
List<IntrospectedColumn> columns = ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns());
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
IntrospectedColumn introspectedColumn = columns.get(i);
|
||||
XmlElement check = new XmlElement("if");
|
||||
check.addAttribute(new Attribute("test", "'"+introspectedColumn.getActualColumnName()+"' == column.value"));
|
||||
check.addElement(new TextElement(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, "item.")));
|
||||
|
||||
foreachInsertColumnsCheck.addElement(check);
|
||||
}
|
||||
foreachValues.addElement(foreachInsertColumnsCheck);
|
||||
|
||||
foreachValues.addElement(new TextElement(")"));
|
||||
|
||||
when.addElement(foreachValues);
|
||||
choose.addElement(when);
|
||||
|
||||
// 普通不带insertColumns参数实现
|
||||
XmlElement otherwise = new XmlElement("otherwise");
|
||||
this.addNormalBatchInsertXml(otherwise, introspectedTable);
|
||||
choose.addElement(otherwise);
|
||||
|
||||
element.addElement(choose);
|
||||
if (context.getPlugins().sqlMapInsertElementGenerated(element, introspectedTable)) {
|
||||
document.getRootElement().addElement(element);
|
||||
logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。");
|
||||
}
|
||||
} else {
|
||||
XmlElement element = new XmlElement("insert"); //$NON-NLS-1$
|
||||
|
||||
element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT)); //$NON-NLS-1$
|
||||
|
||||
// 参数类型
|
||||
element.addAttribute(new Attribute("parameterType", FullyQualifiedJavaType.getNewListInstance().getFullyQualifiedName()));
|
||||
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(element);
|
||||
|
||||
GeneratedKey gk = introspectedTable.getGeneratedKey();
|
||||
if (gk != null) {
|
||||
IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn());
|
||||
// if the column is null, then it's a configuration error. The
|
||||
// warning has already been reported
|
||||
if (introspectedColumn != null) {
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
element.addAttribute(new Attribute("useGeneratedKeys", "true")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
element.addAttribute(new Attribute("keyProperty", introspectedColumn.getJavaProperty())); //$NON-NLS-1$
|
||||
element.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
// 普通插入语句
|
||||
this.addNormalBatchInsertXml(element, introspectedTable);
|
||||
|
||||
document.getRootElement().addElement(element);
|
||||
logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通不带insertColumns的插入语句Xml实现
|
||||
*
|
||||
* @param element
|
||||
* @param introspectedTable
|
||||
*/
|
||||
private void addNormalBatchInsertXml(XmlElement element, IntrospectedTable introspectedTable) {
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
CommTools.useGeneratedKeys(batchInsertEle, introspectedTable);
|
||||
|
||||
StringBuilder insertClause = new StringBuilder();
|
||||
StringBuilder valuesClause = new StringBuilder();
|
||||
@@ -306,7 +188,7 @@ public class BatchInsertPlugin extends PluginAdapter {
|
||||
}
|
||||
|
||||
insertClause.append(')');
|
||||
element.addElement(new TextElement(insertClause.toString()));
|
||||
batchInsertEle.addElement(new TextElement(insertClause.toString()));
|
||||
|
||||
valuesClause.append(')');
|
||||
valuesClauses.add(valuesClause.toString());
|
||||
@@ -323,7 +205,75 @@ public class BatchInsertPlugin extends PluginAdapter {
|
||||
}
|
||||
|
||||
// values 构建
|
||||
batchInsertEle.addElement(new TextElement("values"));
|
||||
batchInsertEle.addElement(foreachElement);
|
||||
if (context.getPlugins().sqlMapInsertElementGenerated(batchInsertEle, introspectedTable)) {
|
||||
document.getRootElement().addElement(batchInsertEle);
|
||||
logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。");
|
||||
}
|
||||
|
||||
// 2. batchInsertSelective
|
||||
XmlElement element = new XmlElement("insert");
|
||||
element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT_SELECTIVE));
|
||||
// 参数类型
|
||||
element.addAttribute(new Attribute("parameterType", "map"));
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(element);
|
||||
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
CommTools.useGeneratedKeys(element, introspectedTable);
|
||||
|
||||
element.addElement(new TextElement("insert into "+introspectedTable.getFullyQualifiedTableNameAtRuntime()+" ("));
|
||||
|
||||
XmlElement foreachInsertColumns = new XmlElement("foreach");
|
||||
foreachInsertColumns.addAttribute(new Attribute("collection", "selective"));
|
||||
foreachInsertColumns.addAttribute(new Attribute("item", "column"));
|
||||
foreachInsertColumns.addAttribute(new Attribute("separator", ","));
|
||||
foreachInsertColumns.addElement(new TextElement("${column.value}"));
|
||||
|
||||
element.addElement(foreachInsertColumns);
|
||||
|
||||
element.addElement(new TextElement(")"));
|
||||
|
||||
// values
|
||||
element.addElement(new TextElement("values"));
|
||||
element.addElement(foreachElement);
|
||||
|
||||
// foreach values
|
||||
XmlElement foreachValues = new XmlElement("foreach");
|
||||
foreachValues.addAttribute(new Attribute("collection", "list"));
|
||||
foreachValues.addAttribute(new Attribute("item", "item"));
|
||||
foreachValues.addAttribute(new Attribute("separator", ","));
|
||||
|
||||
foreachValues.addElement(new TextElement("("));
|
||||
|
||||
// foreach 所有插入的列,比较是否存在
|
||||
XmlElement foreachInsertColumnsCheck = new XmlElement("foreach");
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("collection", "selective"));
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("item", "column"));
|
||||
foreachInsertColumnsCheck.addAttribute(new Attribute("separator", ","));
|
||||
|
||||
// 所有表字段
|
||||
List<IntrospectedColumn> columns1 = ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns());
|
||||
for (int i = 0; i < columns1.size(); i++) {
|
||||
IntrospectedColumn introspectedColumn = columns.get(i);
|
||||
XmlElement check = new XmlElement("if");
|
||||
check.addAttribute(new Attribute("test", "'"+introspectedColumn.getActualColumnName()+"' == column.value"));
|
||||
check.addElement(new TextElement(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, "item.")));
|
||||
|
||||
foreachInsertColumnsCheck.addElement(check);
|
||||
}
|
||||
foreachValues.addElement(foreachInsertColumnsCheck);
|
||||
|
||||
foreachValues.addElement(new TextElement(")"));
|
||||
|
||||
element.addElement(foreachValues);
|
||||
|
||||
if (context.getPlugins().sqlMapInsertElementGenerated(element, introspectedTable)) {
|
||||
document.getRootElement().addElement(element);
|
||||
logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsertSelective实现方法。");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 2017.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.itfsw.mybatis.generator.plugins;
|
||||
|
||||
import com.itfsw.mybatis.generator.plugins.utils.CommTools;
|
||||
import com.itfsw.mybatis.generator.plugins.utils.CommentTools;
|
||||
import org.mybatis.generator.api.IntrospectedColumn;
|
||||
import org.mybatis.generator.api.IntrospectedTable;
|
||||
import org.mybatis.generator.api.PluginAdapter;
|
||||
import org.mybatis.generator.api.dom.java.*;
|
||||
import org.mybatis.generator.api.dom.xml.*;
|
||||
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
|
||||
import org.mybatis.generator.internal.util.StringUtility;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------------------
|
||||
* 存在即更新插件
|
||||
* ---------------------------------------------------------------------------
|
||||
* @author: hewei
|
||||
* @time:2017/3/21 10:59
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
public class UpsertPlugin extends PluginAdapter {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BatchInsertPlugin.class);
|
||||
public static final String METHOD_UPSERT = "upsert"; // 方法名
|
||||
public static final String METHOD_UPSERT_SELECTIVE = "upsertSelective"; // 方法名
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean validate(List<String> warnings) {
|
||||
// 插件使用前提是targetRuntime为MyBatis3
|
||||
if (StringUtility.stringHasValue(getContext().getTargetRuntime()) && "MyBatis3".equalsIgnoreCase(getContext().getTargetRuntime()) == false) {
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "要求运行targetRuntime必须为MyBatis3!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 插件使用前提是数据库为MySQL
|
||||
if ("com.mysql.jdbc.Driver".equalsIgnoreCase(this.getContext().getJdbcConnectionConfiguration().getDriverClass()) == false){
|
||||
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "插件使用前提是数据库为MySQL!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Java Client Methods 生成
|
||||
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
|
||||
*
|
||||
* @param interfaze
|
||||
* @param topLevelClass
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
|
||||
// ====================================== 1. upsert ======================================
|
||||
Method mUpsert = new Method(METHOD_UPSERT);
|
||||
// 返回值类型
|
||||
mUpsert.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
mUpsert.addParameter(new Parameter(introspectedTable.getRules().calculateAllFieldsClass(), "record"));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(mUpsert, introspectedTable);
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(mUpsert);
|
||||
logger.debug("itfsw(存在即更新插件):" + interfaze.getType().getShortName() + "增加upsert方法。");
|
||||
|
||||
// ====================================== 2. upsertSelective ======================================
|
||||
Method mUpsertSelective = new Method(METHOD_UPSERT_SELECTIVE);
|
||||
// 返回值类型
|
||||
mUpsertSelective.setReturnType(FullyQualifiedJavaType.getIntInstance());
|
||||
// 添加参数
|
||||
mUpsertSelective.addParameter(new Parameter(introspectedTable.getRules().calculateAllFieldsClass(), "record"));
|
||||
// 添加方法说明
|
||||
CommentTools.addGeneralMethodComment(mUpsertSelective, introspectedTable);
|
||||
// interface 增加方法
|
||||
interfaze.addMethod(mUpsertSelective);
|
||||
logger.debug("itfsw(存在即更新插件):" + interfaze.getType().getShortName() + "增加upsertSelective方法。");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL Map Methods 生成
|
||||
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
|
||||
*
|
||||
* @param document
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
|
||||
|
||||
// ====================================== 1. upsert ======================================
|
||||
XmlElement eleUpsert = new XmlElement("insert");
|
||||
eleUpsert.addAttribute(new Attribute("id", METHOD_UPSERT));
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(eleUpsert);
|
||||
|
||||
// 参数类型
|
||||
eleUpsert.addAttribute(new Attribute("parameterType", introspectedTable.getRules().calculateAllFieldsClass().getFullyQualifiedName()));
|
||||
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
CommTools.useGeneratedKeys(eleUpsert, introspectedTable);
|
||||
|
||||
// insert
|
||||
eleUpsert.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
|
||||
eleUpsert.addElement(this.generateInsertClause(introspectedTable));
|
||||
eleUpsert.addElement(new TextElement("values"));
|
||||
eleUpsert.addElement(this.generateValuesClause(introspectedTable));
|
||||
eleUpsert.addElement(new TextElement("on duplicate key update "));
|
||||
eleUpsert.addElement(this.generateDuplicateClause(introspectedTable));
|
||||
|
||||
document.getRootElement().addElement(eleUpsert);
|
||||
logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加upsert实现方法。");
|
||||
|
||||
// ====================================== 2. upsertSelective ======================================
|
||||
XmlElement eleUpsertSelective = new XmlElement("insert");
|
||||
eleUpsertSelective.addAttribute(new Attribute("id", METHOD_UPSERT_SELECTIVE));
|
||||
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
|
||||
CommentTools.addComment(eleUpsertSelective);
|
||||
|
||||
// 参数类型
|
||||
eleUpsertSelective.addAttribute(new Attribute("parameterType", introspectedTable.getRules().calculateAllFieldsClass().getFullyQualifiedName()));
|
||||
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
CommTools.useGeneratedKeys(eleUpsertSelective, introspectedTable);
|
||||
|
||||
// insert
|
||||
eleUpsertSelective.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
|
||||
eleUpsertSelective.addElement(this.generateInsertSelectiveClause(introspectedTable));
|
||||
eleUpsertSelective.addElement(new TextElement("values"));
|
||||
eleUpsertSelective.addElement(this.generateValuesSelectiveClause(introspectedTable));
|
||||
eleUpsertSelective.addElement(new TextElement("on duplicate key update "));
|
||||
eleUpsertSelective.addElement(this.generateDuplicateSelectiveClause(introspectedTable));
|
||||
|
||||
document.getRootElement().addElement(eleUpsertSelective);
|
||||
logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加upsertSelective实现方法。");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通insert
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
private Element generateInsertClause(IntrospectedTable introspectedTable){
|
||||
StringBuilder insertClause = new StringBuilder();
|
||||
|
||||
insertClause.append(" (");
|
||||
|
||||
List<IntrospectedColumn> columns = introspectedTable.getAllColumns();
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
IntrospectedColumn introspectedColumn = columns.get(i);
|
||||
|
||||
insertClause.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
|
||||
|
||||
if (i + 1 < columns.size()) {
|
||||
insertClause.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
insertClause.append(") ");
|
||||
|
||||
return new TextElement(insertClause.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通 values
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
private Element generateValuesClause(IntrospectedTable introspectedTable){
|
||||
StringBuilder valuesClause = new StringBuilder();
|
||||
|
||||
valuesClause.append(" (");
|
||||
|
||||
List<IntrospectedColumn> columns = introspectedTable.getAllColumns();
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
IntrospectedColumn introspectedColumn = columns.get(i);
|
||||
|
||||
valuesClause.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
|
||||
if (i + 1 < columns.size()) {
|
||||
valuesClause.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
valuesClause.append(") ");
|
||||
|
||||
return new TextElement(valuesClause.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通duplicate
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
private Element generateDuplicateClause(IntrospectedTable introspectedTable){
|
||||
StringBuilder duplicateClause = new StringBuilder();
|
||||
|
||||
List<IntrospectedColumn> columns = introspectedTable.getAllColumns();
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
IntrospectedColumn introspectedColumn = columns.get(i);
|
||||
|
||||
duplicateClause.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
|
||||
duplicateClause.append(" = ");
|
||||
duplicateClause.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
|
||||
|
||||
if (i + 1 < columns.size()) {
|
||||
duplicateClause.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
return new TextElement(duplicateClause.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通insert
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
private Element generateInsertSelectiveClause(IntrospectedTable introspectedTable){
|
||||
XmlElement insertTrimEle = new XmlElement("trim");
|
||||
insertTrimEle.addAttribute(new Attribute("prefix", "("));
|
||||
insertTrimEle.addAttribute(new Attribute("suffix", ")"));
|
||||
insertTrimEle.addAttribute(new Attribute("suffixOverrides", ","));
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
|
||||
|
||||
XmlElement insertNotNullElement = new XmlElement("if"); //$NON-NLS-1$
|
||||
sb.setLength(0);
|
||||
sb.append(introspectedColumn.getJavaProperty());
|
||||
sb.append(" != null");
|
||||
insertNotNullElement.addAttribute(new Attribute("test", sb.toString()));
|
||||
|
||||
sb.setLength(0);
|
||||
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
|
||||
sb.append(',');
|
||||
insertNotNullElement.addElement(new TextElement(sb.toString()));
|
||||
insertTrimEle.addElement(insertNotNullElement);
|
||||
}
|
||||
|
||||
return insertTrimEle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通 values
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
private Element generateValuesSelectiveClause(IntrospectedTable introspectedTable){
|
||||
XmlElement valuesTrimEle = new XmlElement("trim");
|
||||
valuesTrimEle.addAttribute(new Attribute("prefix", "("));
|
||||
valuesTrimEle.addAttribute(new Attribute("suffix", ")"));
|
||||
valuesTrimEle.addAttribute(new Attribute("suffixOverrides", ","));
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
|
||||
|
||||
XmlElement valuesNotNullElement = new XmlElement("if"); //$NON-NLS-1$
|
||||
sb.setLength(0);
|
||||
sb.append(introspectedColumn.getJavaProperty());
|
||||
sb.append(" != null");
|
||||
valuesNotNullElement.addAttribute(new Attribute("test", sb.toString()));
|
||||
|
||||
sb.setLength(0);
|
||||
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
|
||||
sb.append(',');
|
||||
valuesNotNullElement.addElement(new TextElement(sb.toString()));
|
||||
valuesTrimEle.addElement(valuesNotNullElement);
|
||||
}
|
||||
return valuesTrimEle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通duplicate
|
||||
*
|
||||
* @param introspectedTable
|
||||
* @return
|
||||
*/
|
||||
private Element generateDuplicateSelectiveClause(IntrospectedTable introspectedTable){
|
||||
XmlElement duplicateTrimEle = new XmlElement("trim");
|
||||
duplicateTrimEle.addAttribute(new Attribute("suffixOverrides", ","));
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
|
||||
|
||||
XmlElement duplicateNotNullElement = new XmlElement("if"); //$NON-NLS-1$
|
||||
sb.setLength(0);
|
||||
sb.append(introspectedColumn.getJavaProperty());
|
||||
sb.append(" != null");
|
||||
duplicateNotNullElement.addAttribute(new Attribute("test", sb.toString()));
|
||||
|
||||
sb.setLength(0);
|
||||
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
|
||||
sb.append(" = ");
|
||||
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
|
||||
sb.append(",");
|
||||
|
||||
duplicateNotNullElement.addElement(new TextElement(sb.toString()));
|
||||
duplicateTrimEle.addElement(duplicateNotNullElement);
|
||||
}
|
||||
return duplicateTrimEle;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2017.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.itfsw.mybatis.generator.plugins.utils;
|
||||
|
||||
import org.mybatis.generator.api.IntrospectedColumn;
|
||||
import org.mybatis.generator.api.IntrospectedTable;
|
||||
import org.mybatis.generator.api.dom.xml.Attribute;
|
||||
import org.mybatis.generator.api.dom.xml.XmlElement;
|
||||
import org.mybatis.generator.config.GeneratedKey;
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------------------
|
||||
* 一些通用工具集
|
||||
* ---------------------------------------------------------------------------
|
||||
* @author: hewei
|
||||
* @time:2017/3/22 14:03
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
public class CommTools {
|
||||
|
||||
/**
|
||||
* 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
*
|
||||
* @param element
|
||||
* @param introspectedTable
|
||||
*/
|
||||
public static void useGeneratedKeys(XmlElement element, IntrospectedTable introspectedTable){
|
||||
GeneratedKey gk = introspectedTable.getGeneratedKey();
|
||||
if (gk != null) {
|
||||
IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn());
|
||||
// if the column is null, then it's a configuration error. The
|
||||
// warning has already been reported
|
||||
if (introspectedColumn != null) {
|
||||
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
|
||||
element.addAttribute(new Attribute("useGeneratedKeys", "true")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
element.addAttribute(new Attribute("keyProperty", introspectedColumn.getJavaProperty())); //$NON-NLS-1$
|
||||
element.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user