diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/IncrementsPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/IncrementsPlugin.java index ffe93f3..6997c7a 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/IncrementsPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/IncrementsPlugin.java @@ -292,34 +292,46 @@ public class IncrementsPlugin extends BasePlugin implements IModelBuilderPluginH /** * 生成增量操作节点(SelectiveEnhancedPlugin) + * @param versionColumn 需要排除的column(主要是和乐观锁插件整合时要把版本列排除掉) * @return */ @Override - public Element incrementSetsWithSelectiveEnhancedPluginElementGenerated() { + public Element incrementSetsWithSelectiveEnhancedPluginElementGenerated(IntrospectedColumn versionColumn) { if (incTools.support()) { XmlElement choose = new XmlElement("choose"); for (IntrospectedColumn introspectedColumn : incTools.getColumns()) { - XmlElement when = new XmlElement("when"); + if (versionColumn == null || !introspectedColumn.getActualColumnName().equals(versionColumn.getActualColumnName())) { + XmlElement when = new XmlElement("when"); - // 需要 inc 的列 - StringBuilder sb = new StringBuilder(); - sb.append("'"); - sb.append(introspectedColumn.getActualColumnName()); - sb.append("'.toString()"); - sb.append(" == "); - sb.append("column.value"); + // 需要 inc 的列 + StringBuilder sb = new StringBuilder(); + sb.append("'"); + sb.append(introspectedColumn.getActualColumnName()); + sb.append("'.toString()"); + sb.append(" == "); + sb.append("column.value"); - when.addAttribute(new Attribute("test", sb.toString())); - when.addElement(new TextElement("${column.value} = ${column.value} ${record.incrementsColumnsInfoMap." - + introspectedColumn.getActualColumnName() - + ".value} #{record.${column.javaProperty},jdbcType=${column.jdbcType}}")); - choose.addElement(when); + when.addAttribute(new Attribute("test", sb.toString())); + when.addElement(new TextElement("${column.value} = ${column.value} ${record.incrementsColumnsInfoMap." + + introspectedColumn.getActualColumnName() + + ".value} #{record.${column.javaProperty},jdbcType=${column.jdbcType}}")); + choose.addElement(when); + } } - XmlElement otherwise = new XmlElement("otherwise"); - otherwise.addElement(new TextElement("${column.value} = #{record.${column.javaProperty},jdbcType=${column.jdbcType}}")); - choose.addElement(otherwise); + if (versionColumn == null) { + XmlElement otherwise = new XmlElement("otherwise"); + otherwise.addElement(new TextElement("${column.value} = #{record.${column.javaProperty},jdbcType=${column.jdbcType}}")); + choose.addElement(otherwise); + } else { + XmlElement when = new XmlElement("when"); + when.addAttribute(new Attribute("test", "column.value != '" + versionColumn.getActualColumnName() + "'.toString()")); + + when.addElement(new TextElement("${column.value} = #{record.${column.javaProperty},jdbcType=${column.jdbcType}}")); + + choose.addElement(when); + } return choose; } diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPlugin.java index 1cc03d4..31c9c1f 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPlugin.java @@ -16,10 +16,8 @@ package com.itfsw.mybatis.generator.plugins; -import com.itfsw.mybatis.generator.plugins.utils.BasePlugin; -import com.itfsw.mybatis.generator.plugins.utils.FormatTools; -import com.itfsw.mybatis.generator.plugins.utils.XmlElementGeneratorTools; -import com.itfsw.mybatis.generator.plugins.utils.XmlElementTools; +import com.itfsw.mybatis.generator.plugins.utils.*; +import com.itfsw.mybatis.generator.plugins.utils.hook.IOptimisticLockerPluginHook; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; @@ -98,10 +96,10 @@ public class OptimisticLockerPlugin extends BasePlugin { @Override public boolean clientUpdateByExampleSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) { if (this.versionColumn != null) { - FormatTools.addMethodWithBestPosition( - interfaze, - this.replaceUpdateExampleMethod(introspectedTable, method, interfaze, METHOD_UPDATE_WITH_VERSION_BY_EXAMPLE_SELECTIVE) - ); + Method withVersion = this.replaceUpdateExampleMethod(introspectedTable, method, interfaze, METHOD_UPDATE_WITH_VERSION_BY_EXAMPLE_SELECTIVE); + if (PluginTools.getHook(IOptimisticLockerPluginHook.class).clientUpdateWithVersionByExampleSelectiveMethodGenerated(withVersion, interfaze, introspectedTable)) { + FormatTools.addMethodWithBestPosition(interfaze, withVersion); + } } return super.clientUpdateByExampleSelectiveMethodGenerated(method, interfaze, introspectedTable); } @@ -131,10 +129,10 @@ public class OptimisticLockerPlugin extends BasePlugin { @Override public boolean clientUpdateByPrimaryKeySelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) { if (this.versionColumn != null) { - FormatTools.addMethodWithBestPosition( - interfaze, - this.replaceUpdatePrimaryKeyXmlMethod(introspectedTable, method, interfaze, METHOD_UPDATE_WITH_VERSION_BY_PRIMARY_KEY_SELECTIVE) - ); + Method withVersion = this.replaceUpdateExampleMethod(introspectedTable, method, interfaze, METHOD_UPDATE_WITH_VERSION_BY_PRIMARY_KEY_SELECTIVE); + if (PluginTools.getHook(IOptimisticLockerPluginHook.class).clientUpdateWithVersionByPrimaryKeySelectiveMethodGenerated(withVersion, interfaze, introspectedTable)) { + FormatTools.addMethodWithBestPosition(interfaze, withVersion); + } } return super.clientUpdateByPrimaryKeySelectiveMethodGenerated(method, interfaze, introspectedTable); } @@ -572,11 +570,18 @@ public class OptimisticLockerPlugin extends BasePlugin { updateEle.addElement(setEle); // set 节点 - XmlElement trimEle = XmlElementGeneratorTools.generateSetsSelective(columns, "record."); - setEle.addElement(trimEle); + XmlElement setsEle = XmlElementGeneratorTools.generateSetsSelective(columns, "record."); + setEle.addElement(setsEle); + + XmlElement needVersionEle; + if (PluginTools.getHook(IOptimisticLockerPluginHook.class).generateSetsSelectiveElement(columns, this.versionColumn, setsEle)) { + needVersionEle = setEle; + } else { + needVersionEle = setsEle; + } // 版本自增 - trimEle.addElement(0, new TextElement( + needVersionEle.addElement(0, new TextElement( MyBatis3FormattingUtilities.getEscapedColumnName(this.versionColumn) + " = " + MyBatis3FormattingUtilities.getEscapedColumnName(this.versionColumn) diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/SelectiveEnhancedPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/SelectiveEnhancedPlugin.java index 6c0c262..720646e 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/SelectiveEnhancedPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/SelectiveEnhancedPlugin.java @@ -18,6 +18,7 @@ package com.itfsw.mybatis.generator.plugins; import com.itfsw.mybatis.generator.plugins.utils.*; import com.itfsw.mybatis.generator.plugins.utils.hook.IIncrementsPluginHook; +import com.itfsw.mybatis.generator.plugins.utils.hook.IOptimisticLockerPluginHook; import com.itfsw.mybatis.generator.plugins.utils.hook.IUpsertPluginHook; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; @@ -42,7 +43,7 @@ import java.util.List; * @time:2018/4/20 15:39 * --------------------------------------------------------------------------- */ -public class SelectiveEnhancedPlugin extends BasePlugin implements IUpsertPluginHook { +public class SelectiveEnhancedPlugin extends BasePlugin implements IUpsertPluginHook, IOptimisticLockerPluginHook { /** * {@inheritDoc} @@ -349,6 +350,33 @@ public class SelectiveEnhancedPlugin extends BasePlugin implements IUpsertPlugin return true; } + // ================================================= IOptimisticLockerPluginHook =============================================== + + @Override + public boolean clientUpdateWithVersionByExampleSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) { + // column枚举,找出全字段对应的Model + FullyQualifiedJavaType fullFieldModel = introspectedTable.getRules().calculateAllFieldsClass(); + FullyQualifiedJavaType selectiveType = new FullyQualifiedJavaType(fullFieldModel.getShortName() + "." + ModelColumnPlugin.ENUM_NAME); + method.addParameter(new Parameter(selectiveType, "selective", "@Param(\"selective\")", true)); + return true; + } + + @Override + public boolean clientUpdateWithVersionByPrimaryKeySelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) { + // column枚举,找出全字段对应的Model + FullyQualifiedJavaType fullFieldModel = introspectedTable.getRules().calculateAllFieldsClass(); + FullyQualifiedJavaType selectiveType = new FullyQualifiedJavaType(fullFieldModel.getShortName() + "." + ModelColumnPlugin.ENUM_NAME); + method.addParameter(new Parameter(selectiveType, "selective", "@Param(\"selective\")", true)); + return true; + } + + @Override + public boolean generateSetsSelectiveElement(List columns, IntrospectedColumn versionColumn, XmlElement setsElement) { + // 替换update set + XmlElementTools.replaceXmlElement(setsElement, this.generateSetsSelective(columns, versionColumn)); + return true; + } + // ====================================================== 一些私有节点生成方法 ========================================================= /** @@ -431,6 +459,15 @@ public class SelectiveEnhancedPlugin extends BasePlugin implements IUpsertPlugin * @return */ private XmlElement generateSetsSelective(List columns) { + return generateSetsSelective(columns, null); + } + + /** + * sets selective + * @param columns + * @return + */ + private XmlElement generateSetsSelective(List columns, IntrospectedColumn versionColumn) { XmlElement setsChooseEle = new XmlElement("choose"); XmlElement setWhenEle = new XmlElement("when"); @@ -443,11 +480,18 @@ public class SelectiveEnhancedPlugin extends BasePlugin implements IUpsertPlugin setForeachEle.addAttribute(new Attribute("item", "column")); setForeachEle.addAttribute(new Attribute("separator", ",")); - Element incrementEle = PluginTools.getHook(IIncrementsPluginHook.class).incrementSetsWithSelectiveEnhancedPluginElementGenerated(); - if (incrementEle == null) { + Element incrementEle = PluginTools.getHook(IIncrementsPluginHook.class).incrementSetsWithSelectiveEnhancedPluginElementGenerated(versionColumn); + // 普通情况 + if (incrementEle == null && versionColumn == null) { setForeachEle.addElement(new TextElement("${column.value} = #{record.${column.javaProperty},jdbcType=${column.jdbcType}}")); - } else { + } else if (incrementEle != null) { setForeachEle.addElement(incrementEle); + } else if (versionColumn != null) { + XmlElement ifEle = new XmlElement("if"); + ifEle.addAttribute(new Attribute("test", "column.value != '" + versionColumn.getActualColumnName() + "'.toString()")); + ifEle.addElement(new TextElement("${column.value} = #{record.${column.javaProperty},jdbcType=${column.jdbcType}}")); + + setForeachEle.addElement(ifEle); } diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/HookAggregator.java b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/HookAggregator.java index eb3078c..60c7fc0 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/HookAggregator.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/HookAggregator.java @@ -42,7 +42,7 @@ import java.util.List; * @time:2018/4/27 11:33 * --------------------------------------------------------------------------- */ -public class HookAggregator implements IUpsertPluginHook, IModelBuilderPluginHook, IIncrementsPluginHook { +public class HookAggregator implements IUpsertPluginHook, IModelBuilderPluginHook, IIncrementsPluginHook, IOptimisticLockerPluginHook { protected static final Logger logger = LoggerFactory.getLogger(BasePlugin.class); // 日志 private final static HookAggregator instance = new HookAggregator(); private Context context; @@ -105,11 +105,11 @@ public class HookAggregator implements IUpsertPluginHook, IModelBuilderPluginHoo } @Override - public Element incrementSetsWithSelectiveEnhancedPluginElementGenerated() { - if (this.getPlugins(IIncrementsPluginHook.class).isEmpty()){ + public Element incrementSetsWithSelectiveEnhancedPluginElementGenerated(IntrospectedColumn versionColumn) { + if (this.getPlugins(IIncrementsPluginHook.class).isEmpty()) { return null; } else { - return this.getPlugins(IIncrementsPluginHook.class).get(0).incrementSetsWithSelectiveEnhancedPluginElementGenerated(); + return this.getPlugins(IIncrementsPluginHook.class).get(0).incrementSetsWithSelectiveEnhancedPluginElementGenerated(versionColumn); } } @@ -166,4 +166,35 @@ public class HookAggregator implements IUpsertPluginHook, IModelBuilderPluginHoo } return true; } + + // ================================================= IOptimisticLockerPluginHook =============================================== + + @Override + public boolean clientUpdateWithVersionByExampleSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) { + for (IOptimisticLockerPluginHook plugin : this.getPlugins(IOptimisticLockerPluginHook.class)) { + if (!plugin.clientUpdateWithVersionByExampleSelectiveMethodGenerated(method, interfaze, introspectedTable)) { + return false; + } + } + return true; + } + + @Override + public boolean clientUpdateWithVersionByPrimaryKeySelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) { + for (IOptimisticLockerPluginHook plugin : this.getPlugins(IOptimisticLockerPluginHook.class)) { + if (!plugin.clientUpdateWithVersionByPrimaryKeySelectiveMethodGenerated(method, interfaze, introspectedTable)) { + return false; + } + } + return true; + } + + @Override + public boolean generateSetsSelectiveElement(List columns, IntrospectedColumn versionColumn, XmlElement setsElement) { + if (this.getPlugins(IOptimisticLockerPluginHook.class).isEmpty()) { + return false; + } else { + return this.getPlugins(IOptimisticLockerPluginHook.class).get(0).generateSetsSelectiveElement(columns, versionColumn, setsElement); + } + } } diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/IIncrementsPluginHook.java b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/IIncrementsPluginHook.java index 377816e..893f954 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/IIncrementsPluginHook.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/IIncrementsPluginHook.java @@ -41,7 +41,8 @@ public interface IIncrementsPluginHook { /** * 生成增量操作节点(SelectiveEnhancedPlugin) + * @param versionColumn 需要排除的column(主要是和乐观锁插件整合时要把版本列排除掉) * @return */ - Element incrementSetsWithSelectiveEnhancedPluginElementGenerated(); + Element incrementSetsWithSelectiveEnhancedPluginElementGenerated(IntrospectedColumn versionColumn); } diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/IOptimisticLockerPluginHook.java b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/IOptimisticLockerPluginHook.java new file mode 100644 index 0000000..5228705 --- /dev/null +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/hook/IOptimisticLockerPluginHook.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018. + * + * 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.hook; + +import org.mybatis.generator.api.IntrospectedColumn; +import org.mybatis.generator.api.IntrospectedTable; +import org.mybatis.generator.api.dom.java.Interface; +import org.mybatis.generator.api.dom.java.Method; +import org.mybatis.generator.api.dom.xml.XmlElement; + +import java.util.List; + +/** + * --------------------------------------------------------------------------- + * + * --------------------------------------------------------------------------- + * @author: hewei + * @time:2018/5/4 18:08 + * --------------------------------------------------------------------------- + */ +public interface IOptimisticLockerPluginHook { + // ========================================= method 生成 ============================================ + + boolean clientUpdateWithVersionByExampleSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable); + + boolean clientUpdateWithVersionByPrimaryKeySelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable); + + // ========================================= sqlMap 生成 ============================================ + + boolean generateSetsSelectiveElement(List columns, IntrospectedColumn versionColumn, XmlElement setsElement); +} diff --git a/src/test/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPluginTest.java b/src/test/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPluginTest.java index 13ee900..351f101 100644 --- a/src/test/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPluginTest.java +++ b/src/test/java/com/itfsw/mybatis/generator/plugins/OptimisticLockerPluginTest.java @@ -766,4 +766,49 @@ public class OptimisticLockerPluginTest { } }); } + + /** + * 测试整合SelectiveEnhancedPlugin插件 + */ + @Test + public void testWithSelectiveEnhancedPlugin() throws Exception { + MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/OptimisticLockerPlugin/mybatis-generator-with-SelectiveEnhancedPlugin.xml"); + + // 测试updateWithVersionByExampleSelective + tool.generate(() -> DBHelper.createDB("scripts/OptimisticLockerPlugin/init.sql"), new AbstractShellCallback() { + @Override + public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) throws Exception { + ObjectUtil tbMapper = new ObjectUtil(sqlSession.getMapper(loader.loadClass(packagz + ".TbMapper"))); + + ObjectUtil tbExample = new ObjectUtil(loader, packagz + ".TbExample"); + ObjectUtil criteria = new ObjectUtil(tbExample.invoke("createCriteria")); + criteria.invoke("andIdEqualTo", 1l); + + ObjectUtil tbBuilder = new ObjectUtil(loader, packagz + ".Tb$Builder"); + ObjectUtil tbBuilderInc = new ObjectUtil(loader, packagz + ".Tb$Builder$Inc#INC"); + tbBuilder.invoke("id", 1L); + tbBuilder.invoke("incF1", 121l, tbBuilderInc.getObject()); // 这个不会在sql才为正常 + tbBuilder.invoke("incF2", 5l, tbBuilderInc.getObject()); + tbBuilder.invoke("incF3", 10l); + + // sql + String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "updateWithVersionByExampleSelective", 100L, tbBuilder.invoke("build"), tbExample.getObject()); + Assert.assertEquals(sql, "update tb SET inc_f1 = inc_f1 + 1, id = 1, inc_f2 = inc_f2 + 5 , inc_f3 = 10 WHERE inc_f1 = 100 and ( ( id = '1' ) )"); + + // 执行一次,因为版本号100不存在所以应该返回0 + Object result = tbMapper.invoke("updateWithVersionByExampleSelective", 100L, tbBuilder.invoke("build"), tbExample.getObject()); + Assert.assertEquals(result, 0); + + // id = 1 的版本号应该是0 + result = tbMapper.invoke("updateWithVersionByExampleSelective", 0L, tbBuilder.invoke("build"), tbExample.getObject()); + Assert.assertEquals(result, 1); + + // 执行完成后版本号应该加1 + ResultSet rs = DBHelper.execute(sqlSession.getConnection(), "select * from tb where id = 1"); + rs.first(); + Assert.assertEquals(rs.getInt("inc_f1"), 1); + Assert.assertEquals(rs.getInt("inc_f2"), 7); + } + }); + } } \ No newline at end of file diff --git a/src/test/resources/scripts/OptimisticLockerPlugin/mybatis-generator-with-SelectiveEnhancedPlugin.xml b/src/test/resources/scripts/OptimisticLockerPlugin/mybatis-generator-with-SelectiveEnhancedPlugin.xml new file mode 100644 index 0000000..a27316a --- /dev/null +++ b/src/test/resources/scripts/OptimisticLockerPlugin/mybatis-generator-with-SelectiveEnhancedPlugin.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+
\ No newline at end of file