Compare commits

...
12 Commits
10 changed files with 208 additions and 43 deletions
+19 -1
View File
@@ -30,7 +30,7 @@ Maven引用:
<dependency>
<groupId>com.itfsw</groupId>
<artifactId>mybatis-generator-plugin</artifactId>
<version>1.2.1</version>
<version>1.2.3</version>
</dependency>
```
---------------------------------------
@@ -346,6 +346,8 @@ public class Test {
this.tbMapper.batchInsert(list);
// !!!下面按需插入指定列(类似于insertSelective),需要数据Model属性对应Column获取插件(ModelColumnPlugin)插件
this.tbMapper.batchInsertSelective(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);
// 或者排除某些列
this.tbMapper.batchInsertSelective(list, Tb.Column.excludes(Tb.Column.id, Tb.Column.delFlag));
}
}
```
@@ -427,6 +429,7 @@ public class Test {
项目中我们有时需要获取数据Model对应数据库字段的名称,一般直接根据数据Model的属性就可以猜出数据库对应column的名字,可是有的时候当column使用了columnOverride或者columnRenamingRule时就需要去看数据库设计了,所以提供了这个插件获取model对应的数据库Column。
* 配合Example Criteria 增强插件(ExampleEnhancedPlugin)使用,这个插件还提供了asc()和desc()方法配合Example的orderBy方法效果更佳。
* 配合批量插入插件(BatchInsertPlugin)使用,batchInsertSelective(@Param("list") List<XXX> list, @Param("selective") XXX.Column ... insertColumns)。
* 提供静态excludes方法来进行快速反选。
插件:
```xml
@@ -481,6 +484,9 @@ public class Test {
this.tbMapper.batchInsert(list);
// 下面按需插入指定列(类似于insertSelective)
this.tbMapper.batchInsertSelective(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime);
// 4. excludes 方法
this.tbMapper.batchInsertSelective(list, Tb.Column.excludes(Tb.Column.id, Tb.Column.delFlag));
}
}
```
@@ -607,6 +613,9 @@ public class Test {
.build(),
Tb.Column.field1
);
// 3. 排除某些列
this.tbMapper.insertSelective(tb, Tb.Column.excludes(Tb.Column.id, Tb.Column.delFlag));
}
}
```
@@ -1075,6 +1084,15 @@ public class Test {
Tb.Column.field2
);
// 同理还有 selectByPrimaryKeySelective,selectOneByExampleSelective(SelectOneByExamplePlugin插件配合使用)方法
// 当然可以使用excludes
this.tbMapper.selectByExampleSelective(
new TbExample()
.createCriteria()
.andField1GreaterThan(1)
.example(),
Tb.Column.excludes(Tb.Column.id, Tb.Column.delFlag)
);
}
}
```
+7 -2
View File
@@ -3,7 +3,7 @@
<groupId>com.itfsw</groupId>
<artifactId>mybatis-generator-plugin</artifactId>
<version>1.2.2</version>
<version>1.2.4</version>
<packaging>jar</packaging>
<name>${project.groupId}:${project.artifactId}</name>
@@ -85,6 +85,11 @@
<version>2.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
</dependencies>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++profiles++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -212,7 +217,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.2.2</tag>
<tag>V1.2.4</tag>
</scm>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++distribution++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -461,12 +461,6 @@ public class LogicalDeletePlugin extends BasePlugin {
} else {
logicalDeleteValue = this.logicalDeleteValue;
}
// TODO 过期
Field field = JavaElementGeneratorTools.generateStaticFinalField("DEL_FLAG_OFF", this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalDeleteValue);
field.addAnnotation("@Deprecated");
commentGenerator.addFieldComment(field, introspectedTable);
// 常量插入到第一位
fields.add(0, field);
Field logicalDeleteConstField = JavaElementGeneratorTools.generateStaticFinalField(this.logicalDeleteConstName, this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalDeleteValue);
commentGenerator.addFieldComment(logicalDeleteConstField, introspectedTable);
@@ -485,13 +479,6 @@ public class LogicalDeletePlugin extends BasePlugin {
logicalUnDeleteValue = this.logicalUnDeleteValue;
}
// TODO 过期
Field field1 = JavaElementGeneratorTools.generateStaticFinalField("DEL_FLAG_ON", this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalUnDeleteValue);
field1.addAnnotation("@Deprecated");
commentGenerator.addFieldComment(field1, introspectedTable);
// 常量插入到第一位
fields.add(0, field1);
Field logicalUnDeleteConstField = JavaElementGeneratorTools.generateStaticFinalField(this.logicalUnDeleteConstName, this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalUnDeleteValue);
commentGenerator.addFieldComment(logicalUnDeleteConstField, introspectedTable);
fields.add(0, logicalUnDeleteConstField);
@@ -565,13 +552,6 @@ public class LogicalDeletePlugin extends BasePlugin {
method.addBodyLine(sb.toString());
FormatTools.addMethodWithBestPosition(innerClass, method);
// TODO 过期方法
Method mAndDeleted = new Method(method);
mAndDeleted.setName("andDeleted");
mAndDeleted.addAnnotation("@Deprecated");
FormatTools.addMethodWithBestPosition(innerClass, mAndDeleted);
logger.debug("itfsw(逻辑删除插件):" + topLevelClass.getType().getShortName() + "." + innerClass.getType().getShortName() + "增加andDeleted方法。");
}
}
}
@@ -34,6 +34,7 @@ import org.mybatis.generator.internal.util.JavaBeansUtil;
*/
public class ModelColumnPlugin extends BasePlugin {
public static final String ENUM_NAME = "Column"; // 内部Enum名
public static final String METHOD_EXCLUDES = "excludes"; // 方法名
/**
* Model Methods 生成
@@ -174,6 +175,28 @@ public class ModelColumnPlugin extends BasePlugin {
FormatTools.addMethodWithBestPosition(innerEnum, asc);
logger.debug("itfsw(数据Model属性对应Column获取插件):" + topLevelClass.getType().getShortName() + ".Column增加asc()和desc()方法。");
// excludes
topLevelClass.addImportedType("java.util.Arrays");
topLevelClass.addImportedType(FullyQualifiedJavaType.getNewArrayListInstance());
Method mExcludes = JavaElementGeneratorTools.generateMethod(
METHOD_EXCLUDES,
JavaVisibility.PUBLIC,
new FullyQualifiedJavaType(ENUM_NAME + "[]"),
new Parameter(innerEnum.getType(), "excludes", true)
);
commentGenerator.addGeneralMethodComment(mExcludes, introspectedTable);
mExcludes.setStatic(true);
JavaElementGeneratorTools.generateMethodBody(
mExcludes,
"ArrayList<Column> columns = new ArrayList<>(Arrays.asList(Column.values()));",
"if (excludes != null && excludes.length > 0) {",
"columns.removeAll(new ArrayList<>(Arrays.asList(excludes)));",
"}",
"return columns.toArray(new Column[]{});"
);
FormatTools.addMethodWithBestPosition(innerEnum, mExcludes);
logger.debug("itfsw(数据Model属性对应Column获取插件):" + topLevelClass.getType().getShortName() + ".Column增加excludes方法。");
return innerEnum;
}
}
@@ -41,6 +41,14 @@ public class SelectOneByExamplePlugin extends BasePlugin {
private XmlElement selectOneByExampleEle;
private XmlElement selectOneByExampleWithBLOBsEle;
@Override
public void initialized(IntrospectedTable introspectedTable) {
super.initialized(introspectedTable);
// bug:26,27
this.selectOneByExampleWithBLOBsEle = null;
this.selectOneByExampleEle = null;
}
/**
* Java Client Methods 生成
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
@@ -20,10 +20,7 @@ import com.itfsw.mybatis.generator.plugins.utils.*;
import com.itfsw.mybatis.generator.plugins.utils.hook.ISelectOneByExamplePluginHook;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.*;
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
@@ -44,6 +41,8 @@ public class SelectSelectivePlugin extends BasePlugin implements ISelectOneByExa
public static final String METHOD_SELECT_BY_PRIMARY_KEY_SELECTIVE = "selectByPrimaryKeySelective";
public static final String METHOD_SELECT_ONE_BY_EXAMPLE_SELECTIVE = "selectOneByExampleSelective";
public static final String ID_FOR_PROPERTY_BASED_RESULT_MAP = "BasePropertyResultMap";
private XmlElement selectByExampleSelectiveEle;
private XmlElement selectByPrimaryKeySelectiveEle;
/**
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
@@ -62,6 +61,19 @@ public class SelectSelectivePlugin extends BasePlugin implements ISelectOneByExa
return super.validate(warnings);
}
/**
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
* @param introspectedTable
*/
@Override
public void initialized(IntrospectedTable introspectedTable) {
super.initialized(introspectedTable);
// bug:26,27
this.selectByExampleSelectiveEle = null;
this.selectByPrimaryKeySelectiveEle = null;
}
// =========================================== client 方法生成 ===================================================
@Override
@@ -120,18 +132,24 @@ public class SelectSelectivePlugin extends BasePlugin implements ISelectOneByExa
// ============================================== sqlMap 生成 ===================================================
@Override
public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
this.selectByExampleSelectiveEle = this.generateSelectSelectiveElement(METHOD_SELECT_BY_EXAMPLE_SELECTIVE, introspectedTable, false, true);
return super.sqlMapSelectByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
}
@Override
public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
if (!introspectedTable.hasBLOBColumns()) {
this.selectByExampleSelectiveEle = this.generateSelectSelectiveElement(METHOD_SELECT_BY_EXAMPLE_SELECTIVE, introspectedTable, false, true);
}
return super.sqlMapSelectByExampleWithBLOBsElementGenerated(element, introspectedTable);
}
@Override
public boolean sqlMapSelectByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
this.selectByPrimaryKeySelectiveEle = this.generateSelectSelectiveElement(METHOD_SELECT_BY_PRIMARY_KEY_SELECTIVE, introspectedTable, false, false);
return super.sqlMapSelectByPrimaryKeyElementGenerated(element, introspectedTable);
}
@@ -156,15 +174,18 @@ public class SelectSelectivePlugin extends BasePlugin implements ISelectOneByExa
for (IntrospectedColumn introspectedColumn : introspectedTable.getNonPrimaryKeyColumns()) {
resultMapEle.addElement(XmlElementGeneratorTools.generateResultMapResultElement("result", introspectedColumn));
}
document.getRootElement().getElements().add(0, resultMapEle);
document.getRootElement().addElement(0, resultMapEle);
}
// 1. selectByExampleSelective 方法
FormatTools.addElementWithBestPosition(document.getRootElement(), this.generateSelectSelectiveElement(METHOD_SELECT_BY_EXAMPLE_SELECTIVE, introspectedTable, false, true));
if (this.selectByExampleSelectiveEle != null) {
FormatTools.addElementWithBestPosition(document.getRootElement(), this.selectByExampleSelectiveEle);
}
// 2. selectByPrimaryKeySelective
FormatTools.addElementWithBestPosition(document.getRootElement(), this.generateSelectSelectiveElement(METHOD_SELECT_BY_PRIMARY_KEY_SELECTIVE, introspectedTable, false, false));
if (this.selectByPrimaryKeySelectiveEle != null) {
FormatTools.addElementWithBestPosition(document.getRootElement(), this.selectByPrimaryKeySelectiveEle);
}
return true;
}
@@ -141,7 +141,7 @@ public class LogicalDeletePluginTest {
ObjectUtil tbExample = new ObjectUtil(loader, packagz + ".TbExample");
ObjectUtil criteria = new ObjectUtil(tbExample.invoke("createCriteria"));
criteria.invoke("andDeleted", true);
criteria.invoke("andLogicalDeleted", true);
criteria.invoke("andIdEqualTo", 3l);
@@ -16,16 +16,15 @@
package com.itfsw.mybatis.generator.plugins;
import com.itfsw.mybatis.generator.plugins.tools.AbstractShellCallback;
import com.itfsw.mybatis.generator.plugins.tools.DBHelper;
import com.itfsw.mybatis.generator.plugins.tools.MyBatisGeneratorTool;
import com.itfsw.mybatis.generator.plugins.tools.ObjectUtil;
import com.itfsw.mybatis.generator.plugins.tools.*;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.lang.reflect.Array;
import java.sql.SQLException;
/**
@@ -41,7 +40,7 @@ public class ModelColumnPluginTest {
* 初始化数据库
*/
@BeforeClass
public static void init() throws SQLException, IOException, ClassNotFoundException {
public static void init() throws SQLException, IOException {
DBHelper.createDB("scripts/ModelColumnPlugin/init.sql");
}
@@ -49,7 +48,7 @@ public class ModelColumnPluginTest {
* 测试生成的model
*/
@Test
public void test() throws Exception {
public void testModel() throws Exception {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/ModelColumnPlugin/mybatis-generator.xml");
tool.generate(new AbstractShellCallback() {
@Override
@@ -78,6 +77,63 @@ public class ModelColumnPluginTest {
Assert.assertEquals(TbKeysColumnKey1.invoke("value"), "key_1");
ObjectUtil TbKeysColumnField1 = new ObjectUtil(loader, packagz + ".TbKeys$Column#field1");
Assert.assertEquals(TbKeysColumnField1.invoke("value"), "field_1");
// 5. excludes 方法
// 不排除
Object columns = Array.newInstance(TbColumnField1.getCls(), 0);
Object[] result = (Object[])(MethodUtils.invokeStaticMethod(Class.forName(packagz + ".Tb$Column"), "excludes", columns));
Assert.assertEquals(result.length, 5);
// 排除两个
columns = Array.newInstance(TbColumnField1.getCls(), 2);
Array.set(columns, 0, TbColumnField1.getObject());
Array.set(columns, 1, TbColumnTsIncF2.getObject());
result = (Object[])(MethodUtils.invokeStaticMethod(Class.forName(packagz + ".Tb$Column"), "excludes", columns));
Assert.assertEquals(result.length, 3);
for (Object obj : result){
ObjectUtil column = new ObjectUtil(obj);
if (column.invoke("value").equals("field_1") || column.invoke("value").equals("inc_f2")){
Assert.assertTrue(false);
}
}
}
});
}
/**
* 测试excludes
*/
@Test
public void testExcludes() throws Exception {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/ModelColumnPlugin/mybatis-generator-with-SeleciveEnhancedPlugin.xml");
tool.generate(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 tb = new ObjectUtil(loader, packagz + ".Tb");
tb.set("id", 121L);
tb.set("incF3", 10L);
tb.set("tsIncF2", 5L);
// selective
ObjectUtil TbColumnId = new ObjectUtil(loader, packagz + ".Tb$Column#id");
ObjectUtil TbColumnField1 = new ObjectUtil(loader, packagz + ".Tb$Column#field1");
ObjectUtil TbColumnTsIncF2 = new ObjectUtil(loader, packagz + ".Tb$Column#tsIncF2");
Object columns = Array.newInstance(TbColumnField1.getCls(), 3);
Array.set(columns, 0, TbColumnId.getObject());
Array.set(columns, 1, TbColumnField1.getObject());
Array.set(columns, 2, TbColumnTsIncF2.getObject());
// sql(指定列)
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "insertSelective", tb.getObject(), columns);
Assert.assertEquals(sql, "insert into tb ( id , field_1 , inc_f2 ) values ( 121 , 'null' , 5 )");
// sql(排除列)
columns = MethodUtils.invokeStaticMethod(Class.forName(packagz + ".Tb$Column"), "excludes", columns);
sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "insertSelective", tb.getObject(), columns);
Assert.assertEquals(sql, "insert into tb ( inc_f1 , inc_f3 ) values ( null , 10 )");
Object result = tbMapper.invoke("insertSelective", tb.getObject(), columns);
Assert.assertEquals(result, 1);
}
});
}
@@ -20,11 +20,11 @@ SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
DROP TABLE IF EXISTS `tb`;
CREATE TABLE `tb` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1',
`field_1` 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',
`id` bigint(20) AUTO_INCREMENT COMMENT '注释1',
`field_1` varchar(255) COMMENT '注释2',
`inc_f1` bigint(20) DEFAULT '0',
`inc_f2` bigint(20) DEFAULT '0',
`inc_f3` bigint(20) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<!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.UpsertPlugin">
<property name="allowMultiQueries" value="true"/>
</plugin>
<plugin type="com.itfsw.mybatis.generator.plugins.SelectiveEnhancedPlugin"/>
<plugin type="com.itfsw.mybatis.generator.plugins.ModelColumnPlugin"/>
<!--jdbc的数据库连接 -->
<jdbcConnection driverClass="${driver}" connectionURL="${url}" userId="${username}" password="${password}" />
<!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径 -->
<javaModelGenerator targetPackage="" targetProject=""/>
<!--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"/>
<columnOverride column="inc_f2" property="tsIncF2"/>
</table>
</context>
</generatorConfiguration>