Commit 706fad7e authored by hewei's avatar hewei

Bugfix:IncrementsPlugin插件自增参数配置字段取名不特殊,会和用户数据库表中字段存在冲突可能。同时补充该插件测试用例

parent e6f607d3
...@@ -40,6 +40,8 @@ import java.util.List; ...@@ -40,6 +40,8 @@ import java.util.List;
*/ */
public class IncrementsPlugin extends BasePlugin { public class IncrementsPlugin extends BasePlugin {
public static final String PRE_INCREMENTS_COLUMNS = "incrementsColumns"; // incrementsColumns property public static final String PRE_INCREMENTS_COLUMNS = "incrementsColumns"; // incrementsColumns property
public static final String FIELD_INC_MAP = "incrementsColumnsInfoMap"; // 为了防止和用户数据库字段冲突,特殊命名
public static final String METHOD_INC_CHECK = "hasIncsForColumn"; // inc 检查方法名称
private IncrementsPluginTools incTools; // 增量插件工具 private IncrementsPluginTools incTools; // 增量插件工具
/** /**
......
...@@ -154,7 +154,6 @@ public class ModelBuilderPlugin extends BasePlugin { ...@@ -154,7 +154,6 @@ public class ModelBuilderPlugin extends BasePlugin {
mInc.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "value")); mInc.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "value"));
commentGenerator.addGeneralMethodComment(mInc, introspectedTable); commentGenerator.addGeneralMethodComment(mInc, introspectedTable);
eIncrements.addMethod(mInc); eIncrements.addMethod(mInc);
logger.debug("itfsw(数据Model属性对应Column获取插件):" + topLevelClass.getType().getShortName() + ".Column增加构造方法和column属性。");
Method mValue = JavaElementGeneratorTools.generateGetterMethod(fValue); Method mValue = JavaElementGeneratorTools.generateGetterMethod(fValue);
commentGenerator.addGeneralMethodComment(mValue, introspectedTable); commentGenerator.addGeneralMethodComment(mValue, introspectedTable);
...@@ -163,7 +162,7 @@ public class ModelBuilderPlugin extends BasePlugin { ...@@ -163,7 +162,7 @@ public class ModelBuilderPlugin extends BasePlugin {
innerClass.addInnerEnum(eIncrements); innerClass.addInnerEnum(eIncrements);
// 增加field // 增加field
Field fIncrements = JavaElementGeneratorTools.generateField( Field fIncrements = JavaElementGeneratorTools.generateField(
"incs", IncrementsPlugin.FIELD_INC_MAP,
JavaVisibility.PROTECTED, JavaVisibility.PROTECTED,
new FullyQualifiedJavaType("Map<String, " + incTools.getIncEnum().getFullyQualifiedName() + ">"), new FullyQualifiedJavaType("Map<String, " + incTools.getIncEnum().getFullyQualifiedName() + ">"),
"new HashMap<String, " + incTools.getIncEnum().getFullyQualifiedName() + ">()" "new HashMap<String, " + incTools.getIncEnum().getFullyQualifiedName() + ">()"
...@@ -179,6 +178,16 @@ public class ModelBuilderPlugin extends BasePlugin { ...@@ -179,6 +178,16 @@ public class ModelBuilderPlugin extends BasePlugin {
Method mSetter = JavaElementGeneratorTools.generateSetterMethod(fIncrements); Method mSetter = JavaElementGeneratorTools.generateSetterMethod(fIncrements);
commentGenerator.addSetterComment(mSetter, introspectedTable, null); commentGenerator.addSetterComment(mSetter, introspectedTable, null);
topLevelClass.addMethod(mSetter); topLevelClass.addMethod(mSetter);
// 增加判断方法
Method mHasIncsForColumn = JavaElementGeneratorTools.generateMethod(
IncrementsPlugin.METHOD_INC_CHECK,
JavaVisibility.PUBLIC,
FullyQualifiedJavaType.getBooleanPrimitiveInstance(),
new Parameter(FullyQualifiedJavaType.getStringInstance(), "column")
);
commentGenerator.addGeneralMethodComment(mHasIncsForColumn, introspectedTable);
mHasIncsForColumn.addBodyLine("return " + IncrementsPlugin.FIELD_INC_MAP + ".get(column) != null;");
FormatTools.addMethodWithBestPosition(topLevelClass, mHasIncsForColumn);
} }
// Builder 中 添加字段支持 // Builder 中 添加字段支持
...@@ -196,7 +205,7 @@ public class ModelBuilderPlugin extends BasePlugin { ...@@ -196,7 +205,7 @@ public class ModelBuilderPlugin extends BasePlugin {
commentGenerator.addSetterComment(mIncrements, introspectedTable, column); commentGenerator.addSetterComment(mIncrements, introspectedTable, column);
Method setterMethod = JavaBeansUtil.getJavaBeansSetter(column, context, introspectedTable); Method setterMethod = JavaBeansUtil.getJavaBeansSetter(column, context, introspectedTable);
mIncrements.addBodyLine("obj.incs.put(\"" + column.getActualColumnName() + "\", inc);"); mIncrements.addBodyLine("obj." + IncrementsPlugin.FIELD_INC_MAP + ".put(\"" + column.getActualColumnName() + "\", inc);");
mIncrements.addBodyLine("obj." + setterMethod.getName() + "(" + field.getName() + ");"); mIncrements.addBodyLine("obj." + setterMethod.getName() + "(" + field.getName() + ");");
mIncrements.addBodyLine("return this;"); mIncrements.addBodyLine("return this;");
......
...@@ -19,6 +19,7 @@ package com.itfsw.mybatis.generator.plugins.utils; ...@@ -19,6 +19,7 @@ package com.itfsw.mybatis.generator.plugins.utils;
import org.mybatis.generator.api.dom.java.InnerClass; import org.mybatis.generator.api.dom.java.InnerClass;
import org.mybatis.generator.api.dom.java.Interface; import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method; import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute; import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Element; import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.api.dom.xml.XmlElement; import org.mybatis.generator.api.dom.xml.XmlElement;
...@@ -41,30 +42,7 @@ public class FormatTools { ...@@ -41,30 +42,7 @@ public class FormatTools {
* @param method * @param method
*/ */
public static void addMethodWithBestPosition(InnerClass innerClass, Method method){ public static void addMethodWithBestPosition(InnerClass innerClass, Method method){
List<Method> methods = innerClass.getMethods(); addMethodWithBestPosition(method, innerClass.getMethods());
int index = -1;
for (int i = 0; i < methods.size(); i++){
Method m = methods.get(i);
if (m.getName().equals(method.getName())){
if (m.getParameters().size() <= method.getParameters().size()){
index = i + 1;
} else {
index = i;
}
} else if (m.getName().startsWith(method.getName())){
if (index == - 1){
index = i;
}
} else if (method.getName().startsWith(m.getName())){
index = i + 1;
}
}
if (index == -1 || index >= methods.size()){
innerClass.addMethod(method);
} else {
methods.add(index, method);
}
} }
/** /**
...@@ -74,30 +52,17 @@ public class FormatTools { ...@@ -74,30 +52,17 @@ public class FormatTools {
* @param method * @param method
*/ */
public static void addMethodWithBestPosition(Interface interfacz, Method method){ public static void addMethodWithBestPosition(Interface interfacz, Method method){
List<Method> methods = interfacz.getMethods(); addMethodWithBestPosition(method, interfacz.getMethods());
int index = -1;
for (int i = 0; i < methods.size(); i++){
Method m = methods.get(i);
if (m.getName().equals(method.getName())){
if (m.getParameters().size() <= method.getParameters().size()){
index = i + 1;
} else {
index = i;
}
} else if (m.getName().startsWith(method.getName())){
if (index == - 1){
index = i;
}
} else if (method.getName().startsWith(m.getName())){
index = i + 1;
}
} }
if (index == -1 || index >= methods.size()){ /**
interfacz.addMethod(method); * 在最佳位置添加方法
} else { *
methods.add(index, method); * @param topLevelClass
} * @param method
*/
public static void addMethodWithBestPosition(TopLevelClass topLevelClass, Method method){
addMethodWithBestPosition(method, topLevelClass.getMethods());
} }
/** /**
...@@ -151,4 +116,36 @@ public class FormatTools { ...@@ -151,4 +116,36 @@ public class FormatTools {
} }
return null; return null;
} }
/**
* 获取最佳添加位置
*
* @param method
* @param methods
* @return
*/
private static void addMethodWithBestPosition(Method method, List<Method> methods){
int index = -1;
for (int i = 0; i < methods.size(); i++){
Method m = methods.get(i);
if (m.getName().equals(method.getName())){
if (m.getParameters().size() <= method.getParameters().size()){
index = i + 1;
} else {
index = i;
}
} else if (m.getName().startsWith(method.getName())){
if (index == - 1){
index = i;
}
} else if (method.getName().startsWith(m.getName())){
index = i + 1;
}
}
if (index == -1 || index >= methods.size()){
methods.add(methods.size(), method);
} else {
methods.add(index, method);
}
}
} }
...@@ -96,10 +96,9 @@ public class IncrementsPluginTools { ...@@ -96,10 +96,9 @@ public class IncrementsPluginTools {
/** /**
* 是否启用了 * 是否启用了
*
* @return * @return
*/ */
public boolean support(){ public boolean support() {
return this.columns.size() > 0; return this.columns.size() > 0;
} }
...@@ -114,13 +113,12 @@ public class IncrementsPluginTools { ...@@ -114,13 +113,12 @@ public class IncrementsPluginTools {
/** /**
* 判断是否为需要进行增量操作的column * 判断是否为需要进行增量操作的column
*
* @param searchColumn * @param searchColumn
* @return * @return
*/ */
public boolean supportColumn(IntrospectedColumn searchColumn){ public boolean supportColumn(IntrospectedColumn searchColumn) {
for (IntrospectedColumn column: this.columns){ for (IntrospectedColumn column : this.columns) {
if (column.getActualColumnName().equals(searchColumn.getActualColumnName())){ if (column.getActualColumnName().equals(searchColumn.getActualColumnName())) {
return true; return true;
} }
} }
...@@ -129,7 +127,6 @@ public class IncrementsPluginTools { ...@@ -129,7 +127,6 @@ public class IncrementsPluginTools {
/** /**
* 生成增量操作节点 * 生成增量操作节点
*
* @param introspectedColumn * @param introspectedColumn
* @param hasPrefix * @param hasPrefix
* @param hasComma * @param hasComma
...@@ -146,18 +143,23 @@ public class IncrementsPluginTools { ...@@ -146,18 +143,23 @@ public class IncrementsPluginTools {
// 没有启用增量操作 // 没有启用增量操作
XmlElement when = new XmlElement("when"); XmlElement when = new XmlElement("when");
when.addAttribute(new Attribute("test", (hasPrefix ? "record" : "_parameter") + ".incs.isEmpty()")); when.addAttribute(new Attribute(
TextElement normal = new TextElement(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, hasPrefix ? "record." : null)); "test",
when.addElement(normal); (hasPrefix ? "record." : "_parameter.") + IncrementsPlugin.METHOD_INC_CHECK
+ "('" + MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn) + "')"
));
TextElement spec = new TextElement(
MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn)
+ " ${" + (hasPrefix ? "record." : "")
+ IncrementsPlugin.FIELD_INC_MAP + "." + MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn) + ".value} "
+ MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, hasPrefix ? "record." : null));
when.addElement(spec);
choose.addElement(when); choose.addElement(when);
// 启用了增量操作 // 启用了增量操作
XmlElement otherwise = new XmlElement("otherwise"); XmlElement otherwise = new XmlElement("otherwise");
TextElement spec = new TextElement( TextElement normal = new TextElement(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, hasPrefix ? "record." : null));
MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn) otherwise.addElement(normal);
+ " ${" + (hasPrefix ? "record" : "_parameter") + ".incs." + MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn) + ".value} "
+ MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, hasPrefix ? "record." : null));
otherwise.addElement(spec);
choose.addElement(otherwise); choose.addElement(otherwise);
list.add(choose); list.add(choose);
......
...@@ -210,7 +210,7 @@ public class BatchInsertPluginTest { ...@@ -210,7 +210,7 @@ public class BatchInsertPluginTest {
String sql = SqlHelper.getFormatMapperSql(tbBlobsMapper.getObject(), "batchInsertSelective", params, columns); String sql = SqlHelper.getFormatMapperSql(tbBlobsMapper.getObject(), "batchInsertSelective", params, columns);
Assert.assertEquals(sql, "insert into tb_blobs ( field2 ) values ( 'null' ) , ( 'test123' )"); Assert.assertEquals(sql, "insert into tb_blobs ( field2 ) values ( 'null' ) , ( 'test123' )");
// 2. 执行sql // 2. 执行sql
Object count = tbBlobsMapper.invokeVarArgs("batchInsertSelective", params, columns); Object count = tbBlobsMapper.invoke("batchInsertSelective", params, columns);
Assert.assertEquals(count, 2); Assert.assertEquals(count, 2);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
......
/*
* 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.tools.*;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
/**
* ---------------------------------------------------------------------------
*
* ---------------------------------------------------------------------------
* @author: hewei
* @time:2017/7/5 15:32
* ---------------------------------------------------------------------------
*/
public class IncrementsPluginTest {
/**
* 初始化数据库
*/
@BeforeClass
public static void init() throws Exception {
DBHelper.createDB("scripts/IncrementsPlugin/init.sql");
}
/**
* 测试没有配置ModelBuilderPlugin
*/
@Test
public void testWarningsWithoutModelBuilderPlugin() throws Exception {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/IncrementsPlugin/mybatis-generator-without-model-builder-plugin.xml");
tool.generate();
Assert.assertEquals(tool.getWarnings().get(0), "itfsw:插件com.itfsw.mybatis.generator.plugins.IncrementsPlugin插件需配合com.itfsw.mybatis.generator.plugins.ModelBuilderPlugin插件使用!");
}
/**
* 测试ModelBuilder是否按配置正常生成了对应方法
*/
@Test
public void testModelBuilderMethod() throws Exception {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/IncrementsPlugin/mybatis-generator.xml");
tool.generate(new AbstractShellCallback() {
@Override
public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) {
try {
// 1. 测试生成的方法
ObjectUtil tbBuilder = new ObjectUtil(loader, packagz + ".Tb$Builder");
List<Method> methods = tbBuilder.getMethods("incF1");
Assert.assertEquals(methods.size(), 2);
// 自增方法
Method incMethod = methods.get(0).getParameterTypes().length == 1 ? methods.get(1) : methods.get(0);
Assert.assertEquals(incMethod.getParameters()[1].getParameterizedType().getTypeName(), packagz + ".Tb$Builder$Inc");
// 2. 测试有空格
ObjectUtil tbKeysBuilder = new ObjectUtil(loader, packagz + ".TbKeys$Builder");
Assert.assertEquals(tbKeysBuilder.getMethods("incF1").size(), 2);
Assert.assertEquals(tbKeysBuilder.getMethods("incF2").size(), 2);
Assert.assertEquals(tbKeysBuilder.getMethods("incF3").size(), 2);
// 3. 测试在WithBlobs正确生成
ObjectUtil tbBlobsWithBLOBs = new ObjectUtil(loader, packagz + ".TbBlobsWithBLOBs$Builder");
Assert.assertEquals(tbBlobsWithBLOBs.getMethods("incF1").size(), 2);
Assert.assertEquals(tbBlobsWithBLOBs.getMethods("incF2").size(), 1);
Assert.assertEquals(tbBlobsWithBLOBs.getMethods("incF3").size(), 2);
} catch (Exception e) {
e.printStackTrace();
Assert.assertTrue(false);
}
}
});
}
/**
* 测试生成的sql和具体执行
*/
@Test
public void testSqlAndExecute() throws Exception {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/IncrementsPlugin/mybatis-generator.xml");
tool.generate(new AbstractShellCallback() {
@Override
public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) {
try {
// 1. 测试updateByExample、updateByExampleSelective
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", 3l);
ObjectUtil tbBuilder = new ObjectUtil(loader, packagz + ".Tb$Builder");
ObjectUtil tbBuilderInc = new ObjectUtil(loader, packagz + ".Tb$Builder$Inc#INC");
tbBuilder.invoke("incF1", 100l, tbBuilderInc.getObject());
// sql
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "updateByExample", tbBuilder.invoke("build"), tbExample.getObject());
Assert.assertEquals(sql, "update tb set id = null, field1 = 'null', inc_f1 = inc_f1 + 100 , inc_f2 = null, inc_f3 = null WHERE ( id = '3' )");
sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "updateByExampleSelective", tbBuilder.invoke("build"), tbExample.getObject());
Assert.assertEquals(sql, "update tb SET inc_f1 = inc_f1 + 100 WHERE ( id = '3' )");
// 执行
// inc_f1 增加100
Object result = tbMapper.invoke("updateByExampleSelective", tbBuilder.invoke("build"), tbExample.getObject());
Assert.assertEquals(result, 1);
PreparedStatement preparedStatement = sqlSession.getConnection().prepareStatement("select inc_f1 from tb where id = 3");
preparedStatement.execute();
ResultSet rs = preparedStatement.getResultSet();
rs.first();
Assert.assertEquals(rs.getInt("inc_f1"), 103);
// inc_f1 再减去50
ObjectUtil tbBuilderDec = new ObjectUtil(loader, packagz + ".Tb$Builder$Inc#DEC");
tbBuilder.invoke("incF1", 50l, tbBuilderDec.getObject());
result = tbMapper.invoke("updateByExampleSelective", tbBuilder.invoke("build"), tbExample.getObject());
Assert.assertEquals(result, 1);
// 验证执行结果
preparedStatement = sqlSession.getConnection().prepareStatement("select inc_f1 from tb where id = 3");
preparedStatement.execute();
rs = preparedStatement.getResultSet();
rs.first();
Assert.assertEquals(rs.getInt("inc_f1"), 53);
// 2. 测试updateByPrimaryKey、updateByPrimaryKeySelective
ObjectUtil tbKeysMapper = new ObjectUtil(sqlSession.getMapper(loader.loadClass(packagz + ".TbKeysMapper")));
ObjectUtil tbKeysBuilderInc = new ObjectUtil(loader, packagz + ".TbKeys$Builder$Inc#INC");
ObjectUtil tbKeysBuilder = new ObjectUtil(loader, packagz + ".TbKeys$Builder");
tbKeysBuilder.invoke("key1", 1l);
tbKeysBuilder.invoke("key2", "k1");
tbKeysBuilder.invoke("incF1", 10l, tbKeysBuilderInc.getObject());
tbKeysBuilder.invoke("incF3", 30l, tbKeysBuilderInc.getObject());
// sql
sql = SqlHelper.getFormatMapperSql(tbKeysMapper.getObject(), "updateByPrimaryKey", tbKeysBuilder.invoke("build"));
Assert.assertEquals(sql, "update tb_keys set field1 = 'null', field2 = null, inc_f1 = inc_f1 + 10 , inc_f2 = null , inc_f3 = inc_f3 + 30 where key1 = 1 and key2 = 'k1'");
sql = SqlHelper.getFormatMapperSql(tbKeysMapper.getObject(), "updateByPrimaryKeySelective", tbKeysBuilder.invoke("build"));
Assert.assertEquals(sql, "update tb_keys SET inc_f1 = inc_f1 + 10 , inc_f3 = inc_f3 + 30 where key1 = 1 and key2 = 'k1'");
// 执行
result = tbKeysMapper.invoke("updateByPrimaryKeySelective", tbKeysBuilder.invoke("build"));
Assert.assertEquals(result, 1);
// 验证执行结果
preparedStatement = sqlSession.getConnection().prepareStatement("select inc_f1, inc_f3 from tb_keys where key1 = 1 and key2 = 'k1'");
preparedStatement.execute();
rs = preparedStatement.getResultSet();
rs.first();
Assert.assertEquals(rs.getInt("inc_f1"), 11);
Assert.assertEquals(rs.getInt("inc_f3"), 33);
// 3. 测试updateByExampleWithBLOBs、updateByPrimaryKeyWithBLOBs
ObjectUtil tbBlobsMapper = new ObjectUtil(sqlSession.getMapper(loader.loadClass(packagz + ".TbBlobsMapper")));
ObjectUtil tbBlobsExample = new ObjectUtil(loader, packagz + ".TbBlobsExample");
ObjectUtil tbBlobsExampleCriteria = new ObjectUtil(tbBlobsExample.invoke("createCriteria"));
tbBlobsExampleCriteria.invoke("andIdEqualTo", 3l);
ObjectUtil tbBlobsWithBLOBsBuilder = new ObjectUtil(loader, packagz + ".TbBlobsWithBLOBs$Builder");
ObjectUtil tbBlobsBuilderInc = new ObjectUtil(loader, packagz + ".TbBlobs$Builder$Inc#INC");
tbBlobsWithBLOBsBuilder.invoke("incF1", 100l, tbBlobsBuilderInc.getObject());
tbBlobsWithBLOBsBuilder.invoke("incF2", 50l);
tbBlobsWithBLOBsBuilder.invoke("field3", "blob");
// sql
sql = SqlHelper.getFormatMapperSql(tbBlobsMapper.getObject(), "updateByExampleWithBLOBs", tbBlobsWithBLOBsBuilder.invoke("build"), tbBlobsExample.getObject());
Assert.assertEquals(sql, "update tb_blobs set id = null, field1 = 'null', inc_f1 = inc_f1 + 100 , inc_f2 = 50, inc_f3 = null , field2 = 'null', field3 = 'blob' WHERE ( id = '3' )");
tbBlobsWithBLOBsBuilder.invoke("id", 3l);
sql = SqlHelper.getFormatMapperSql(tbBlobsMapper.getObject(), "updateByPrimaryKeyWithBLOBs", tbBlobsWithBLOBsBuilder.invoke("build"));
Assert.assertEquals(sql, "update tb_blobs set field1 = 'null', inc_f1 = inc_f1 + 100 , inc_f2 = 50, inc_f3 = null , field2 = 'null', field3 = 'blob' where id = 3");
// 执行
tbBlobsWithBLOBsBuilder.invoke("incF3", 10l);
// 测试自增字段没有配置自增参数
sql = SqlHelper.getFormatMapperSql(tbBlobsMapper.getObject(), "updateByPrimaryKeyWithBLOBs", tbBlobsWithBLOBsBuilder.invoke("build"));
Assert.assertEquals(sql, "update tb_blobs set field1 = 'null', inc_f1 = inc_f1 + 100 , inc_f2 = 50, inc_f3 = 10 , field2 = 'null', field3 = 'blob' where id = 3");
result = tbBlobsMapper.invoke("updateByPrimaryKeyWithBLOBs", tbBlobsWithBLOBsBuilder.invoke("build"));
Assert.assertEquals(result, 1);
} catch (Exception e) {
e.printStackTrace();
Assert.assertTrue(false);
}
}
});
}
}
...@@ -79,7 +79,7 @@ public class SelectSelectivePluginTest { ...@@ -79,7 +79,7 @@ public class SelectSelectivePluginTest {
// 2. 执行sql // 2. 执行sql
List list = (List) tbMapper.invokeVarArgs("selectByExampleSelective", tbExample.getObject(), columns1); List list = (List) tbMapper.invoke("selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(list.size(), 3); Assert.assertEquals(list.size(), 3);
int index = 0; int index = 0;
for (Object obj : list) { for (Object obj : list) {
...@@ -143,7 +143,7 @@ public class SelectSelectivePluginTest { ...@@ -143,7 +143,7 @@ public class SelectSelectivePluginTest {
Assert.assertEquals(sql, "select field2 from tb_keys where key1 = 1 and key2 = '2'"); Assert.assertEquals(sql, "select field2 from tb_keys where key1 = 1 and key2 = '2'");
// 3. 执行sql // 3. 执行sql
Object tbKeys = tbKeysMapper.invokeVarArgs("selectByPrimaryKeySelective", tbKeysKey.getObject(), columns1); Object tbKeys = tbKeysMapper.invoke("selectByPrimaryKeySelective", tbKeysKey.getObject(), columns1);
Assert.assertEquals(new ObjectUtil(tbKeys).get("field1"), "fd1"); Assert.assertEquals(new ObjectUtil(tbKeys).get("field1"), "fd1");
} catch (Exception e) { } catch (Exception e) {
...@@ -195,7 +195,7 @@ public class SelectSelectivePluginTest { ...@@ -195,7 +195,7 @@ public class SelectSelectivePluginTest {
Assert.assertEquals(sql, "select field1 from tb WHERE ( id = '3' ) order by field2 asc limit 1"); Assert.assertEquals(sql, "select field1 from tb WHERE ( id = '3' ) order by field2 asc limit 1");
// 2. 执行sql // 2. 执行sql
Object result = tbMapper.invokeVarArgs("selectOneByExampleSelective", tbExample.getObject(), columns1); Object result = tbMapper.invoke("selectOneByExampleSelective", tbExample.getObject(), columns1);
ObjectUtil tb = new ObjectUtil(result); ObjectUtil tb = new ObjectUtil(result);
Assert.assertEquals(tb.get("field1"), "fd3"); Assert.assertEquals(tb.get("field1"), "fd3");
Assert.assertNull(tb.get("field2")); Assert.assertNull(tb.get("field2"));
......
...@@ -16,9 +16,12 @@ ...@@ -16,9 +16,12 @@
package com.itfsw.mybatis.generator.plugins.tools; package com.itfsw.mybatis.generator.plugins.tools;
import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/** /**
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
...@@ -107,7 +110,7 @@ public class ObjectUtil { ...@@ -107,7 +110,7 @@ public class ObjectUtil {
} }
/** /**
* 执行方法 * 执行方法(mapper动态代理后VarArgs检查有问题)
* @param methodName * @param methodName
* @param args * @param args
* @return * @return
...@@ -116,12 +119,15 @@ public class ObjectUtil { ...@@ -116,12 +119,15 @@ public class ObjectUtil {
* @throws IllegalAccessException * @throws IllegalAccessException
*/ */
public Object invoke(String methodName, Object... args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { public Object invoke(String methodName, Object... args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method[] methods = this.cls.getDeclaredMethods(); List<Method> methods = getMethods(methodName);
for (Method method : methods) { for (Method method : methods) {
if (method.getName().equals(methodName) && method.getParameterTypes().length == args.length) { if (method.getParameterTypes().length == args.length) {
boolean flag = true; boolean flag = true;
Class[] parameterTypes = method.getParameterTypes(); Class[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < args.length; i++) { // !! mapper动态代理后VarArgs检查有问题
// 暂时只检查前几位相同就假设为可变参数
int check = args.length > 0 ? (args[args.length - 1] instanceof Array ? args.length - 1 : args.length) : 0;
for (int i = 0; i < check; i++) {
if (!(parameterTypes[i].isAssignableFrom(args[i].getClass()))) { if (!(parameterTypes[i].isAssignableFrom(args[i].getClass()))) {
flag = false; flag = false;
} }
...@@ -132,26 +138,26 @@ public class ObjectUtil { ...@@ -132,26 +138,26 @@ public class ObjectUtil {
} }
} }
} }
return null; throw new NoSuchMethodError("没有找到方法:" + methodName);
} }
/** /**
* 执行方法(mapper动态代理后VarArgs检查有问题) * 获取指定名称的方法
* @param methodName *
* @param args * @param name
* @return * @return
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/ */
public Object invokeVarArgs(String methodName, Object... args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { public List<Method> getMethods(String name){
Method[] methods = this.cls.getDeclaredMethods(); List<Method> list = new ArrayList<>();
for (Method method : methods) { Class clazz = this.cls;
if (method.getName().equals(methodName)) { for (; clazz != Object.class; clazz = clazz.getSuperclass()){
return method.invoke(this.object, args); for (Method method : clazz.getDeclaredMethods()){
if (method.getName().equals(name)){
list.add(method);
} }
} }
return null; }
return list;
} }
/** /**
......
...@@ -127,13 +127,11 @@ public class SqlHelper { ...@@ -127,13 +127,11 @@ public class SqlHelper {
} }
} }
if (args != null && args.length == 1) { if (args != null && args.length == 1) {
Object _params = wrapCollection(args[0]); return getNamespaceSql(session, fullMapperMethodName, args[0]);
if (_params instanceof Map) { } else {
params.putAll((Map) _params);
}
}
return getNamespaceSql(session, fullMapperMethodName, params); return getNamespaceSql(session, fullMapperMethodName, params);
} }
}
/** /**
......
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50617
Source Host : localhost:3306
Source Database : mybatis-generator-plugin
Target Server Type : MYSQL
Target Server Version : 50617
File Encoding : 65001
Date: 2017-07-05 17:21:41
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for tb
-- ----------------------------
DROP TABLE IF EXISTS `tb`;
CREATE TABLE `tb` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1',
`field1` varchar(255) DEFAULT NULL COMMENT '注释2',
`inc_f1` bigint(20) NOT NULL DEFAULT '0',
`inc_f2` bigint(20) NOT NULL DEFAULT '0',
`inc_f3` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb
-- ----------------------------
INSERT INTO `tb` VALUES ('1', 'fd1', '0', '0', '0');
INSERT INTO `tb` VALUES ('2', 'fd2', '1', '2', '3');
INSERT INTO `tb` VALUES ('3', null, '3', '2', '1');
INSERT INTO `tb` VALUES ('4', 'fd3', '1', '1', '1');
-- ----------------------------
-- Table structure for tb_blobs
-- ----------------------------
DROP TABLE IF EXISTS `tb_blobs`;
CREATE TABLE `tb_blobs` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1',
`field1` varchar(255) DEFAULT NULL,
`field2` longtext COMMENT '注释2',
`field3` longtext,
`inc_f1` bigint(20) NOT NULL DEFAULT '0',
`inc_f2` bigint(20) NOT NULL DEFAULT '0',
`inc_f3` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_blobs
-- ----------------------------
INSERT INTO `tb_blobs` VALUES ('1', 'fd1', null, null, '1', '2', '3');
INSERT INTO `tb_blobs` VALUES ('2', null, 'fd2', null, '3', '2', '1');
INSERT INTO `tb_blobs` VALUES ('3', null, null, 'fd3', '1', '1', '1');
INSERT INTO `tb_blobs` VALUES ('4', 'fd4', 'fd5', 'fd6', '0', '0', '0');
-- ----------------------------
-- Table structure for tb_keys
-- ----------------------------
DROP TABLE IF EXISTS `tb_keys`;
CREATE TABLE `tb_keys` (
`key1` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1',
`key2` varchar(255) NOT NULL,
`field1` varchar(255) DEFAULT NULL COMMENT '注释2',
`field2` int(11) DEFAULT NULL,
`inc_f1` bigint(20) NOT NULL DEFAULT '0',
`inc_f2` bigint(20) NOT NULL DEFAULT '0',
`inc_f3` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`key1`,`key2`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_keys
-- ----------------------------
INSERT INTO `tb_keys` VALUES ('1', 'k1', 'fd1', null, '1', '2', '3');
INSERT INTO `tb_keys` VALUES ('2', 'k2', null, '2', '3', '2', '1');
INSERT INTO `tb_keys` VALUES ('3', 'k3', null, null, '1', '1', '1');
-- ----------------------------
-- Table structure for tb_single_blob
-- ----------------------------
DROP TABLE IF EXISTS `tb_single_blob`;
CREATE TABLE `tb_single_blob` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1',
`field1` longtext COMMENT '注释2',
`field2` int(11) DEFAULT NULL,
`inc_f1` bigint(20) NOT NULL DEFAULT '0',
`inc_f2` bigint(20) NOT NULL DEFAULT '0',
`inc_f3` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_single_blob
-- ----------------------------
INSERT INTO `tb_single_blob` VALUES ('1', 'fd1', '0', '1', '2', '3');
INSERT INTO `tb_single_blob` VALUES ('2', null, null, '3', '2', '1');
INSERT INTO `tb_single_blob` VALUES ('3', null, null, '1', '1', '1');
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="db.properties"/>
<!--导入属性配置 -->
<context id="default" targetRuntime="MyBatis3">
<!-- 插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.IncrementsPlugin" />
<!--jdbc的数据库连接 -->
<jdbcConnection driverClass="${driver}" connectionURL="${url}" userId="${username}" password="${password}" />
<!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径 -->
<javaModelGenerator targetPackage="" targetProject="">
<!-- 是否对model添加 构造函数 -->
<property name="constructorBased" value="true"/>
<!-- 给Model添加一个父类 -->
<!--<property name="rootClass" value="com.itfsw.base"/>-->
</javaModelGenerator>
<!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
<sqlMapGenerator targetPackage="" targetProject="" />
<!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
<javaClientGenerator targetPackage="" targetProject="" type="XMLMAPPER"/>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 要自动生成的表 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<table tableName="tb">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
</context>
</generatorConfiguration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="db.properties"/>
<!--导入属性配置 -->
<context id="default" targetRuntime="MyBatis3">
<!-- 插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.IncrementsPlugin" />
<plugin type="com.itfsw.mybatis.generator.plugins.ModelBuilderPlugin" />
<!--jdbc的数据库连接 -->
<jdbcConnection driverClass="${driver}" connectionURL="${url}" userId="${username}" password="${password}" />
<!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径 -->
<javaModelGenerator targetPackage="" targetProject="">
<!-- 是否对model添加 构造函数 -->
<property name="constructorBased" value="true"/>
<!-- 给Model添加一个父类 -->
<!--<property name="rootClass" value="com.itfsw.base"/>-->
</javaModelGenerator>
<!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
<sqlMapGenerator targetPackage="" targetProject="" />
<!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
<javaClientGenerator targetPackage="" targetProject="" type="XMLMAPPER"/>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 要自动生成的表 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<table tableName="tb">
<property name="incrementsColumns" value="inc_f1"/>
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
<table tableName="tb_keys">
<property name="incrementsColumns" value=" inc_f1, inc_f2, inc_f3 "/>
</table>
<table tableName="tb_blobs">
<property name="incrementsColumns" value="inc_f1,inc_f3"/>
</table>
</context>
</generatorConfiguration>
\ No newline at end of file
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