Compare commits

..
27 Commits
Author SHA1 Message Date
hewei 5db845038b [maven-release-plugin] prepare for next development iteration 2018-02-05 14:02:40 +08:00
hewei b4741d9ebe [maven-release-plugin] prepare release V1.1.2 2018-02-05 14:02:19 +08:00
hewei fef2b76d6e V1.1.2 2018-02-05 14:00:39 +08:00
hewei adbfe3a2db [issues#20]:selectByExampleSelective 不支持 distinct 2018-02-05 14:00:06 +08:00
hewei f3d2a6fdba [issues#19]:提供默认模板下载地址 2018-02-05 13:59:15 +08:00
hewei 9fa87b4222 [maven-release-plugin] prepare for next development iteration 2018-01-22 16:49:33 +08:00
hewei fe83da74ba [maven-release-plugin] prepare release V1.1.1 2018-01-22 16:49:14 +08:00
hewei f50f031dea bugfix[issues#16]:修复选择返回插件对于自定义column异常问题,不能直接使用resultType而只能使用resultMap进行 2018-01-22 16:47:29 +08:00
hewei 21743bf020 bugfix[issues#16]:修复选择返回插件对于自定义column异常问题,不能直接使用resultType而只能使用resultMap进行 2018-01-22 16:40:33 +08:00
hewei 51eb354d83 bugfix[issues#16]:修复选择返回插件对于自定义column异常问题,不能直接使用resultType而只能使用resultMap进行 2018-01-22 16:25:43 +08:00
hewei d2ede434ed 完善注释插件里具体参数链接,方便使用 2018-01-08 10:24:45 +08:00
hewei bde5387f41 完善注释插件里具体参数链接,方便使用 2018-01-08 10:20:03 +08:00
hewei 5b89754a1e [maven-release-plugin] prepare for next development iteration 2017-12-28 16:13:08 +08:00
hewei bf3a12e952 [maven-release-plugin] prepare release V1.1.0 2017-12-28 16:12:50 +08:00
hewei 60b160dd4f V1.1.0 2017-12-28 16:11:00 +08:00
hewei f8d728f4ed V1.0.20 2017-12-28 16:09:37 +08:00
hewei ff41844450 升级mybatis-generator到最新版本1.3.6 2017-12-28 15:28:54 +08:00
hewei 09c947db35 [maven-release-plugin] prepare for next development iteration 2017-09-28 18:30:14 +08:00
hewei f0506b934d [maven-release-plugin] prepare release V1.0.19 2017-09-28 18:29:58 +08:00
hewei 9868f0ed44 V1.0.19 2017-09-28 18:27:17 +08:00
hewei 40aed67856 bugfix:插件SelectiveEnhancedPlugin之前命名的判断方法isSelective在进行Json Serializer 时某些情况下可能造成冲突,重新命名为hasSelective 2017-09-28 18:16:48 +08:00
hewei 826ad11e64 [maven-release-plugin] prepare for next development iteration 2017-08-31 18:51:35 +08:00
hewei a82128c10c [maven-release-plugin] prepare release V1.0.18 2017-08-31 18:51:16 +08:00
hewei 3464bc28aa V1.0.18 2017-08-31 18:49:55 +08:00
hewei 1589709d5c pull#12 逻辑删除插件增强 2017-08-31 18:39:24 +08:00
何伟 b1e23b3b51 Update README.md
重命名插件文档错误更正
2017-08-31 10:55:06 +08:00
hewei a4700aa38c [maven-release-plugin] prepare for next development iteration 2017-08-17 13:54:59 +08:00
17 changed files with 902 additions and 220 deletions
+30 -19
View File
@@ -19,7 +19,7 @@
* [自定义注释插件(CommentPlugin)](#13-自定义注释插件)
* [增量插件(IncrementsPlugin)](#14-增量插件)
* [查询结果选择性返回插件(SelectSelectivePlugin)](#15-查询结果选择性返回插件)
* [官方ConstructorBased配置BUG临时修正插件(ConstructorBasedBugFixPlugin)](#16-官方constructorbased配置bug临时修正插件)
* [~~官方ConstructorBased配置BUG临时修正插件(ConstructorBasedBugFixPlugin)~~](#16-官方constructorbased配置bug临时修正插件)
---------------------------------------
Maven引用:
@@ -27,7 +27,7 @@ Maven引用:
<dependency>
<groupId>com.itfsw</groupId>
<artifactId>mybatis-generator-plugin</artifactId>
<version>1.0.17</version>
<version>1.1.2</version>
</dependency>
```
---------------------------------------
@@ -37,7 +37,7 @@ MyBatis Generator 参考配置(插件依赖应该配置在mybatis-generator-ma
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<version>1.3.6</version>
<configuration>
<!-- 配置文件 -->
<configurationFile>src/main/resources/mybatis-generator.xml</configurationFile>
@@ -348,8 +348,10 @@ public class Test {
```
### 7. 逻辑删除插件
因为很多实际项目数据都不允许物理删除,多采用逻辑删除,所以单独为逻辑删除做了一个插件,方便使用。
- 增加logicalDeleteByExample和logicalDeleteByPrimaryKey方法;
- 查询构造工具中增加逻辑删除条件andDeleted(boolean);
- 增加logicalDeleteByExample和logicalDeleteByPrimaryKey方法;
- 增加selectByPrimaryKeyWithLogicalDelete方法([[pull#12]](https://github.com/itfsw/mybatis-generator-plugin/pull/12));
- 查询构造工具中增加逻辑删除条件andLogicalDeleted(boolean);
- 数据Model增加逻辑删除条件andLogicalDeleted(boolean);
- 增加逻辑删除常量IS_DELETED(已删除 默认值)、NOT_DELETED(未删除 默认值)([[issues#11]](https://github.com/itfsw/mybatis-generator-plugin/issues/11));
插件:
@@ -399,7 +401,7 @@ public class Test {
.createCriteria()
.andField1EqualTo(1)
// 新增了一个andDeleted方法过滤逻辑删除数据
.andDeleted(true)
.andLogicalDeleted(true)
// 当然也可直接使用逻辑删除列的查询方法,我们数据Model中定义了一个逻辑删除常量DEL_FLAG
.andDelFlagEqualTo(Tb.IS_DELETED)
.example()
@@ -409,7 +411,12 @@ public class Test {
Tb tb = new Tb.Builder()
.delFlag(Tb.IS_DELETED) // 删除
.delFlag(Tb.NOT_DELETED) // 未删除
.build();
.build()
.andLogicalDeleted(true); // 也可以在这里使用true|false设置逻辑删除
// 5. selectByPrimaryKeyWithLogicalDelete V1.0.18 版本增加
// 因为之前觉得既然拿到了主键这种查询没有必要,但是实际使用中可能存在根据主键判断是否逻辑删除的情况,这种场景还是有用的
this.tbMapper.selectByPrimaryKeyWithLogicalDelete(1, true);
}
}
```
@@ -650,7 +657,7 @@ public class Test {
```xml
<xml>
<!-- Table重命名插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.TablePrefixPlugin">
<plugin type="com.itfsw.mybatis.generator.plugins.TableRenamePlugin">
<!-- 可根据具体需求确定是否配置 -->
<property name="searchString" value="^T"/>
<property name="replaceString" value=""/>
@@ -689,20 +696,22 @@ Mybatis Generator是原生支持自定义注释的(commentGenerator配置type
>warning: 请注意拷贝参考模板注释前方空格,idea等工具拷贝进去后自动格式化会造成格式错乱。
>warning: 模板引擎采用的是freemarker所以一些freemarker指令参数(如:<#if xx></#if>、${.now?string("yyyy-MM-dd HH:mm:ss")})都是可以使用的,请自己尝试。
>warning: 模板引擎采用的是freemarker所以一些freemarker指令参数(如:<#if xx></#if>、${.now?string("yyyy-MM-dd HH:mm:ss")})都是可以使用的,请自己尝试。
>warning: [默认模板](https://github.com/itfsw/mybatis-generator-plugin/blob/master/src/main/resources/default-comment.ftl)
| 注释ID | 传入参数 | 备注 |
| ----- | ----- | ---- |
| addJavaFileComment | mgb<br>compilationUnit | Java文件注释 |
| addComment | mgb<br>xmlElement | Xml节点注释 |
| addRootComment | mgb<br>rootElement | Xml根节点注释 |
| addFieldComment | mgb<br>field<br>introspectedTable<br>introspectedColumn | Java 字段注释(非生成Model对应表字段时,introspectedColumn可能不存在) |
| addModelClassComment | mgb<br>topLevelClass<br>introspectedTable | 表Model类注释 |
| addClassComment | mgb<br>innerClass<br>introspectedTable | 类注释 |
| addEnumComment | mgb<br>innerEnum<br>introspectedTable | 枚举注释 |
| addInterfaceComment | mgb<br>innerInterface<br>introspectedTable | 接口注释(itfsw插件新增类型) |
| addGetterComment | mgb<br>method<br>introspectedTable<br>introspectedColumn | getter方法注释(introspectedColumn可能不存在) |
| addSetterComment | mgb<br>method<br>introspectedTable<br>introspectedColumn | getter方法注释(introspectedColumn可能不存在) |
| addJavaFileComment | mgb<br>[compilationUnit](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/java/CompilationUnit.java) | Java文件注释 |
| addComment | mgb<br>[xmlElement](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/xml/XmlElement.java) | Xml节点注释 |
| addRootComment | mgb<br>[rootElement](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/xml/XmlElement.java) | Xml根节点注释 |
| addFieldComment | mgb<br>[field](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/java/Field.java)<br>[introspectedTable](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/IntrospectedTable.java)<br>[introspectedColumn](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/IntrospectedColumn.java) | Java 字段注释(非生成Model对应表字段时,introspectedColumn可能不存在) |
| addModelClassComment | mgb<br>[topLevelClass](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/java/TopLevelClass.java)<br>introspectedTable | 表Model类注释 |
| addClassComment | mgb<br>[innerClass](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/java/InnerClass.java)<br>introspectedTable | 类注释 |
| addEnumComment | mgb<br>[innerEnum](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/java/InnerEnum.java)<br>introspectedTable | 枚举注释 |
| addInterfaceComment | mgb<br>[innerInterface](https://github.com/itfsw/mybatis-generator-plugin/blob/master/src/main/java/com/itfsw/mybatis/generator/plugins/utils/enhanced/InnerInterface.java)<br>introspectedTable | 接口注释(itfsw插件新增类型) |
| addGetterComment | mgb<br>[method](https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/dom/java/Method.java)<br>introspectedTable<br>introspectedColumn | getter方法注释(introspectedColumn可能不存在) |
| addSetterComment | mgb<br>method<br>introspectedTable<br>introspectedColumn | setter方法注释(introspectedColumn可能不存在) |
| addGeneralMethodComment | mgb<br>method<br>introspectedTable | 方法注释 |
插件:
@@ -1036,6 +1045,8 @@ public class Test {
一般我们在做查询优化的时候会要求查询返回时不要返回自己不需要的字段数据,因为Sending data所花费的时间和加大内存的占用
,所以我们看到官方对于大数据的字段会拆分成xxxWithBLOBs的操作,但是这种拆分还是不能精确到具体列返回。
所以该插件的作用就是精确指定查询操作所需要返回的字段信息,实现查询的精确返回。
>warning: 因为采用的是resultMap进行的属性绑定(即时设置了constructorBased=true也无效,因为参数个数不一致会导致异常,该插件也会另外生成一个基于属性绑定的resultMap),
所以可能会出现list中存在null元素的问题,这个是mybatis自身机制造成的当查询出来的某行所有列都为null时不会生成对象(PS:其实这个不能算是错误,mybatis这样处理也说的通,但是在使用时还是要注意null的判断,当然如果有什么配置或者其他处理方式欢迎反馈哦)。
插件:
```xml
+3 -3
View File
@@ -3,7 +3,7 @@
<groupId>com.itfsw</groupId>
<artifactId>mybatis-generator-plugin</artifactId>
<version>1.0.17</version>
<version>1.1.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>${project.groupId}:${project.artifactId}</name>
@@ -32,7 +32,7 @@
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
<version>1.3.6</version>
<scope>provided</scope>
</dependency>
<!-- 日志 -->
@@ -212,7 +212,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.17</tag>
<tag>HEAD</tag>
</scm>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++distribution++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -17,6 +17,7 @@
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.JavaElementGeneratorTools;
import com.itfsw.mybatis.generator.plugins.utils.XmlElementGeneratorTools;
import org.mybatis.generator.api.IntrospectedColumn;
@@ -27,10 +28,13 @@ 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.MyBatis3FormattingUtilities;
import org.mybatis.generator.internal.util.JavaBeansUtil;
import java.sql.JDBCType;
import java.util.*;
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
/**
* ---------------------------------------------------------------------------
* 逻辑删除插件
@@ -52,7 +56,10 @@ public class LogicalDeletePlugin extends BasePlugin {
public static final String DEFAULT_LOGICAL_DELETE_CONST_NAME = "IS_DELETED"; // 逻辑删除标志位常量名称
public static final String DEFAULT_LOGICAL_UN_DELETE_CONST_NAME = "NOT_DELETED"; // 逻辑删除标志位常量名称(未删除)
public static final String METHOD_LOGICAL_DELETE = "andDeleted"; // 逻辑删除查询方法
public static final String METHOD_LOGICAL_DELETED = "andLogicalDeleted"; // 逻辑删除查询方法
public static final String PARAMETER_LOGICAL_DELETED = METHOD_LOGICAL_DELETED; // 增强selectByPrimaryKey是参数名称
public static final String METHOD_SELECT_BY_PRIMARY_KEY_WITH_LOGICAL_DELETE = "selectByPrimaryKeyWithLogicalDelete"; // selectByPrimaryKey 的逻辑删除增强
private IntrospectedColumn logicalDeleteColumn; // 逻辑删除列
private String logicalDeleteValue; // 逻辑删除值
@@ -125,6 +132,15 @@ public class LogicalDeletePlugin extends BasePlugin {
// 5. 获取逻辑删除常量值
this.logicalDeleteConstName = properties.getProperty(PRO_LOGICAL_DELETE_CONST_NAME) != null ? properties.getProperty(PRO_LOGICAL_DELETE_CONST_NAME).toUpperCase() : DEFAULT_LOGICAL_DELETE_CONST_NAME;
this.logicalUnDeleteConstName = properties.getProperty(PRO_LOGICAL_UN_DELETE_CONST_NAME) != null ? properties.getProperty(PRO_LOGICAL_UN_DELETE_CONST_NAME).toUpperCase() : DEFAULT_LOGICAL_UN_DELETE_CONST_NAME;
// 6. 防止增强的selectByPrimaryKey中逻辑删除键冲突
if (this.logicalDeleteColumn != null) {
Field logicalDeleteField = JavaBeansUtil.getJavaBeansField(this.logicalDeleteColumn, context, introspectedTable);
if (logicalDeleteField.getName().equals(PARAMETER_LOGICAL_DELETED)) {
this.logicalDeleteColumn = null;
warnings.add("itfsw(逻辑删除插件):" + introspectedTable.getFullyQualifiedTable() + "配置的逻辑删除列和插件保留关键字(" + PARAMETER_LOGICAL_DELETED + ")冲突!");
}
}
}
/**
@@ -154,17 +170,30 @@ public class LogicalDeletePlugin extends BasePlugin {
// 2. 判断是否有主键,生成主键删除方法
if (introspectedTable.hasPrimaryKeyColumns()) {
// 1. 逻辑删除ByExample
Method mLogicalDeleteByPrimaryKey = new Method(METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY);
// 返回值类型
mLogicalDeleteByPrimaryKey.setReturnType(FullyQualifiedJavaType.getIntInstance());
// 2.1. 逻辑删除ByExample
Method mLogicalDeleteByPrimaryKey = JavaElementGeneratorTools.generateMethod(
METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY,
JavaVisibility.DEFAULT,
FullyQualifiedJavaType.getIntInstance()
);
commentGenerator.addGeneralMethodComment(mLogicalDeleteByPrimaryKey, introspectedTable);
// 2.2 增强selectByPrimaryKey
Method mSelectByPrimaryKey = JavaElementGeneratorTools.generateMethod(
METHOD_SELECT_BY_PRIMARY_KEY_WITH_LOGICAL_DELETE,
JavaVisibility.DEFAULT,
introspectedTable.getRules().calculateAllFieldsClass()
);
// 添加参数
Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
Set<FullyQualifiedJavaType> importedTypes = new TreeSet<>();
importedTypes.add(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Param"));
if (introspectedTable.getRules().generatePrimaryKeyClass()) {
FullyQualifiedJavaType type1 = new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyType());
importedTypes.add(type1);
mLogicalDeleteByPrimaryKey.addParameter(new Parameter(type1, "key")); //$NON-NLS-1$
mLogicalDeleteByPrimaryKey.addParameter(new Parameter(type1, "key"));
mSelectByPrimaryKey.addParameter(new Parameter(type1, "key", "@Param(\"key\")"));
} else {
// no primary key class - fields are in the base class
// if more than one PK field, then we need to annotate the
@@ -172,9 +201,6 @@ public class LogicalDeletePlugin extends BasePlugin {
// for MyBatis
List<IntrospectedColumn> introspectedColumns = introspectedTable.getPrimaryKeyColumns();
boolean annotate = introspectedColumns.size() > 1;
if (annotate) {
importedTypes.add(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Param")); //$NON-NLS-1$
}
StringBuilder sb = new StringBuilder();
for (IntrospectedColumn introspectedColumn : introspectedColumns) {
FullyQualifiedJavaType type1 = introspectedColumn.getFullyQualifiedJavaType();
@@ -182,21 +208,38 @@ public class LogicalDeletePlugin extends BasePlugin {
Parameter parameter = new Parameter(type1, introspectedColumn.getJavaProperty());
if (annotate) {
sb.setLength(0);
sb.append("@Param(\""); //$NON-NLS-1$
sb.append("@Param(\"");
sb.append(introspectedColumn.getJavaProperty());
sb.append("\")"); //$NON-NLS-1$
sb.append("\")");
parameter.addAnnotation(sb.toString());
}
mLogicalDeleteByPrimaryKey.addParameter(parameter);
Parameter parameter1 = new Parameter(type1, introspectedColumn.getJavaProperty());
sb.setLength(0);
sb.append("@Param(\"");
sb.append(introspectedColumn.getJavaProperty());
sb.append("\")");
parameter1.addAnnotation(sb.toString());
mSelectByPrimaryKey.addParameter(parameter1);
}
}
// 添加方法说明
commentGenerator.addGeneralMethodComment(mLogicalDeleteByPrimaryKey, introspectedTable);
// interface 增加方法
interfaze.addImportedTypes(importedTypes);
interfaze.addMethod(mLogicalDeleteByPrimaryKey);
logger.debug("itfsw(逻辑删除插件):" + interfaze.getType().getShortName() + "增加方法logicalDeleteByPrimaryKey。");
// 增强selectByPrimaryKey
mSelectByPrimaryKey.addParameter(new Parameter(
FullyQualifiedJavaType.getBooleanPrimitiveInstance(),
PARAMETER_LOGICAL_DELETED,
"@Param(\"" + PARAMETER_LOGICAL_DELETED + "\")"
));
commentGenerator.addGeneralMethodComment(mSelectByPrimaryKey, introspectedTable);
FormatTools.addMethodWithBestPosition(interfaze, mSelectByPrimaryKey);
}
}
return true;
@@ -213,13 +256,13 @@ public class LogicalDeletePlugin extends BasePlugin {
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
if (this.logicalDeleteColumn != null) {
// 1. 逻辑删除ByExample
XmlElement logicalDeleteByExample = new XmlElement("update"); //$NON-NLS-1$
XmlElement logicalDeleteByExample = new XmlElement("update");
logicalDeleteByExample.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_EXAMPLE));
logicalDeleteByExample.addAttribute(new Attribute("parameterType", "map")); //$NON-NLS-1$ //$NON-NLS-2$
logicalDeleteByExample.addAttribute(new Attribute("parameterType", "map")); //$NON-NLS-2$
commentGenerator.addComment(logicalDeleteByExample);
StringBuilder sb = new StringBuilder();
sb.append("update "); //$NON-NLS-1$
sb.append("update ");
sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
sb.append(" set ");
// 更新逻辑删除字段
@@ -251,7 +294,7 @@ public class LogicalDeletePlugin extends BasePlugin {
// 2. 判断是否有主键,生成主键删除方法
if (introspectedTable.hasPrimaryKeyColumns()) {
XmlElement logicalDeleteByPrimaryKey = new XmlElement("update"); //$NON-NLS-1$
XmlElement logicalDeleteByPrimaryKey = new XmlElement("update");
logicalDeleteByPrimaryKey.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY));
String parameterClass;
@@ -261,7 +304,7 @@ public class LogicalDeletePlugin extends BasePlugin {
// PK fields are in the base class. If more than on PK
// field, then they are coming in a map.
if (introspectedTable.getPrimaryKeyColumns().size() > 1) {
parameterClass = "map"; //$NON-NLS-1$
parameterClass = "map";
} else {
parameterClass = introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().toString();
}
@@ -270,7 +313,7 @@ public class LogicalDeletePlugin extends BasePlugin {
commentGenerator.addComment(logicalDeleteByPrimaryKey);
StringBuilder sb1 = new StringBuilder();
sb1.append("update "); //$NON-NLS-1$
sb1.append("update ");
sb1.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
sb1.append(" set ");
// 更新逻辑删除字段
@@ -300,25 +343,108 @@ public class LogicalDeletePlugin extends BasePlugin {
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
sb.setLength(0);
if (and) {
sb.append(" and "); //$NON-NLS-1$
sb.append(" and ");
} else {
sb.append("where "); //$NON-NLS-1$
sb.append("where ");
and = true;
}
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(" = "); //$NON-NLS-1$
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
logicalDeleteByPrimaryKey.addElement(new TextElement(sb.toString()));
}
document.getRootElement().addElement(logicalDeleteByPrimaryKey);
logger.debug("itfsw(逻辑删除插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加方法logicalDeleteByPrimaryKey的实现。");
// 3. 增强selectByPrimaryKey
XmlElement selectByPrimaryKey = new XmlElement("select");
commentGenerator.addComment(selectByPrimaryKey);
selectByPrimaryKey.addAttribute(new Attribute("id", METHOD_SELECT_BY_PRIMARY_KEY_WITH_LOGICAL_DELETE));
if (introspectedTable.getRules().generateResultMapWithBLOBs()) {
selectByPrimaryKey.addAttribute(new Attribute("resultMap", introspectedTable.getResultMapWithBLOBsId()));
} else {
selectByPrimaryKey.addAttribute(new Attribute("resultMap", introspectedTable.getBaseResultMapId()));
}
selectByPrimaryKey.addAttribute(new Attribute("parameterType", "map"));
context.getCommentGenerator().addComment(selectByPrimaryKey);
sb = new StringBuilder();
sb.append("select ");
if (stringHasValue(introspectedTable.getSelectByPrimaryKeyQueryId())) {
sb.append('\'');
sb.append(introspectedTable.getSelectByPrimaryKeyQueryId());
sb.append("' as QUERYID,");
}
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
selectByPrimaryKey.addElement(XmlElementGeneratorTools.getBaseColumnListElement(introspectedTable));
if (introspectedTable.hasBLOBColumns()) {
selectByPrimaryKey.addElement(new TextElement(","));
selectByPrimaryKey.addElement(XmlElementGeneratorTools.getBlobColumnListElement(introspectedTable));
}
sb.setLength(0);
sb.append("from ");
sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
and = false;
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
sb.setLength(0);
if (and) {
sb.append(" and ");
} else {
sb.append("where ");
and = true;
}
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(introspectedColumn));
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
}
// 逻辑删除的判断
sb.setLength(0);
sb.append(" and ");
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(this.logicalDeleteColumn));
sb.append(" = ");
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
XmlElement chooseEle = new XmlElement("choose");
XmlElement whenEle = new XmlElement("when");
whenEle.addAttribute(new Attribute("test", PARAMETER_LOGICAL_DELETED));
whenEle.addElement(new TextElement("'" + this.logicalDeleteValue + "'"));
chooseEle.addElement(whenEle);
XmlElement otherwiseEle = new XmlElement("otherwise");
otherwiseEle.addElement(new TextElement("'" + this.logicalUnDeleteValue + "'"));
chooseEle.addElement(otherwiseEle);
selectByPrimaryKey.addElement(chooseEle);
FormatTools.addElementWithBestPosition(document.getRootElement(), selectByPrimaryKey);
}
}
return true;
}
/**
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
this.generateModelMethodsAndFields(topLevelClass, introspectedTable);
return super.modelPrimaryKeyClassGenerated(topLevelClass, introspectedTable);
}
/**
* Model 生成
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
@@ -328,57 +454,89 @@ public class LogicalDeletePlugin extends BasePlugin {
*/
@Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
this.generateModelMethodsAndFields(topLevelClass, introspectedTable);
return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
}
/**
* 生成Model 逻辑删除相关方法和常量
* !!! bugfix:逻辑删除列作为复合主键的一部分的情况
* @param topLevelClass
* @param introspectedTable
*/
private void generateModelMethodsAndFields(TopLevelClass topLevelClass, IntrospectedTable introspectedTable){
if (this.logicalDeleteColumn != null) {
ArrayList<Field> fields = (ArrayList<Field>) topLevelClass.getFields();
// 添加删除标志位常量
String logicalDeleteValue;
if (this.logicalDeleteValue == null || "NULL".equalsIgnoreCase(this.logicalDeleteValue)) {
logicalDeleteValue = "null";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("String")) {
logicalDeleteValue = "\"" + this.logicalDeleteValue + "\"";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("Boolean")) {
logicalDeleteValue = (this.logicalDeleteValue.equals("1") || this.logicalDeleteValue.equalsIgnoreCase("true")) ? "true" : "false";
} 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);
fields.add(0, logicalDeleteConstField);
// 添加删除标志位常量 DEL_FLAG_ON
String logicalUnDeleteValue;
if (this.logicalUnDeleteValue == null || "NULL".equalsIgnoreCase(this.logicalUnDeleteValue)) {
logicalUnDeleteValue = "null";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("String")) {
logicalUnDeleteValue = "\"" + this.logicalUnDeleteValue + "\"";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("Boolean")) {
logicalUnDeleteValue = (this.logicalUnDeleteValue.equals("1") || this.logicalUnDeleteValue.equalsIgnoreCase("true")) ? "true" : "false";
} else {
logicalUnDeleteValue = this.logicalUnDeleteValue;
// 常量和逻辑删除方法跟随 逻辑删除列走
boolean flag = false;
for (Field field : topLevelClass.getFields()){
if (this.logicalDeleteColumn.getJavaProperty().equals(field.getName())){
flag = true;
break;
}
}
// TODO 过期
Field field1 = JavaElementGeneratorTools.generateStaticFinalField("DEL_FLAG_ON", this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalUnDeleteValue);
field1.addAnnotation("@Deprecated");
commentGenerator.addFieldComment(field1, introspectedTable);
// 常量插入到第一位
fields.add(0, field1);
if (flag){
ArrayList<Field> fields = (ArrayList<Field>) topLevelClass.getFields();
Field logicalUnDeleteConstField = JavaElementGeneratorTools.generateStaticFinalField(this.logicalUnDeleteConstName, this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalUnDeleteValue);
commentGenerator.addFieldComment(logicalUnDeleteConstField, introspectedTable);
fields.add(0, logicalUnDeleteConstField);
// 添加删除标志位常量
String logicalDeleteValue;
if (this.logicalDeleteValue == null || "NULL".equalsIgnoreCase(this.logicalDeleteValue)) {
logicalDeleteValue = "null";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("String")) {
logicalDeleteValue = "\"" + this.logicalDeleteValue + "\"";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("Boolean")) {
logicalDeleteValue = (this.logicalDeleteValue.equals("1") || this.logicalDeleteValue.equalsIgnoreCase("true")) ? "true" : "false";
} 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);
fields.add(0, logicalDeleteConstField);
// 添加删除标志位常量 DEL_FLAG_ON
String logicalUnDeleteValue;
if (this.logicalUnDeleteValue == null || "NULL".equalsIgnoreCase(this.logicalUnDeleteValue)) {
logicalUnDeleteValue = "null";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("String")) {
logicalUnDeleteValue = "\"" + this.logicalUnDeleteValue + "\"";
} else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("Boolean")) {
logicalUnDeleteValue = (this.logicalUnDeleteValue.equals("1") || this.logicalUnDeleteValue.equalsIgnoreCase("true")) ? "true" : "false";
} else {
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);
// ================================================= andLogicalDeleted =============================================
Method mAndLogicalDeleted = JavaElementGeneratorTools.generateMethod(
METHOD_LOGICAL_DELETED,
JavaVisibility.PUBLIC,
null,
new Parameter(FullyQualifiedJavaType.getBooleanPrimitiveInstance(), "deleted")
);
commentGenerator.addGeneralMethodComment(mAndLogicalDeleted, introspectedTable);
Method logicalDeleteSetter = JavaBeansUtil.getJavaBeansSetter(this.logicalDeleteColumn, context, introspectedTable);
mAndLogicalDeleted.addBodyLine(logicalDeleteSetter.getName() +"(deleted ? " + this.logicalDeleteConstName + " : " + this.logicalUnDeleteConstName + ");");
FormatTools.addMethodWithBestPosition(topLevelClass, mAndLogicalDeleted);
}
}
return true;
}
/**
@@ -399,7 +557,7 @@ public class LogicalDeletePlugin extends BasePlugin {
for (InnerClass innerClass : innerClasses) {
if ("Criteria".equals(innerClass.getType().getShortName())) {
// 增加逻辑删除条件
Method method = new Method(METHOD_LOGICAL_DELETE);
Method method = new Method(METHOD_LOGICAL_DELETED);
commentGenerator.addGeneralMethodComment(method, introspectedTable);
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(innerClass.getType());
@@ -414,7 +572,7 @@ public class LogicalDeletePlugin extends BasePlugin {
StringBuilder equalToMethodName = new StringBuilder();
equalToMethodName.append(this.logicalDeleteColumn.getJavaProperty());
equalToMethodName.setCharAt(0, Character.toUpperCase(equalToMethodName.charAt(0)));
equalToMethodName.insert(0, "and"); //$NON-NLS-1$
equalToMethodName.insert(0, "and");
equalToMethodName.append("EqualTo");
sb.append(equalToMethodName);
sb.append("(" + modelName + "." + this.logicalDeleteConstName + ")");
@@ -425,7 +583,7 @@ public class LogicalDeletePlugin extends BasePlugin {
StringBuilder notEqualToMethodName = new StringBuilder();
notEqualToMethodName.append(this.logicalDeleteColumn.getJavaProperty());
notEqualToMethodName.setCharAt(0, Character.toUpperCase(notEqualToMethodName.charAt(0)));
notEqualToMethodName.insert(0, "and"); //$NON-NLS-1$
notEqualToMethodName.insert(0, "and");
notEqualToMethodName.append("NotEqualTo");
sb.append(notEqualToMethodName);
sb.append("(" + modelName + "." + this.logicalDeleteConstName + ")");
@@ -435,6 +593,12 @@ public class LogicalDeletePlugin extends BasePlugin {
method.addBodyLine(sb.toString());
innerClass.addMethod(method);
// TODO 过期方法
Method mAndDeleted = JavaElementGeneratorTools.cloneMethod(method);
mAndDeleted.setName("andDeleted");
mAndDeleted.addAnnotation("@Deprecated");
innerClass.addMethod(mAndDeleted);
logger.debug("itfsw(逻辑删除插件):" + topLevelClass.getType().getShortName() + "." + innerClass.getType().getShortName() + "增加andDeleted方法。");
}
}
@@ -25,6 +25,8 @@ 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.MyBatis3FormattingUtilities;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.elements.ResultMapWithBLOBsElementGenerator;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.elements.ResultMapWithoutBLOBsElementGenerator;
import java.util.List;
@@ -42,6 +44,7 @@ public class SelectSelectivePlugin extends BasePlugin {
public static final String METHOD_SELECT_BY_EXAMPLE_SELECTIVE = "selectByExampleSelective";
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";
/**
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
@@ -139,6 +142,29 @@ public class SelectSelectivePlugin extends BasePlugin {
*/
@Override
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
// issues#16
if (introspectedTable.isConstructorBased()) {
XmlElement resultMapEle = new XmlElement("resultMap");
resultMapEle.addAttribute(new Attribute("id", ID_FOR_PROPERTY_BASED_RESULT_MAP));
String returnType;
if (introspectedTable.getRules().generateBaseRecordClass()) {
returnType = introspectedTable.getBaseRecordType();
} else {
returnType = introspectedTable.getPrimaryKeyType();
}
resultMapEle.addAttribute(new Attribute("type", returnType));
commentGenerator.addComment(resultMapEle);
if (introspectedTable.getRules().generateResultMapWithBLOBs()) {
addResultMapElementsWithBLOBs(resultMapEle, introspectedTable);
} else if (introspectedTable.getRules().generateBaseResultMap()) {
addResultMapElementsWithoutBLOBs(resultMapEle, introspectedTable);
}
document.getRootElement().getElements().add(0, resultMapEle);
}
// 生成返回字段节点
XmlElement columnsEle = new XmlElement("foreach");
columnsEle.addAttribute(new Attribute("collection", "selective"));
@@ -151,13 +177,25 @@ public class SelectSelectivePlugin extends BasePlugin {
commentGenerator.addComment(selectByExampleSelectiveEle);
selectByExampleSelectiveEle.addAttribute(new Attribute("id", METHOD_SELECT_BY_EXAMPLE_SELECTIVE));
selectByExampleSelectiveEle.addAttribute(new Attribute("resultType", introspectedTable.getRules().calculateAllFieldsClass().getFullyQualifiedName()));
// issues#16
if (introspectedTable.isConstructorBased()) {
selectByExampleSelectiveEle.addAttribute(new Attribute("resultMap", ID_FOR_PROPERTY_BASED_RESULT_MAP));
} else {
selectByExampleSelectiveEle.addAttribute(new Attribute("resultMap", introspectedTable.getBaseResultMapId()));
}
selectByExampleSelectiveEle.addAttribute(new Attribute("parameterType", "map"));
selectByExampleSelectiveEle.addElement(new TextElement("select"));
if (stringHasValue(introspectedTable.getSelectByExampleQueryId())) {
selectByExampleSelectiveEle.addElement(new TextElement("'" + introspectedTable.getSelectByExampleQueryId() + "' as QUERYID,"));
}
// issues#20
XmlElement ifDistinctElement = new XmlElement("if");
ifDistinctElement.addAttribute(new Attribute("test", "example.distinct"));
ifDistinctElement.addElement(new TextElement("distinct"));
selectByExampleSelectiveEle.addElement(ifDistinctElement);
selectByExampleSelectiveEle.addElement(columnsEle);
selectByExampleSelectiveEle.addElement(new TextElement("from " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()));
@@ -171,11 +209,16 @@ public class SelectSelectivePlugin extends BasePlugin {
FormatTools.addElementWithBestPosition(document.getRootElement(), selectByExampleSelectiveEle);
// 2. selectByPrimaryKeySelective
XmlElement selectByPrimaryKeySelectiveEle = new XmlElement("select");
XmlElement selectByPrimaryKeySelectiveEle = new XmlElement("select");
commentGenerator.addComment(selectByPrimaryKeySelectiveEle);
selectByPrimaryKeySelectiveEle.addAttribute(new Attribute("id", METHOD_SELECT_BY_PRIMARY_KEY_SELECTIVE));
selectByPrimaryKeySelectiveEle.addAttribute(new Attribute("resultType", introspectedTable.getRules().calculateAllFieldsClass().getFullyQualifiedName()));
// issues#16
if (introspectedTable.isConstructorBased()) {
selectByPrimaryKeySelectiveEle.addAttribute(new Attribute("resultMap", ID_FOR_PROPERTY_BASED_RESULT_MAP));
} else {
selectByPrimaryKeySelectiveEle.addAttribute(new Attribute("resultMap", introspectedTable.getBaseResultMapId()));
}
selectByPrimaryKeySelectiveEle.addAttribute(new Attribute("parameterType", "map"));
selectByPrimaryKeySelectiveEle.addElement(new TextElement("select"));
@@ -190,14 +233,14 @@ public class SelectSelectivePlugin extends BasePlugin {
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
sb.setLength(0);
if (and) {
sb.append(" and ");
sb.append(" and ");
} else {
sb.append("where ");
sb.append("where ");
and = true;
}
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(introspectedColumn));
sb.append(" = ");
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, introspectedTable.getRules().generatePrimaryKeyClass() ? "record." : null));
selectByPrimaryKeySelectiveEle.addElement(new TextElement(sb.toString()));
}
@@ -210,7 +253,12 @@ public class SelectSelectivePlugin extends BasePlugin {
commentGenerator.addComment(selectOneByExampleSelectiveEle);
selectOneByExampleSelectiveEle.addAttribute(new Attribute("id", METHOD_SELECT_ONE_BY_EXAMPLE_SELECTIVE));
selectOneByExampleSelectiveEle.addAttribute(new Attribute("resultType", introspectedTable.getRules().calculateAllFieldsClass().getFullyQualifiedName()));
// issues#16
if (introspectedTable.isConstructorBased()) {
selectOneByExampleSelectiveEle.addAttribute(new Attribute("resultMap", ID_FOR_PROPERTY_BASED_RESULT_MAP));
} else {
selectOneByExampleSelectiveEle.addAttribute(new Attribute("resultMap", introspectedTable.getBaseResultMapId()));
}
selectOneByExampleSelectiveEle.addAttribute(new Attribute("parameterType", "map"));
selectOneByExampleSelectiveEle.addElement(new TextElement("select"));
@@ -236,4 +284,58 @@ public class SelectSelectivePlugin extends BasePlugin {
return true;
}
/**
* @param answer
* @param introspectedTable
* @see ResultMapWithoutBLOBsElementGenerator#addResultMapElements(XmlElement)
*/
private void addResultMapElementsWithoutBLOBs(XmlElement answer, IntrospectedTable introspectedTable) {
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
XmlElement resultElement = new XmlElement("id");
resultElement.addAttribute(new Attribute("column", MyBatis3FormattingUtilities.getRenamedColumnNameForResultMap(introspectedColumn)));
resultElement.addAttribute(new Attribute("property", introspectedColumn.getJavaProperty()));
resultElement.addAttribute(new Attribute("jdbcType", introspectedColumn.getJdbcTypeName()));
if (stringHasValue(introspectedColumn.getTypeHandler())) {
resultElement.addAttribute(new Attribute("typeHandler", introspectedColumn.getTypeHandler()));
}
answer.addElement(resultElement);
}
List<IntrospectedColumn> columns = introspectedTable.getBaseColumns();
for (IntrospectedColumn introspectedColumn : columns) {
XmlElement resultElement = new XmlElement("result");
resultElement.addAttribute(new Attribute("column", MyBatis3FormattingUtilities.getRenamedColumnNameForResultMap(introspectedColumn)));
resultElement.addAttribute(new Attribute("property", introspectedColumn.getJavaProperty()));
resultElement.addAttribute(new Attribute("jdbcType", introspectedColumn.getJdbcTypeName()));
if (stringHasValue(introspectedColumn.getTypeHandler())) {
resultElement.addAttribute(new Attribute("typeHandler", introspectedColumn.getTypeHandler()));
}
answer.addElement(resultElement);
}
}
/**
* @param answer
* @param introspectedTable
* @see ResultMapWithBLOBsElementGenerator#addResultMapElements(XmlElement)
*/
private void addResultMapElementsWithBLOBs(XmlElement answer, IntrospectedTable introspectedTable) {
for (IntrospectedColumn introspectedColumn : introspectedTable.getBLOBColumns()) {
XmlElement resultElement = new XmlElement("result");
resultElement.addAttribute(new Attribute("column", MyBatis3FormattingUtilities.getRenamedColumnNameForResultMap(introspectedColumn)));
resultElement.addAttribute(new Attribute("property", introspectedColumn.getJavaProperty()));
resultElement.addAttribute(new Attribute("jdbcType", introspectedColumn.getJdbcTypeName()));
if (stringHasValue(introspectedColumn.getTypeHandler())) {
resultElement.addAttribute(new Attribute("typeHandler", introspectedColumn.getTypeHandler()));
}
answer.addElement(resultElement);
}
}
}
@@ -40,6 +40,7 @@ import java.util.regex.Pattern;
* ---------------------------------------------------------------------------
*/
public class SelectiveEnhancedPlugin extends BasePlugin {
public static final String METHOD_HAS_SELECTIVE = "hasSelective"; // 方法名
/**
* {@inheritDoc}
@@ -80,22 +81,22 @@ public class SelectiveEnhancedPlugin extends BasePlugin {
selectiveColumnsField.setInitializationString("new HashMap<String, Boolean>()");
topLevelClass.addField(selectiveColumnsField);
// Method isSelective
Method mIsSelective = new Method("isSelective");
commentGenerator.addGeneralMethodComment(mIsSelective, introspectedTable);
mIsSelective.setVisibility(JavaVisibility.PUBLIC);
mIsSelective.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
mIsSelective.addBodyLine("return this.selectiveColumns.size() > 0;");
topLevelClass.addMethod(mIsSelective);
// Method hasSelective
Method mHasSelective = new Method(METHOD_HAS_SELECTIVE);
commentGenerator.addGeneralMethodComment(mHasSelective, introspectedTable);
mHasSelective.setVisibility(JavaVisibility.PUBLIC);
mHasSelective.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
mHasSelective.addBodyLine("return this.selectiveColumns.size() > 0;");
topLevelClass.addMethod(mHasSelective);
// Method isSelective
Method mIsSelective1 = new Method("isSelective");
commentGenerator.addGeneralMethodComment(mIsSelective1, introspectedTable);
mIsSelective1.setVisibility(JavaVisibility.PUBLIC);
mIsSelective1.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
mIsSelective1.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "column"));
mIsSelective1.addBodyLine("return this.selectiveColumns.get(column) != null;");
topLevelClass.addMethod(mIsSelective1);
// Method hasSelective
Method mHasSelective1 = new Method(METHOD_HAS_SELECTIVE);
commentGenerator.addGeneralMethodComment(mHasSelective1, introspectedTable);
mHasSelective1.setVisibility(JavaVisibility.PUBLIC);
mHasSelective1.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
mHasSelective1.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "column"));
mHasSelective1.addBodyLine("return this.selectiveColumns.get(column) != null;");
topLevelClass.addMethod(mHasSelective1);
// Method selective
Method mSelective = new Method("selective");
@@ -195,7 +196,7 @@ public class SelectiveEnhancedPlugin extends BasePlugin {
XmlElement chooseEle = new XmlElement("choose");
// when
XmlElement whenEle = new XmlElement("when");
whenEle.addAttribute(new Attribute("test", prefix + "isSelective()"));
whenEle.addAttribute(new Attribute("test", prefix + METHOD_HAS_SELECTIVE + "()"));
for (Element ele : element.getElements()) {
// 对于字符串主键,是没有if判断节点的
if (ele instanceof XmlElement) {
@@ -232,7 +233,7 @@ public class SelectiveEnhancedPlugin extends BasePlugin {
XmlElement ifEle = new XmlElement("if");
ifEle.addAttribute(new Attribute("test", prefix + "isSelective(\'" + column.getActualColumnName() + "\')"));
ifEle.addAttribute(new Attribute("test", prefix + METHOD_HAS_SELECTIVE + "(\'" + column.getActualColumnName() + "\')"));
for (Element ifChild : xmlElement.getElements()) {
ifEle.addElement(ifChild);
}
@@ -269,10 +270,10 @@ public class SelectiveEnhancedPlugin extends BasePlugin {
XmlElement chooseEle = new XmlElement("choose");
// when
XmlElement whenEle = new XmlElement("when");
whenEle.addAttribute(new Attribute("test", prefix + "isSelective()"));
whenEle.addAttribute(new Attribute("test", prefix + METHOD_HAS_SELECTIVE + "()"));
for (IntrospectedColumn introspectedColumn : (allColumns ? introspectedTable.getAllColumns() : introspectedTable.getNonBLOBColumns())) {
XmlElement eleIf = new XmlElement("if");
eleIf.addAttribute(new Attribute("test", prefix + "isSelective(\'" + introspectedColumn.getActualColumnName() + "\')"));
eleIf.addAttribute(new Attribute("test", prefix + METHOD_HAS_SELECTIVE + "(\'" + introspectedColumn.getActualColumnName() + "\')"));
eleIf.addElement(new TextElement(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, prefix) + ","));
whenEle.addElement(eleIf);
@@ -33,18 +33,17 @@ public class JavaElementGeneratorTools {
/**
* 生成静态常量
*
* @param fieldName 常量名称
* @param javaType 类型
* @param fieldName 常量名称
* @param javaType 类型
* @param initString 初始化字段
* @return
*/
public static Field generateStaticFinalField(String fieldName, FullyQualifiedJavaType javaType, String initString){
public static Field generateStaticFinalField(String fieldName, FullyQualifiedJavaType javaType, String initString) {
Field field = new Field(fieldName, javaType);
field.setVisibility(JavaVisibility.PUBLIC);
field.setStatic(true);
field.setFinal(true);
if (initString != null){
if (initString != null) {
field.setInitializationString(initString);
}
return field;
@@ -52,17 +51,16 @@ public class JavaElementGeneratorTools {
/**
* 生成属性
*
* @param fieldName 常量名称
* @param visibility 可见性
* @param javaType 类型
* @param fieldName 常量名称
* @param visibility 可见性
* @param javaType 类型
* @param initString 初始化字段
* @return
*/
public static Field generateField(String fieldName, JavaVisibility visibility, FullyQualifiedJavaType javaType, String initString){
public static Field generateField(String fieldName, JavaVisibility visibility, FullyQualifiedJavaType javaType, String initString) {
Field field = new Field(fieldName, javaType);
field.setVisibility(visibility);
if (initString != null){
if (initString != null) {
field.setInitializationString(initString);
}
return field;
@@ -70,19 +68,18 @@ public class JavaElementGeneratorTools {
/**
* 生成方法
*
* @param methodName 方法名
* @param visibility 可见性
* @param visibility 可见性
* @param returnType 返回值类型
* @param parameters 参数列表
* @return
*/
public static Method generateMethod(String methodName, JavaVisibility visibility, FullyQualifiedJavaType returnType, Parameter ... parameters){
public static Method generateMethod(String methodName, JavaVisibility visibility, FullyQualifiedJavaType returnType, Parameter... parameters) {
Method method = new Method(methodName);
method.setVisibility(visibility);
method.setReturnType(returnType);
if (parameters != null){
for (Parameter parameter: parameters) {
if (parameters != null) {
for (Parameter parameter : parameters) {
method.addParameter(parameter);
}
}
@@ -92,14 +89,13 @@ public class JavaElementGeneratorTools {
/**
* 生成方法实现体
*
* @param method 方法
* @param method 方法
* @param bodyLines 方法实现行
* @return
*/
public static Method generateMethodBody(Method method, String ... bodyLines){
if (bodyLines != null){
for (String bodyLine: bodyLines){
public static Method generateMethodBody(Method method, String... bodyLines) {
if (bodyLines != null) {
for (String bodyLine : bodyLines) {
method.addBodyLine(bodyLine);
}
}
@@ -108,11 +104,10 @@ public class JavaElementGeneratorTools {
/**
* 生成Filed的Set方法
*
* @param field field
* @return
*/
public static Method generateSetterMethod(Field field){
public static Method generateSetterMethod(Field field) {
Method method = generateMethod(
"set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1),
JavaVisibility.PUBLIC,
@@ -124,11 +119,10 @@ public class JavaElementGeneratorTools {
/**
* 生成Filed的Get方法
*
* @param field field
* @return
*/
public static Method generateGetterMethod(Field field){
public static Method generateGetterMethod(Field field) {
Method method = generateMethod(
"get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1),
JavaVisibility.PUBLIC,
@@ -139,11 +133,10 @@ public class JavaElementGeneratorTools {
/**
* 获取Model没有BLOBs类时的类型
*
* @param introspectedTable
* @return
*/
public static FullyQualifiedJavaType getModelTypeWithoutBLOBs(IntrospectedTable introspectedTable){
public static FullyQualifiedJavaType getModelTypeWithoutBLOBs(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType type;
if (introspectedTable.getRules().generateBaseRecordClass()) {
type = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
@@ -157,11 +150,10 @@ public class JavaElementGeneratorTools {
/**
* 获取Model有BLOBs类时的类型
*
* @param introspectedTable
* @return
*/
public static FullyQualifiedJavaType getModelTypeWithBLOBs(IntrospectedTable introspectedTable){
public static FullyQualifiedJavaType getModelTypeWithBLOBs(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType type;
if (introspectedTable.getRules().generateRecordWithBLOBsClass()) {
type = new FullyQualifiedJavaType(introspectedTable.getRecordWithBLOBsType());
@@ -171,4 +163,28 @@ public class JavaElementGeneratorTools {
}
return type;
}
/**
* 克隆方法
* @param method
*/
public static Method cloneMethod(Method method) {
Method result = new Method();
result.setConstructor(method.isConstructor());
result.setFinal(method.isFinal());
result.setName(method.getName());
result.setNative(method.isNative());
result.setReturnType(method.getReturnType());
result.setSynchronized(method.isSynchronized());
result.setStatic(method.isStatic());
result.setVisibility(method.getVisibility());
for (Parameter parameter : method.getParameters()) {
result.addParameter(parameter);
}
for (String docLine : method.getJavaDocLines()){
result.addJavaDocLine(docLine);
}
result.addBodyLines(method.getBodyLines());
return result;
}
}
@@ -24,20 +24,23 @@ import org.dom4j.io.SAXReader;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.MergeConstants;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.util.StringUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.bind.DatatypeConverter;
import java.io.File;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.*;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
/**
* ---------------------------------------------------------------------------
@@ -52,6 +55,10 @@ public class TemplateCommentGenerator implements CommentGenerator {
private Map<EnumNode, Template> templates = new HashMap<>(); // 模板
private boolean suppressDate = false;
private boolean suppressAllComments = false;
/**
* 构造函数
* @param templatePath 模板路径
@@ -196,7 +203,11 @@ public class TemplateCommentGenerator implements CommentGenerator {
*/
@Override
public void addConfigurationProperties(Properties properties) {
suppressDate = isTrue(properties
.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
suppressAllComments = isTrue(properties
.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
}
/**
@@ -466,6 +477,80 @@ public class TemplateCommentGenerator implements CommentGenerator {
addXmlElementComment(rootElement, map, EnumNode.ADD_ROOT_COMMENT);
}
@Override
public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> imports) {
imports.add(new FullyQualifiedJavaType("javax.annotation.Generated")); //$NON-NLS-1$
String comment = "Source Table: " + introspectedTable.getFullyQualifiedTable().toString(); //$NON-NLS-1$
method.addAnnotation(getGeneratedAnnotation(comment));
}
@Override
public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {
imports.add(new FullyQualifiedJavaType("javax.annotation.Generated")); //$NON-NLS-1$
String comment = "Source field: " //$NON-NLS-1$
+ introspectedTable.getFullyQualifiedTable().toString()
+ "." //$NON-NLS-1$
+ introspectedColumn.getActualColumnName();
method.addAnnotation(getGeneratedAnnotation(comment));
}
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> imports) {
imports.add(new FullyQualifiedJavaType("javax.annotation.Generated")); //$NON-NLS-1$
String comment = "Source Table: " + introspectedTable.getFullyQualifiedTable().toString(); //$NON-NLS-1$
field.addAnnotation(getGeneratedAnnotation(comment));
}
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {
imports.add(new FullyQualifiedJavaType("javax.annotation.Generated")); //$NON-NLS-1$
String comment = "Source field: " //$NON-NLS-1$
+ introspectedTable.getFullyQualifiedTable().toString()
+ "." //$NON-NLS-1$
+ introspectedColumn.getActualColumnName();
field.addAnnotation(getGeneratedAnnotation(comment));
}
@Override
public void addClassAnnotation(InnerClass innerClass, IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> imports) {
imports.add(new FullyQualifiedJavaType("javax.annotation.Generated")); //$NON-NLS-1$
String comment = "Source Table: " + introspectedTable.getFullyQualifiedTable().toString(); //$NON-NLS-1$
innerClass.addAnnotation(getGeneratedAnnotation(comment));
}
private String getGeneratedAnnotation(String comment) {
StringBuilder buffer = new StringBuilder();
buffer.append("@Generated("); //$NON-NLS-1$
if (suppressAllComments) {
buffer.append('\"');
} else {
buffer.append("value=\""); //$NON-NLS-1$
}
buffer.append(MyBatisGenerator.class.getName());
buffer.append('\"');
if (!suppressDate && !suppressAllComments) {
buffer.append(", date=\""); //$NON-NLS-1$
buffer.append(DatatypeConverter.printDateTime(Calendar.getInstance()));
buffer.append('\"');
}
if (!suppressAllComments) {
buffer.append(", comments=\""); //$NON-NLS-1$
buffer.append(comment);
buffer.append('\"');
}
buffer.append(')');
return buffer.toString();
}
/**
* 评论模板节点ID
*/
@@ -68,6 +68,12 @@ public class LogicalDeletePluginTest {
tool.generate();
Assert.assertEquals(tool.getWarnings().get(0), "itfsw(逻辑删除插件):tb没有找到您配置的逻辑删除值,请全局或者局部配置logicalDeleteValue和logicalUnDeleteValue值!");
// 4. 保留关键词冲突
tool = MyBatisGeneratorTool.create("scripts/LogicalDeletePlugin/mybatis-generator-with-keywords.xml");
tool.generate();
Assert.assertEquals(tool.getWarnings().get(0), "itfsw(逻辑删除插件):tb配置的逻辑删除列和插件保留关键字(andLogicalDeleted)冲突!");
}
/**
@@ -141,7 +147,7 @@ public class LogicalDeletePluginTest {
// 验证sql
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExample", tbExample.getObject());
Assert.assertEquals(sql, "select id, del_flag, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '1' and id = '3' )");
Assert.assertEquals(sql, "select id, del_flag, and_logical_deleted, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '1' and id = '3' )");
// 验证执行
Object result = tbMapper.invoke("selectByExample", tbExample.getObject());
Assert.assertEquals(((List)result).size(), 1);
@@ -168,11 +174,56 @@ public class LogicalDeletePluginTest {
// 验证sql
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExample", tbExample.getObject());
Assert.assertEquals(sql, "select id, del_flag, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '0' and id = '3' )");
Assert.assertEquals(sql, "select id, del_flag, and_logical_deleted, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '0' and id = '3' )");
// 验证执行
Object result = tbMapper.invoke("selectByExample", tbExample.getObject());
Assert.assertEquals(((List)result).size(), 0);
}
});
}
/**
* 测试Model andLogicalDeleted 方法
*/
@Test
public void testModelAndLogicalDeletedMethod() throws InterruptedException, SQLException, InvalidConfigurationException, IOException, XMLParserException {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/LogicalDeletePlugin/mybatis-generator-with-customConstName.xml");
tool.generate(new AbstractShellCallback() {
@Override
public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) throws Exception{
ObjectUtil Tb = new ObjectUtil(loader, packagz + ".Tb");
Tb.invoke("andLogicalDeleted", true);
Assert.assertEquals(Tb.get("delFlag"), (short)1);
Tb.invoke("andLogicalDeleted", false);
Assert.assertEquals(Tb.get("delFlag"), (short)0);
}
});
}
/**
* 测试 selectByPrimaryKeyWithLogicalDelete
*/
@Test
public void testSelectByPrimaryKeyWithLogicalDelete() throws IOException, XMLParserException, InvalidConfigurationException, InterruptedException, SQLException {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/LogicalDeletePlugin/mybatis-generator-with-customConstName.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")));
// 验证sql
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByPrimaryKeyWithLogicalDelete", 5l, true);
Assert.assertEquals(sql, "select id, del_flag, and_logical_deleted, ts_1, ts_3, ts_4 , ts_2 from tb where id = 5 and del_flag = '1'");
// 验证执行
Object result = tbMapper.invoke("selectByPrimaryKeyWithLogicalDelete", 5l, true);
Assert.assertNull(result);
// 验证执行
result = tbMapper.invoke("selectByPrimaryKeyWithLogicalDelete", 5l, false);
Assert.assertNotNull(result);
}
});
}
}
@@ -79,24 +79,33 @@ public class SelectSelectivePluginTest {
// 2. 执行sql
List list = (List) tbMapper.invoke("selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(list.size(), 3);
Assert.assertEquals(list.size(), 4);
int index = 0;
for (Object obj : list) {
ObjectUtil objectUtil = new ObjectUtil(obj);
// 没有查询这两个字段
if (objectUtil.get("id") != null || objectUtil.get("field2") != null) {
Assert.assertTrue(false);
}
if (index == 0) {
Assert.assertEquals(objectUtil.get("field1"), "fd1");
} else if (index == 1) {
Assert.assertNull(objectUtil.get("field1"));
if (index == 1) {
Assert.assertNull(obj);
} else {
Assert.assertEquals(objectUtil.get("field1"), "fd3");
ObjectUtil objectUtil = new ObjectUtil(obj);
// 没有查询这两个字段
if (objectUtil.get("id") != null || objectUtil.get("field2") != null) {
Assert.assertTrue(false);
}
if (index == 0) {
Assert.assertEquals(objectUtil.get("field1"), "fd1");
} else {
Assert.assertEquals(objectUtil.get("field1"), "fd3");
}
}
index++;
}
// 3. 测试 distinct
tbExample.invoke("setDistinct", true);
String sql1 = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(sql1, "select distinct field1 from tb WHERE ( id < '100' ) order by field2 asc");
List list1 = (List) tbMapper.invoke("selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(list1.size(), 3);
}
});
}
@@ -188,4 +197,119 @@ public class SelectSelectivePluginTest {
}
});
}
/**
* 测试生成的方法
* @throws Exception
*/
@Test
public void testSelectiveWithOrWithoutConstructorBased() throws Exception {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/SelectSelectivePlugin/mybatis-generator-with-constructorBased-false.xml");
tool.generate(new AbstractShellCallback() {
@Override
public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) throws Exception {
// 1. 测试sql
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("andIdLessThan", 100l);
tbExample.set("orderByClause", "field1 asc");
ObjectUtil columnField1 = new ObjectUtil(loader, packagz + ".Tb$Column#tsF1");
// java 动态参数不能有两个会冲突,最后一个封装成Array!!!必须使用反射创建指定类型数组,不然调用invoke对了可变参数会检查类型!
Object columns1 = Array.newInstance(columnField1.getCls(), 1);
Array.set(columns1, 0, columnField1.getObject());
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(sql, "select field1 from tb WHERE ( id < '100' ) order by field1 asc");
ObjectUtil columnField2 = new ObjectUtil(loader, packagz + ".Tb$Column#field2");
Object columns2 = Array.newInstance(columnField1.getCls(), 2);
Array.set(columns2, 0, columnField1.getObject());
Array.set(columns2, 1, columnField2.getObject());
sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExampleSelective", tbExample.getObject(), columns2);
Assert.assertEquals(sql, "select field1 , field2 from tb WHERE ( id < '100' ) order by field1 asc");
// 2. 执行sql
List list = (List) tbMapper.invoke("selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(list.size(), 4);
int index = 0;
for (Object obj : list) {
if (index == 0) {
Assert.assertNull(obj);
} else {
ObjectUtil objectUtil = new ObjectUtil(obj);
// 没有查询这两个字段
if (objectUtil.get("id") != null || objectUtil.get("field2") != null) {
Assert.assertTrue(false);
}
if (index == 1) {
Assert.assertEquals(objectUtil.get("tsF1"), "fd1");
} else {
Assert.assertEquals(objectUtil.get("tsF1"), "fd3");
}
}
index++;
}
}
});
tool = MyBatisGeneratorTool.create("scripts/SelectSelectivePlugin/mybatis-generator-with-constructorBased-true.xml");
tool.generate(new AbstractShellCallback() {
@Override
public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) throws Exception {
// 1. 测试sql
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("andIdLessThan", 100l);
tbExample.set("orderByClause", "field1 asc");
ObjectUtil columnField1 = new ObjectUtil(loader, packagz + ".Tb$Column#tsF1");
// java 动态参数不能有两个会冲突,最后一个封装成Array!!!必须使用反射创建指定类型数组,不然调用invoke对了可变参数会检查类型!
Object columns1 = Array.newInstance(columnField1.getCls(), 1);
Array.set(columns1, 0, columnField1.getObject());
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(sql, "select field1 from tb WHERE ( id < '100' ) order by field1 asc");
ObjectUtil columnField2 = new ObjectUtil(loader, packagz + ".Tb$Column#field2");
Object columns2 = Array.newInstance(columnField1.getCls(), 2);
Array.set(columns2, 0, columnField1.getObject());
Array.set(columns2, 1, columnField2.getObject());
sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExampleSelective", tbExample.getObject(), columns2);
Assert.assertEquals(sql, "select field1 , field2 from tb WHERE ( id < '100' ) order by field1 asc");
// 2. 执行sql
List list = (List) tbMapper.invoke("selectByExampleSelective", tbExample.getObject(), columns1);
Assert.assertEquals(list.size(), 4);
int index = 0;
for (Object obj : list) {
if (index == 0) {
Assert.assertNull(obj);
} else {
ObjectUtil objectUtil = new ObjectUtil(obj);
// 没有查询这两个字段
if (objectUtil.get("id") != null || objectUtil.get("field2") != null) {
Assert.assertTrue(false);
}
if (index == 1) {
Assert.assertEquals(objectUtil.get("tsF1"), "fd1");
} else {
Assert.assertEquals(objectUtil.get("tsF1"), "fd3");
}
}
index++;
}
}
});
}
}
@@ -79,10 +79,10 @@ public class SelectiveEnhancedPluginTest {
Array.set(columns, 1, TbColumnTsIncF2.getObject());
tb.invoke("selective", columns);
Assert.assertTrue((Boolean) tb.invoke("isSelective"));
Assert.assertTrue((Boolean) tb.invoke("isSelective", "field_1"));
Assert.assertFalse((Boolean) tb.invoke("isSelective", "inc_f1"));
Assert.assertTrue((Boolean) tb.invoke("isSelective", "inc_f2"));
Assert.assertTrue((Boolean) tb.invoke("hasSelective"));
Assert.assertTrue((Boolean) tb.invoke("hasSelective", "field_1"));
Assert.assertFalse((Boolean) tb.invoke("hasSelective", "inc_f1"));
Assert.assertTrue((Boolean) tb.invoke("hasSelective", "inc_f2"));
}
});
}
@@ -67,7 +67,6 @@ public abstract class AbstractShellCallback implements ShellCallback {
/**
* 重载项目
*
* @param sqlSession
* @param loader
* @param packagz
@@ -92,7 +91,7 @@ public abstract class AbstractShellCallback implements ShellCallback {
}
StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(targetPackage, ".");
StringTokenizer st = new StringTokenizer(targetPackage, ".");
while (st.hasMoreTokens()) {
sb.append(st.nextToken());
sb.append(File.separatorChar);
@@ -112,6 +111,7 @@ public abstract class AbstractShellCallback implements ShellCallback {
/* (non-Javadoc)
* @see org.mybatis.generator.api.ShellCallback#isMergeSupported()
*/
@Override
public boolean isMergeSupported() {
return false;
}
@@ -119,6 +119,7 @@ public abstract class AbstractShellCallback implements ShellCallback {
/* (non-Javadoc)
* @see org.mybatis.generator.api.ShellCallback#isOverwriteEnabled()
*/
@Override
public boolean isOverwriteEnabled() {
return true;
}
@@ -126,9 +127,9 @@ public abstract class AbstractShellCallback implements ShellCallback {
/* (non-Javadoc)
* @see org.mybatis.generator.api.ShellCallback#mergeJavaFile(java.lang.String, java.lang.String, java.lang.String[], java.lang.String)
*/
public String mergeJavaFile(String newFileSource,
String existingFileFullPath, String[] javadocTags, String fileEncoding)
throws ShellException {
@Override
public String mergeJavaFile(String newFileSource, File existingFile,
String[] javadocTags, String fileEncoding) throws ShellException {
throw new UnsupportedOperationException();
}
}
-43
View File
@@ -1,43 +0,0 @@
<?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 configuration PUBLIC "-//mybatis.org//DTDSQL Map Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties" />
<settings>
<setting name="callSettersOnNulls" value="true"/>
</settings>
<!-- 配置环境,制定数据库连接信息 -->
<environments default="test">
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Mapper扫描包,必须同目录同名称下-->
<mapper resource="E:\work_java\mybatis-generator-plugin\target\test-tmp\123456\com\itfsw\mybatis\generator\plugins\dao\TbMapper.xml"/>
</mappers>
</configuration>
@@ -22,6 +22,7 @@ DROP TABLE IF EXISTS `tb`;
CREATE TABLE `tb` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1',
`del_flag` smallint(1) NOT NULL DEFAULT '0',
`and_logical_deleted` smallint(1) NOT NULL DEFAULT '0',
`ts_1` tinyint(1) DEFAULT NULL,
`ts_2` binary(255) DEFAULT NULL,
`ts_3` float DEFAULT NULL,
@@ -32,6 +33,7 @@ CREATE TABLE `tb` (
-- ----------------------------
-- Records of tb
-- ----------------------------
INSERT INTO `tb` VALUES ('1', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('2', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('3', '1', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('1', '0', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('2', '0', '1', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('3', '1', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('5', '0', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
@@ -0,0 +1,51 @@
<?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.LogicalDeletePlugin">
<property name="logicalDeleteColumn" value="and_logical_deleted"/>
<property name="logicalDeleteValue" value="1"/>
<property name="logicalUnDeleteValue" value="0"/>
</plugin>
<!--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"/>
</table>
</context>
</generatorConfiguration>
@@ -32,6 +32,7 @@ CREATE TABLE `tb` (
INSERT INTO `tb` VALUES ('1', 'fd1', null);
INSERT INTO `tb` VALUES ('2', null, '2');
INSERT INTO `tb` VALUES ('3', 'fd3', '3');
INSERT INTO `tb` VALUES ('4', 'fd3', '4');
-- ----------------------------
-- Table structure for tb_blobs
@@ -0,0 +1,58 @@
<?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">
<!-- 插件 -->
<!-- Select Selective插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.SelectSelectivePlugin"/>
<!-- 数据Model属性对应Column获取插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.ModelColumnPlugin"/>
<!-- 查询单条数据插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.SelectOneByExamplePlugin"/>
<!--jdbc的数据库连接 -->
<jdbcConnection driverClass="${driver}" connectionURL="${url}" userId="${username}" password="${password}" />
<!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径 -->
<javaModelGenerator targetPackage="" targetProject="">
<!-- 是否对model添加 构造函数 -->
<property name="constructorBased" value="false"/>
</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"/>
<columnOverride column="field1" property="tsF1"/>
</table>
</context>
</generatorConfiguration>
@@ -0,0 +1,58 @@
<?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">
<!-- 插件 -->
<!-- Select Selective插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.SelectSelectivePlugin"/>
<!-- 数据Model属性对应Column获取插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.ModelColumnPlugin"/>
<!-- 查询单条数据插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.SelectOneByExamplePlugin"/>
<!--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"/>
</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"/>
<columnOverride column="field1" property="tsF1"/>
</table>
</context>
</generatorConfiguration>