Commit 12bd2b18 authored by hewei's avatar hewei

fixed:[issues#2]

upsertByExample 实现
parent e359e3a6
......@@ -18,17 +18,21 @@ package com.itfsw.mybatis.generator.plugins;
import com.itfsw.mybatis.generator.plugins.utils.CommTools;
import com.itfsw.mybatis.generator.plugins.utils.CommentTools;
import com.itfsw.mybatis.generator.plugins.utils.XmlElementGeneratorTools;
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.ListUtilities;
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.Iterator;
import java.util.List;
import java.util.Properties;
/**
* ---------------------------------------------------------------------------
......@@ -42,6 +46,10 @@ 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"; // 方法名
public static final String METHOD_UPSERT_BY_EXAMPLE = "upsertByExample"; // 方法名
public static final String PRE_ALLOW_MULTI_QUERIES = "allowMultiQueries"; // property allowMultiQueries
private boolean allowMultiQueries = false; // 是否允许多sql提交
/**
* {@inheritDoc}
......@@ -60,6 +68,15 @@ public class UpsertPlugin extends PluginAdapter {
return false;
}
// 插件是否开启了多sql提交
Properties properties = this.getProperties();
String allowMultiQueries = properties.getProperty(PRE_ALLOW_MULTI_QUERIES);
this.allowMultiQueries = allowMultiQueries == null ? false : StringUtility.isTrue(allowMultiQueries);
if (this.allowMultiQueries){
// 提示用户注意信息
logger.warn("itfsw:插件" + this.getClass().getTypeName() + "插件您开启了allowMultiQueries支持,注意在jdbc url 配置中增加“allowMultiQueries=true”支持(不怎么建议使用该功能,开启多sql提交会增加sql注入的风险,请确保你所有sql都使用MyBatis书写,请不要使用statement进行sql提交)!");
}
return true;
}
......@@ -98,6 +115,21 @@ public class UpsertPlugin extends PluginAdapter {
interfaze.addMethod(mUpsertSelective);
logger.debug("itfsw(存在即更新插件):" + interfaze.getType().getShortName() + "增加upsertSelective方法。");
if (this.allowMultiQueries){
// ====================================== 3. upsertByExample ======================================
Method mUpsertByExample = new Method(METHOD_UPSERT_BY_EXAMPLE);
// 返回值类型
mUpsertByExample.setReturnType(null);
// 添加参数
mUpsertByExample.addParameter(new Parameter(introspectedTable.getRules().calculateAllFieldsClass(), "record", "@Param(\"record\")"));
mUpsertByExample.addParameter(new Parameter(new FullyQualifiedJavaType(introspectedTable.getExampleType()), "example", "@Param(\"example\")"));
// 添加方法说明
CommentTools.addGeneralMethodComment(mUpsertByExample, introspectedTable);
// interface 增加方法
interfaze.addMethod(mUpsertByExample);
logger.debug("itfsw(存在即更新插件):" + interfaze.getType().getShortName() + "增加upsertByExample方法。");
}
return true;
}
......@@ -128,7 +160,9 @@ public class UpsertPlugin extends PluginAdapter {
eleUpsert.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
eleUpsert.addElement(this.generateInsertClause(introspectedTable));
eleUpsert.addElement(new TextElement("values"));
eleUpsert.addElement(new TextElement("("));
eleUpsert.addElement(this.generateValuesClause(introspectedTable));
eleUpsert.addElement(new TextElement(")"));
eleUpsert.addElement(new TextElement("on duplicate key update "));
eleUpsert.addElement(this.generateDuplicateClause(introspectedTable));
......@@ -158,9 +192,71 @@ public class UpsertPlugin extends PluginAdapter {
document.getRootElement().addElement(eleUpsertSelective);
logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加upsertSelective实现方法。");
if (this.allowMultiQueries){
// ====================================== 2. upsertByExample ======================================
XmlElement eleUpsertByExample = new XmlElement("insert");
eleUpsertByExample.addAttribute(new Attribute("id", METHOD_UPSERT_BY_EXAMPLE));
// 参数类型
eleUpsertByExample.addAttribute(new Attribute("parameterType", "map"));
// 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated)
CommentTools.addComment(eleUpsertByExample);
// 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
CommTools.useGeneratedKeys(eleUpsertByExample, introspectedTable, "record.");
// insert
eleUpsertByExample.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
eleUpsertByExample.addElement(this.generateInsertClause(introspectedTable));
this.generateExistsClause(introspectedTable, eleUpsertByExample);
// multiQueries
eleUpsertByExample.addElement(new TextElement(";"));
// update
eleUpsertByExample.addElement(new TextElement("update " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()));
eleUpsertByExample.addElement(new TextElement("set"));
Iterator<IntrospectedColumn> iterator = ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()).iterator();
StringBuffer sb = new StringBuffer();
while (iterator.hasNext()){
IntrospectedColumn column = iterator.next();
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(column));
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(column, "record."));
if (iterator.hasNext()){
sb.append(",");
}
}
eleUpsertByExample.addElement(new TextElement(sb.toString()));
// update where
eleUpsertByExample.addElement(XmlElementGeneratorTools.getUpdateByExampleIncludeElement(introspectedTable));
document.getRootElement().addElement(eleUpsertByExample);
logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加upsertSelective实现方法。");
}
return true;
}
/**
* exists 语句
*
* @param introspectedTable
* @return
*/
private void generateExistsClause(IntrospectedTable introspectedTable, XmlElement element){
element.addElement(new TextElement("select"));
element.addElement(this.generateValuesClause(introspectedTable, "record."));
element.addElement(new TextElement("from dual where not exists"));
element.addElement(new TextElement("("));
element.addElement(new TextElement("select 1 from " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
// if example
element.addElement(XmlElementGeneratorTools.getUpdateByExampleIncludeElement(introspectedTable));
element.addElement(new TextElement(")"));
}
/**
* 普通insert
*
......@@ -195,22 +291,29 @@ public class UpsertPlugin extends PluginAdapter {
* @return
*/
private Element generateValuesClause(IntrospectedTable introspectedTable){
StringBuilder valuesClause = new StringBuilder();
return this.generateValuesClause(introspectedTable, null);
}
valuesClause.append(" (");
/**
* 普通 values
*
* @param introspectedTable
* @param prefix
* @return
*/
private Element generateValuesClause(IntrospectedTable introspectedTable, String prefix){
StringBuilder valuesClause = new StringBuilder();
List<IntrospectedColumn> columns = introspectedTable.getAllColumns();
for (int i = 0; i < columns.size(); i++) {
IntrospectedColumn introspectedColumn = columns.get(i);
valuesClause.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
valuesClause.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, prefix));
if (i + 1 < columns.size()) {
valuesClause.append(", ");
}
}
valuesClause.append(") ");
return new TextElement(valuesClause.toString());
}
......
......@@ -39,6 +39,17 @@ public class CommTools {
* @param introspectedTable
*/
public static void useGeneratedKeys(XmlElement element, IntrospectedTable introspectedTable){
useGeneratedKeys(element, introspectedTable, null);
}
/**
* 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
*
* @param element
* @param introspectedTable
* @param prefix
*/
public static void useGeneratedKeys(XmlElement element, IntrospectedTable introspectedTable, String prefix){
GeneratedKey gk = introspectedTable.getGeneratedKey();
if (gk != null) {
IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn());
......@@ -47,7 +58,7 @@ public class CommTools {
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("keyProperty", (prefix == null ? "" : prefix) + introspectedColumn.getJavaProperty())); //$NON-NLS-1$
element.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$
}
}
......
......@@ -40,17 +40,17 @@ public class CommentTools {
*/
public static void addFieldComment(Field field, IntrospectedTable introspectedTable) {
StringBuilder sb = new StringBuilder();
field.addJavaDocLine("/**"); //$NON-NLS-1$
field.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的属性(请勿删除)."); //$NON-NLS-1$
sb.append(" * This field corresponds to the database table "); //$NON-NLS-1$
field.addJavaDocLine("/**");
field.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的属性(请勿删除).");
sb.append(" * This field corresponds to the database table ");
sb.append(introspectedTable.getFullyQualifiedTable());
field.addJavaDocLine(sb.toString());
field.addJavaDocLine(" *");
field.addJavaDocLine(" * "+MergeConstants.NEW_ELEMENT_TAG);
field.addJavaDocLine(" * @author hewei");
field.addJavaDocLine(" * @project https://github.com/itfsw/mybatis-generator-plugin");
field.addJavaDocLine(" */"); //$NON-NLS-1$
field.addJavaDocLine(" */");
}
/**
......@@ -61,15 +61,16 @@ public class CommentTools {
*/
public static void addInnerClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
StringBuilder sb = new StringBuilder();
innerClass.addJavaDocLine("/**"); //$NON-NLS-1$
innerClass.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的类(请勿删除)."); //$NON-NLS-1$
sb.append(" * This class corresponds to the database table "); //$NON-NLS-1$
innerClass.addJavaDocLine("/**");
innerClass.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的类(请勿删除).");
sb.append(" * This class corresponds to the database table ");
sb.append(introspectedTable.getFullyQualifiedTable());
innerClass.addJavaDocLine(sb.toString());
innerClass.addJavaDocLine(" *");
innerClass.addJavaDocLine(" * "+MergeConstants.NEW_ELEMENT_TAG);
innerClass.addJavaDocLine(" * @author hewei");
innerClass.addJavaDocLine(" */"); //$NON-NLS-1$
innerClass.addJavaDocLine(" * @project https://github.com/itfsw/mybatis-generator-plugin");
innerClass.addJavaDocLine(" */");
}
/**
......@@ -80,15 +81,16 @@ public class CommentTools {
*/
public static void addInnerEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
StringBuilder sb = new StringBuilder();
innerEnum.addJavaDocLine("/**"); //$NON-NLS-1$
innerEnum.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的枚举(请勿删除)."); //$NON-NLS-1$
sb.append(" * This class corresponds to the database table "); //$NON-NLS-1$
innerEnum.addJavaDocLine("/**");
innerEnum.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的枚举(请勿删除).");
sb.append(" * This class corresponds to the database table ");
sb.append(introspectedTable.getFullyQualifiedTable());
innerEnum.addJavaDocLine(sb.toString());
innerEnum.addJavaDocLine(" *");
innerEnum.addJavaDocLine(" * "+MergeConstants.NEW_ELEMENT_TAG);
innerEnum.addJavaDocLine(" * @author hewei");
innerEnum.addJavaDocLine(" */"); //$NON-NLS-1$
innerEnum.addJavaDocLine(" * @project https://github.com/itfsw/mybatis-generator-plugin");
innerEnum.addJavaDocLine(" */");
}
/**
......@@ -99,15 +101,16 @@ public class CommentTools {
*/
public static void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
StringBuilder sb = new StringBuilder();
method.addJavaDocLine("/**"); //$NON-NLS-1$
method.addJavaDocLine("/**");
method.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的方法(请勿删除).");
sb.append(" * This method corresponds to the database table ");
sb.append(introspectedTable.getFullyQualifiedTable());
method.addJavaDocLine(sb.toString());
method.addJavaDocLine(" *");
method.addJavaDocLine(" * "+MergeConstants.NEW_ELEMENT_TAG);
method.addJavaDocLine(" * @author hewei");
method.addJavaDocLine(" */"); //$NON-NLS-1$
method.addJavaDocLine(" * @project https://github.com/itfsw/mybatis-generator-plugin");
method.addJavaDocLine(" */");
}
/**
......@@ -117,16 +120,16 @@ public class CommentTools {
*/
public static void addComment(XmlElement xmlElement) {
xmlElement.addElement(new TextElement("<!--")); //$NON-NLS-1$
xmlElement.addElement(new TextElement("<!--"));
StringBuilder sb = new StringBuilder();
sb.append(" WARNING - "); //$NON-NLS-1$
sb.append(" WARNING - ");
sb.append(MergeConstants.NEW_ELEMENT_TAG);
xmlElement.addElement(new TextElement(sb.toString()));
xmlElement.addElement(new TextElement(" 这个节点为代码生成工具生成,请不要修改!")); //$NON-NLS-1$
xmlElement.addElement(new TextElement(" @author hewei"));
xmlElement.addElement(new TextElement(" 这个节点为代码生成工具生成,请不要修改!"));
xmlElement.addElement(new TextElement(" @project https://github.com/itfsw/mybatis-generator-plugin"));
xmlElement.addElement(new TextElement("-->")); //$NON-NLS-1$
xmlElement.addElement(new TextElement("-->"));
}
/**
......@@ -137,15 +140,16 @@ public class CommentTools {
*/
public static void addInterfaceComment(Interface interf, IntrospectedTable introspectedTable) {
StringBuilder sb = new StringBuilder();
interf.addJavaDocLine("/**"); //$NON-NLS-1$
interf.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的接口(请勿删除)."); //$NON-NLS-1$
sb.append(" * This class corresponds to the database table "); //$NON-NLS-1$
interf.addJavaDocLine("/**");
interf.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的接口(请勿删除).");
sb.append(" * This class corresponds to the database table ");
sb.append(introspectedTable.getFullyQualifiedTable());
interf.addJavaDocLine(sb.toString());
interf.addJavaDocLine(" *");
interf.addJavaDocLine(" * "+MergeConstants.NEW_ELEMENT_TAG);
interf.addJavaDocLine(" * @author hewei");
interf.addJavaDocLine(" */"); //$NON-NLS-1$
interf.addJavaDocLine(" * @project https://github.com/itfsw/mybatis-generator-plugin");
interf.addJavaDocLine(" */");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment