mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-11 00:02:22 +08:00
同步mybatis-plus 3.4.3代码,并升级mybatis-plus版本
This commit is contained in:
parent
ee22855046
commit
a466cfc066
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*;
|
|||||||
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.apache.ibatis.mapping.ResultMapping;
|
import org.apache.ibatis.mapping.ResultMapping;
|
||||||
import org.apache.ibatis.reflection.Reflector;
|
import org.apache.ibatis.reflection.Reflector;
|
||||||
@ -42,6 +43,10 @@ public class TableFieldInfo implements Constants {
|
|||||||
* 属性表达式#{property}, 可以指定jdbcType, typeHandler等
|
* 属性表达式#{property}, 可以指定jdbcType, typeHandler等
|
||||||
*/
|
*/
|
||||||
private final String el;
|
private final String el;
|
||||||
|
/**
|
||||||
|
* jdbcType, typeHandler等部分
|
||||||
|
*/
|
||||||
|
private final String mapping;
|
||||||
/**
|
/**
|
||||||
* 属性类型
|
* 属性类型
|
||||||
*/
|
*/
|
||||||
@ -140,6 +145,32 @@ public class TableFieldInfo implements Constants {
|
|||||||
*/
|
*/
|
||||||
private Class<? extends TypeHandler<?>> typeHandler;
|
private Class<? extends TypeHandler<?>> typeHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在OrderBy注解
|
||||||
|
*/
|
||||||
|
private boolean isOrderBy;
|
||||||
|
/**
|
||||||
|
* 排序类型
|
||||||
|
*/
|
||||||
|
private String orderByType;
|
||||||
|
/**
|
||||||
|
* 排序顺序
|
||||||
|
*/
|
||||||
|
private short orderBySort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全新的 存在 TableField 注解时使用的构造函数
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, TableField tableField,
|
||||||
|
Reflector reflector, boolean existTableLogic,boolean isOrderBy) {
|
||||||
|
this(dbConfig,tableInfo,field,tableField,reflector,existTableLogic);
|
||||||
|
this.isOrderBy = isOrderBy;
|
||||||
|
if(isOrderBy){
|
||||||
|
initOrderBy(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全新的 存在 TableField 注解时使用的构造函数
|
* 全新的 存在 TableField 注解时使用的构造函数
|
||||||
*/
|
*/
|
||||||
@ -163,7 +194,7 @@ public class TableFieldInfo implements Constants {
|
|||||||
String el = this.property;
|
String el = this.property;
|
||||||
if (JdbcType.UNDEFINED != jdbcType) {
|
if (JdbcType.UNDEFINED != jdbcType) {
|
||||||
this.jdbcType = jdbcType;
|
this.jdbcType = jdbcType;
|
||||||
el += (COMMA + "jdbcType=" + jdbcType.name());
|
el += (COMMA + SqlScriptUtils.mappingJdbcType(jdbcType));
|
||||||
}
|
}
|
||||||
if (UnknownTypeHandler.class != typeHandler) {
|
if (UnknownTypeHandler.class != typeHandler) {
|
||||||
this.typeHandler = (Class<? extends TypeHandler<?>>) typeHandler;
|
this.typeHandler = (Class<? extends TypeHandler<?>>) typeHandler;
|
||||||
@ -183,12 +214,14 @@ public class TableFieldInfo implements Constants {
|
|||||||
}
|
}
|
||||||
el += (COMMA + "javaType=" + javaType);
|
el += (COMMA + "javaType=" + javaType);
|
||||||
}
|
}
|
||||||
el += (COMMA + "typeHandler=" + typeHandler.getName());
|
el += (COMMA + SqlScriptUtils.mappingTypeHandler(this.typeHandler));
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(numericScale)) {
|
if (StringUtils.isNotBlank(numericScale)) {
|
||||||
el += (COMMA + "numericScale=" + numericScale);
|
el += (COMMA + SqlScriptUtils.mappingNumericScale(Integer.valueOf(numericScale)));
|
||||||
}
|
}
|
||||||
this.el = el;
|
this.el = el;
|
||||||
|
int index = el.indexOf(COMMA);
|
||||||
|
this.mapping = index > 0 ? el.substring(++index) : null;
|
||||||
this.initLogicDelete(dbConfig, field, existTableLogic);
|
this.initLogicDelete(dbConfig, field, existTableLogic);
|
||||||
|
|
||||||
String column = tableField.value();
|
String column = tableField.value();
|
||||||
@ -241,6 +274,17 @@ public class TableFieldInfo implements Constants {
|
|||||||
return fromAnnotation == FieldStrategy.DEFAULT ? fromDbConfig : fromAnnotation;
|
return fromAnnotation == FieldStrategy.DEFAULT ? fromDbConfig : fromAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不存在 TableField 注解时, 使用的构造函数
|
||||||
|
*/
|
||||||
|
public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, Reflector reflector,
|
||||||
|
boolean existTableLogic,boolean isOrderBy) {
|
||||||
|
this(dbConfig,tableInfo,field,reflector,existTableLogic);
|
||||||
|
this.isOrderBy = isOrderBy;
|
||||||
|
if(isOrderBy){
|
||||||
|
initOrderBy(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 不存在 TableField 注解时, 使用的构造函数
|
* 不存在 TableField 注解时, 使用的构造函数
|
||||||
*/
|
*/
|
||||||
@ -254,6 +298,7 @@ public class TableFieldInfo implements Constants {
|
|||||||
this.isPrimitive = this.propertyType.isPrimitive();
|
this.isPrimitive = this.propertyType.isPrimitive();
|
||||||
this.isCharSequence = StringUtils.isCharSequence(this.propertyType);
|
this.isCharSequence = StringUtils.isCharSequence(this.propertyType);
|
||||||
this.el = this.property;
|
this.el = this.property;
|
||||||
|
this.mapping = null;
|
||||||
this.insertStrategy = dbConfig.getInsertStrategy();
|
this.insertStrategy = dbConfig.getInsertStrategy();
|
||||||
this.updateStrategy = dbConfig.getUpdateStrategy();
|
this.updateStrategy = dbConfig.getUpdateStrategy();
|
||||||
this.whereStrategy = dbConfig.getSelectStrategy();
|
this.whereStrategy = dbConfig.getSelectStrategy();
|
||||||
@ -288,6 +333,21 @@ public class TableFieldInfo implements Constants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序初始化
|
||||||
|
* @param field 字段
|
||||||
|
*/
|
||||||
|
private void initOrderBy(Field field){
|
||||||
|
OrderBy orderBy = field.getAnnotation(OrderBy.class);
|
||||||
|
if (null != orderBy) {
|
||||||
|
this.isOrderBy = true;
|
||||||
|
this.orderBySort = orderBy.sort();
|
||||||
|
this.orderByType = orderBy.isDesc()?"desc":"asc";
|
||||||
|
}else{
|
||||||
|
this.isOrderBy = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 逻辑删除初始化
|
* 逻辑删除初始化
|
||||||
*
|
*
|
||||||
|
@ -13,6 +13,7 @@ import lombok.experimental.Accessors;
|
|||||||
import org.apache.ibatis.session.Configuration;
|
import org.apache.ibatis.session.Configuration;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -148,6 +149,13 @@ public class TableInfo implements Constants {
|
|||||||
@Setter(AccessLevel.NONE)
|
@Setter(AccessLevel.NONE)
|
||||||
private TableFieldInfo versionFieldInfo;
|
private TableFieldInfo versionFieldInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序列表
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public List<TableFieldInfo> orderByFields;
|
||||||
|
|
||||||
public TableInfo(Class<?> entityType) {
|
public TableInfo(Class<?> entityType) {
|
||||||
this.entityType = entityType;
|
this.entityType = entityType;
|
||||||
}
|
}
|
||||||
@ -198,6 +206,12 @@ public class TableInfo implements Constants {
|
|||||||
if (i.isWithUpdateFill()) {
|
if (i.isWithUpdateFill()) {
|
||||||
this.withUpdateFill = true;
|
this.withUpdateFill = true;
|
||||||
}
|
}
|
||||||
|
if (i.isOrderBy()) {
|
||||||
|
if (null == this.orderByFields) {
|
||||||
|
this.orderByFields = new LinkedList<>();
|
||||||
|
}
|
||||||
|
this.orderByFields.add(i);
|
||||||
|
}
|
||||||
if (i.isVersion()) {
|
if (i.isVersion()) {
|
||||||
this.withVersion = true;
|
this.withVersion = true;
|
||||||
this.versionFieldInfo = i;
|
this.versionFieldInfo = i;
|
||||||
|
@ -96,7 +96,7 @@ public class TableInfoHelper {
|
|||||||
tableInfo.setTableName(targetTableName);
|
tableInfo.setTableName(targetTableName);
|
||||||
|
|
||||||
/* 开启了自定义 KEY 生成器 */
|
/* 开启了自定义 KEY 生成器 */
|
||||||
if (null != dbConfig.getKeyGenerator()) {
|
if (CollectionUtils.isNotEmpty(dbConfig.getKeyGenerators())) {
|
||||||
tableInfo.setKeySequence(clazz.getAnnotation(KeySequence.class));
|
tableInfo.setKeySequence(clazz.getAnnotation(KeySequence.class));
|
||||||
}
|
}
|
||||||
return excludeProperty;
|
return excludeProperty;
|
||||||
@ -146,6 +146,8 @@ public class TableInfoHelper {
|
|||||||
boolean existTableId = isExistTableId(list);
|
boolean existTableId = isExistTableId(list);
|
||||||
// 是否存在 @TableLogic 注解
|
// 是否存在 @TableLogic 注解
|
||||||
boolean existTableLogic = isExistTableLogic(list);
|
boolean existTableLogic = isExistTableLogic(list);
|
||||||
|
// 是否存在 @OrderBy 注解
|
||||||
|
boolean existOrderBy = isExistOrderBy(list);
|
||||||
|
|
||||||
List<TableFieldInfo> fieldList = new ArrayList<>(list.size());
|
List<TableFieldInfo> fieldList = new ArrayList<>(list.size());
|
||||||
for (Field field : list) {
|
for (Field field : list) {
|
||||||
@ -175,12 +177,12 @@ public class TableInfoHelper {
|
|||||||
|
|
||||||
/* 有 @TableField 注解的字段初始化 */
|
/* 有 @TableField 注解的字段初始化 */
|
||||||
if (tableField != null) {
|
if (tableField != null) {
|
||||||
fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, tableField, reflector, existTableLogic));
|
fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, tableField, reflector, existTableLogic, existOrderBy));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 无 @TableField 注解的字段初始化 */
|
/* 无 @TableField 注解的字段初始化 */
|
||||||
fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, reflector, existTableLogic));
|
fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, reflector, existTableLogic, existOrderBy));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 字段列表 */
|
/* 字段列表 */
|
||||||
@ -216,6 +218,18 @@ public class TableInfoHelper {
|
|||||||
return list.stream().anyMatch(field -> field.isAnnotationPresent(TableLogic.class));
|
return list.stream().anyMatch(field -> field.isAnnotationPresent(TableLogic.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 判断排序注解是否存在
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param list 字段列表
|
||||||
|
* @return true 为存在 @TableId 注解;
|
||||||
|
*/
|
||||||
|
public static boolean isExistOrderBy(List<Field> list) {
|
||||||
|
return list.stream().anyMatch(field -> field.isAnnotationPresent(OrderBy.class));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 主键属性初始化
|
* 主键属性初始化
|
||||||
|
@ -1,29 +1,120 @@
|
|||||||
package com.github.yulichang.toolkit;
|
package com.github.yulichang.toolkit;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
|
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
import com.github.yulichang.exception.MPJException;
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.support.*;
|
||||||
import org.apache.ibatis.reflection.property.PropertyNamer;
|
import org.apache.ibatis.reflection.property.PropertyNamer;
|
||||||
|
|
||||||
|
import java.lang.invoke.SerializedLambda;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import static java.util.Locale.ENGLISH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yulichang
|
* copy {@link com.baomidou.mybatisplus.core.toolkit.LambdaUtils}
|
||||||
* @see com.baomidou.mybatisplus.core.toolkit.LambdaUtils
|
|
||||||
* @see org.apache.ibatis.reflection.property.PropertyNamer
|
|
||||||
*/
|
*/
|
||||||
public final class LambdaUtils {
|
public final class LambdaUtils {
|
||||||
|
|
||||||
/**
|
/* ******* 自定义方法 *********** */
|
||||||
* 获取属性名
|
|
||||||
*/
|
|
||||||
public static <T> String getName(SFunction<T, ?> fn) {
|
public static <T> String getName(SFunction<T, ?> fn) {
|
||||||
return PropertyNamer.methodToProperty(com.baomidou.mybatisplus.core.toolkit.LambdaUtils.resolve(fn).getImplMethodName());
|
return PropertyNamer.methodToProperty(extract(fn).getImplMethodName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> Class<T> getEntityClass(SFunction<T, ?> fn) {
|
public static <T> Class<T> getEntityClass(SFunction<T, ?> fn) {
|
||||||
return (Class<T>) com.baomidou.mybatisplus.core.toolkit.LambdaUtils.resolve(fn).getInstantiatedType();
|
return (Class<T>) extract(fn).getInstantiatedClass();
|
||||||
|
}
|
||||||
|
/* ******* 自定义方法 结束 以下代码均为拷贝 *********** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段映射
|
||||||
|
*/
|
||||||
|
private static final Map<String, Map<String, ColumnCache>> COLUMN_CACHE_MAP = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该缓存可能会在任意不定的时间被清除
|
||||||
|
*
|
||||||
|
* @param func 需要解析的 lambda 对象
|
||||||
|
* @param <T> 类型,被调用的 Function 对象的目标类型
|
||||||
|
* @return 返回解析后的结果
|
||||||
|
*/
|
||||||
|
public static <T> LambdaMeta extract(SFunction<T, ?> func) {
|
||||||
|
try {
|
||||||
|
Method method = func.getClass().getDeclaredMethod("writeReplace");
|
||||||
|
return new SerializedLambdaMeta((SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
if (func instanceof Proxy) return new ProxyLambdaMeta((Proxy) func);
|
||||||
|
String message = "Cannot find method writeReplace, please make sure that the lambda composite class is currently passed in";
|
||||||
|
throw new MybatisPlusException(message);
|
||||||
|
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||||
|
throw new MybatisPlusException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化 key 将传入的 key 变更为大写格式
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* Assert.assertEquals("USERID", formatKey("userId"))
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param key key
|
||||||
|
* @return 大写的 key
|
||||||
|
*/
|
||||||
|
public static String formatKey(String key) {
|
||||||
|
return key.toUpperCase(ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将传入的表信息加入缓存
|
||||||
|
*
|
||||||
|
* @param tableInfo 表信息
|
||||||
|
*/
|
||||||
|
public static void installCache(TableInfo tableInfo) {
|
||||||
|
COLUMN_CACHE_MAP.put(tableInfo.getEntityType().getName(), createColumnCacheMap(tableInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存实体字段 MAP 信息
|
||||||
|
*
|
||||||
|
* @param info 表信息
|
||||||
|
* @return 缓存 map
|
||||||
|
*/
|
||||||
|
private static Map<String, ColumnCache> createColumnCacheMap(TableInfo info) {
|
||||||
|
Map<String, ColumnCache> map;
|
||||||
|
|
||||||
|
if (info.havePK()) {
|
||||||
|
map = CollectionUtils.newHashMapWithExpectedSize(info.getFieldList().size() + 1);
|
||||||
|
map.put(formatKey(info.getKeyProperty()), new ColumnCache(info.getKeyColumn(), info.getKeySqlSelect()));
|
||||||
|
} else {
|
||||||
|
map = CollectionUtils.newHashMapWithExpectedSize(info.getFieldList().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
info.getFieldList().forEach(i ->
|
||||||
|
map.put(formatKey(i.getProperty()), new ColumnCache(i.getColumn(), i.getSqlSelect(), i.getMapping()))
|
||||||
|
);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实体对应字段 MAP
|
||||||
|
*
|
||||||
|
* @param clazz 实体类
|
||||||
|
* @return 缓存 map
|
||||||
|
*/
|
||||||
|
public static Map<String, ColumnCache> getColumnMap(Class<?> clazz) {
|
||||||
|
return CollectionUtils.computeIfAbsent(COLUMN_CACHE_MAP, clazz.getName(), key -> {
|
||||||
|
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
||||||
|
return info == null ? null : createColumnCacheMap(info);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -3,17 +3,18 @@ package com.github.yulichang.wrapper;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
|
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
|
||||||
import com.baomidou.mybatisplus.core.conditions.SharedString;
|
import com.baomidou.mybatisplus.core.conditions.SharedString;
|
||||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.interfaces.Join;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.interfaces.Nested;
|
import com.baomidou.mybatisplus.core.conditions.interfaces.Nested;
|
||||||
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
|
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
|
||||||
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
||||||
import com.baomidou.mybatisplus.core.enums.SqlLike;
|
import com.baomidou.mybatisplus.core.enums.SqlLike;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
|
import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
|
import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
import com.github.yulichang.wrapper.interfaces.Compare;
|
import com.github.yulichang.wrapper.interfaces.Compare;
|
||||||
import com.github.yulichang.wrapper.interfaces.Func;
|
import com.github.yulichang.wrapper.interfaces.Func;
|
||||||
|
import com.github.yulichang.wrapper.interfaces.Join;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -46,6 +47,11 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
*/
|
*/
|
||||||
protected AtomicInteger paramNameSeq;
|
protected AtomicInteger paramNameSeq;
|
||||||
protected Map<String, Object> paramNameValuePairs;
|
protected Map<String, Object> paramNameValuePairs;
|
||||||
|
/**
|
||||||
|
* 其他
|
||||||
|
*/
|
||||||
|
/* mybatis plus 3.4.3新增 这个时wrapper的别名 不是MPJ的别名 */
|
||||||
|
protected SharedString paramAlias;
|
||||||
protected SharedString lastSql;
|
protected SharedString lastSql;
|
||||||
/**
|
/**
|
||||||
* SQL注释
|
* SQL注释
|
||||||
@ -176,14 +182,14 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children between(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
|
public <X> Children between(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
|
||||||
return doIt(condition, () -> columnToString(column), BETWEEN, () -> formatSql("{0}", val1), AND,
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
|
||||||
() -> formatSql("{0}", val2));
|
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children notBetween(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
|
public <X> Children notBetween(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
|
||||||
return doIt(condition, () -> columnToString(column), NOT_BETWEEN, () -> formatSql("{0}", val1), AND,
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN,
|
||||||
() -> formatSql("{0}", val2));
|
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -208,12 +214,13 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Children or(boolean condition) {
|
public Children or(boolean condition) {
|
||||||
return doIt(condition, OR);
|
return maybeDo(condition, () -> appendSqlSegments(OR));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Children apply(boolean condition, String applySql, Object... value) {
|
public Children apply(boolean condition, String applySql, Object... values) {
|
||||||
return doIt(condition, APPLY, () -> formatSql(applySql, value));
|
return maybeDo(condition, () -> appendSqlSegments(APPLY,
|
||||||
|
() -> formatSqlMaybeWithParam(applySql, null, values)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -241,77 +248,101 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Children exists(boolean condition, String existsSql) {
|
public Children exists(boolean condition, String existsSql, Object... values) {
|
||||||
return doIt(condition, EXISTS, () -> String.format("(%s)", existsSql));
|
return maybeDo(condition, () -> appendSqlSegments(EXISTS,
|
||||||
|
() -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, null, values))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Children notExists(boolean condition, String existsSql) {
|
public Children notExists(boolean condition, String existsSql, Object... values) {
|
||||||
return not(condition).exists(condition, existsSql);
|
return not(condition).exists(condition, existsSql, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children isNull(boolean condition, SFunction<X, ?> column) {
|
public <X> Children isNull(boolean condition, SFunction<X, ?> column) {
|
||||||
return doIt(condition, () -> columnToString(column), IS_NULL);
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IS_NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children isNotNull(boolean condition, SFunction<X, ?> column) {
|
public <X> Children isNotNull(boolean condition, SFunction<X, ?> column) {
|
||||||
return doIt(condition, () -> columnToString(column), IS_NOT_NULL);
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IS_NOT_NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children in(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
|
public <X> Children in(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
|
||||||
return doIt(condition, () -> columnToString(column), IN, inExpression(coll));
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN, inExpression(coll)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> Children in(boolean condition, SFunction<X, ?> column, Object... values) {
|
||||||
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN, inExpression(values)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
|
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
|
||||||
return doIt(condition, () -> columnToString(column), NOT_IN, inExpression(coll));
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN, inExpression(coll)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Object... values) {
|
||||||
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN, inExpression(values)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children inSql(boolean condition, SFunction<X, ?> column, String inValue) {
|
public <X> Children inSql(boolean condition, SFunction<X, ?> column, String inValue) {
|
||||||
return doIt(condition, () -> columnToString(column), IN, () -> String.format("(%s)", inValue));
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN,
|
||||||
|
() -> String.format("(%s)", inValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children notInSql(boolean condition, SFunction<X, ?> column, String inValue) {
|
public <X> Children notInSql(boolean condition, SFunction<X, ?> column, String inValue) {
|
||||||
return doIt(condition, () -> columnToString(column), NOT_IN, () -> String.format("(%s)", inValue));
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN,
|
||||||
|
() -> String.format("(%s)", inValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children groupBy(boolean condition, SFunction<X, ?>... columns) {
|
public <X> Children groupBy(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns) {
|
||||||
if (ArrayUtils.isEmpty(columns)) {
|
return maybeDo(condition, () -> {
|
||||||
return typedThis;
|
String one = columnToString(column);
|
||||||
|
if (ArrayUtils.isNotEmpty(columns)) {
|
||||||
|
one += (StringPool.COMMA + columnsToString(columns));
|
||||||
}
|
}
|
||||||
return doIt(condition, GROUP_BY,
|
final String finalOne = one;
|
||||||
() -> columns.length == 1 ? columnToString(columns[0]) : columnsToString(columns));
|
appendSqlSegments(GROUP_BY, () -> finalOne);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> Children orderBy(boolean condition, boolean isAsc, SFunction<X, ?>... columns) {
|
public <X> Children orderBy(boolean condition, boolean isAsc, SFunction<X, ?> column, SFunction<X, ?>... columns) {
|
||||||
if (ArrayUtils.isEmpty(columns)) {
|
return maybeDo(condition, () -> {
|
||||||
return typedThis;
|
final SqlKeyword mode = isAsc ? ASC : DESC;
|
||||||
|
appendSqlSegments(ORDER_BY, columnToSqlSegment(column), mode);
|
||||||
|
if (ArrayUtils.isNotEmpty(columns)) {
|
||||||
|
Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
|
||||||
|
columnToSqlSegment(columnSqlInjectFilter(c)), mode));
|
||||||
}
|
}
|
||||||
SqlKeyword mode = isAsc ? ASC : DESC;
|
});
|
||||||
for (SFunction<X, ?> column : columns) {
|
|
||||||
doIt(condition, ORDER_BY, () -> columnToString(column), mode);
|
|
||||||
}
|
}
|
||||||
return typedThis;
|
|
||||||
|
/**
|
||||||
|
* 字段 SQL 注入过滤处理,子类重写实现过滤逻辑
|
||||||
|
*
|
||||||
|
* @param column 字段内容
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected <X> SFunction<X, ?> columnSqlInjectFilter(SFunction<X, ?> column) {
|
||||||
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Children having(boolean condition, String sqlHaving, Object... params) {
|
public Children having(boolean condition, String sqlHaving, Object... params) {
|
||||||
return doIt(condition, HAVING, () -> formatSqlIfNeed(condition, sqlHaving, params));
|
return maybeDo(condition, () -> appendSqlSegments(HAVING,
|
||||||
|
() -> formatSqlMaybeWithParam(sqlHaving, null, params)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Children func(boolean condition, Consumer<Children> consumer) {
|
public Children func(boolean condition, Consumer<Children> consumer) {
|
||||||
if (condition) {
|
return maybeDo(condition, () -> consumer.accept(typedThis));
|
||||||
consumer.accept(typedThis);
|
|
||||||
}
|
|
||||||
return typedThis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,7 +350,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
* <p>NOT 关键词</p>
|
* <p>NOT 关键词</p>
|
||||||
*/
|
*/
|
||||||
protected Children not(boolean condition) {
|
protected Children not(boolean condition) {
|
||||||
return doIt(condition, NOT);
|
return maybeDo(condition, () -> appendSqlSegments(NOT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,7 +358,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
* <p>拼接 AND</p>
|
* <p>拼接 AND</p>
|
||||||
*/
|
*/
|
||||||
protected Children and(boolean condition) {
|
protected Children and(boolean condition) {
|
||||||
return doIt(condition, AND);
|
return maybeDo(condition, () -> appendSqlSegments(AND));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -335,7 +366,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
* <p>拼接 LIKE 以及 值</p>
|
* <p>拼接 LIKE 以及 值</p>
|
||||||
*/
|
*/
|
||||||
protected <X> Children likeValue(boolean condition, SqlKeyword keyword, SFunction<X, ?> column, Object val, SqlLike sqlLike) {
|
protected <X> Children likeValue(boolean condition, SqlKeyword keyword, SFunction<X, ?> column, Object val, SqlLike sqlLike) {
|
||||||
return doIt(condition, () -> columnToString(column), keyword, () -> formatSql("{0}", SqlUtils.concatLike(val, sqlLike)));
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), keyword,
|
||||||
|
() -> formatParam(null, SqlUtils.concatLike(val, sqlLike))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -347,7 +379,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
* @param val 条件值
|
* @param val 条件值
|
||||||
*/
|
*/
|
||||||
protected <X> Children addCondition(boolean condition, SFunction<X, ?> column, SqlKeyword sqlKeyword, Object val) {
|
protected <X> Children addCondition(boolean condition, SFunction<X, ?> column, SqlKeyword sqlKeyword, Object val) {
|
||||||
return doIt(condition, () -> columnToString(column), sqlKeyword, () -> formatSql("{0}", val));
|
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword,
|
||||||
|
() -> formatParam(null, val)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -356,12 +389,11 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
* @param condition 查询条件值
|
* @param condition 查询条件值
|
||||||
*/
|
*/
|
||||||
protected Children addNestedCondition(boolean condition, Consumer<Children> consumer) {
|
protected Children addNestedCondition(boolean condition, Consumer<Children> consumer) {
|
||||||
if (condition) {
|
return maybeDo(condition, () -> {
|
||||||
final Children instance = instance();
|
final Children instance = instance();
|
||||||
consumer.accept(instance);
|
consumer.accept(instance);
|
||||||
return doIt(true, APPLY, instance);
|
appendSqlSegments(APPLY, instance);
|
||||||
}
|
});
|
||||||
return typedThis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -370,56 +402,80 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
protected abstract Children instance();
|
protected abstract Children instance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化SQL
|
* 格式化 sql
|
||||||
*
|
|
||||||
* @param sqlStr SQL语句部分
|
|
||||||
* @param params 参数集
|
|
||||||
* @return sql
|
|
||||||
*/
|
|
||||||
protected final String formatSql(String sqlStr, Object... params) {
|
|
||||||
return formatSqlIfNeed(true, sqlStr, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
* <p>
|
||||||
* 根据需要格式化SQL<br>
|
* 支持 "{0}" 这种,或者 "sql {0} sql" 这种
|
||||||
* <br>
|
|
||||||
* Format SQL for methods: EntityQ<T>.where/and/or...("name={0}", value);
|
|
||||||
* ALL the {<b>i</b>} will be replaced with #{MPGENVAL<b>i</b>}<br>
|
|
||||||
* <br>
|
|
||||||
* ew.where("sample_name=<b>{0}</b>", "haha").and("sample_age ><b>{0}</b>
|
|
||||||
* and sample_age<<b>{1}</b>", 18, 30) <b>TO</b>
|
|
||||||
* sample_name=<b>#{MPGENVAL1}</b> and sample_age>#<b>{MPGENVAL2}</b> and
|
|
||||||
* sample_age<<b>#{MPGENVAL3}</b><br>
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @param need 是否需要格式化
|
* @param sqlStr 可能是sql片段
|
||||||
* @param sqlStr SQL语句部分
|
* @param mapping 例如: "javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler" 这种
|
||||||
* @param params 参数集
|
* @param params 参数
|
||||||
* @return sql
|
* @return sql片段
|
||||||
*/
|
*/
|
||||||
protected final String formatSqlIfNeed(boolean need, String sqlStr, Object... params) {
|
protected final String formatSqlMaybeWithParam(String sqlStr, String mapping, Object... params) {
|
||||||
if (!need || StringUtils.isBlank(sqlStr)) {
|
if (StringUtils.isBlank(sqlStr)) {
|
||||||
|
// todo 何时会这样?
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (ArrayUtils.isNotEmpty(params)) {
|
if (ArrayUtils.isNotEmpty(params)) {
|
||||||
for (int i = 0; i < params.length; ++i) {
|
for (int i = 0; i < params.length; ++i) {
|
||||||
String genParamName = Constants.WRAPPER_PARAM + paramNameSeq.incrementAndGet();
|
final String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE;
|
||||||
sqlStr = sqlStr.replace(String.format("{%s}", i),
|
sqlStr = sqlStr.replace(target, formatParam(mapping, params[i]));
|
||||||
String.format(Constants.WRAPPER_PARAM_FORMAT, Constants.WRAPPER, genParamName));
|
|
||||||
paramNameValuePairs.put(genParamName, params[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sqlStr;
|
return sqlStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理入参
|
||||||
|
*
|
||||||
|
* @param mapping 例如: "javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler" 这种
|
||||||
|
* @param param 参数
|
||||||
|
* @return value
|
||||||
|
*/
|
||||||
|
protected final String formatParam(String mapping, Object param) {
|
||||||
|
final String genParamName = Constants.WRAPPER_PARAM + paramNameSeq.incrementAndGet();
|
||||||
|
final String paramStr = getParamAlias() + Constants.WRAPPER_PARAM_MIDDLE + genParamName;
|
||||||
|
paramNameValuePairs.put(genParamName, param);
|
||||||
|
return SqlScriptUtils.safeParam(paramStr, mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 函数化的做事
|
||||||
|
*
|
||||||
|
* @param condition 做不做
|
||||||
|
* @param something 做什么
|
||||||
|
* @return Children
|
||||||
|
*/
|
||||||
|
protected final Children maybeDo(boolean condition, DoSomething something) {
|
||||||
|
if (condition) {
|
||||||
|
something.doIt();
|
||||||
|
}
|
||||||
|
return typedThis;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取in表达式 包含括号
|
* 获取in表达式 包含括号
|
||||||
*
|
*
|
||||||
* @param value 集合
|
* @param value 集合
|
||||||
*/
|
*/
|
||||||
private ISqlSegment inExpression(Collection<?> value) {
|
protected ISqlSegment inExpression(Collection<?> value) {
|
||||||
return () -> value.stream().map(i -> formatSql("{0}", i))
|
if (CollectionUtils.isEmpty(value)) {
|
||||||
|
return () -> "()";
|
||||||
|
}
|
||||||
|
return () -> value.stream().map(i -> formatParam(null, i))
|
||||||
|
.collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取in表达式 包含括号
|
||||||
|
*
|
||||||
|
* @param values 数组
|
||||||
|
*/
|
||||||
|
protected ISqlSegment inExpression(Object[] values) {
|
||||||
|
if (ArrayUtils.isEmpty(values)) {
|
||||||
|
return () -> "()";
|
||||||
|
}
|
||||||
|
return () -> Arrays.stream(values).map(i -> formatParam(null, i))
|
||||||
.collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET));
|
.collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,18 +503,13 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对sql片段进行组装
|
* 添加 where 片段
|
||||||
*
|
*
|
||||||
* @param condition 是否执行
|
* @param sqlSegments ISqlSegment 数组
|
||||||
* @param sqlSegments sql片段数组
|
|
||||||
* @return children
|
|
||||||
*/
|
*/
|
||||||
protected Children doIt(boolean condition, ISqlSegment... sqlSegments) {
|
protected void appendSqlSegments(ISqlSegment... sqlSegments) {
|
||||||
if (condition) {
|
|
||||||
expression.add(sqlSegments);
|
expression.add(sqlSegments);
|
||||||
}
|
}
|
||||||
return typedThis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSqlSegment() {
|
public String getSqlSegment() {
|
||||||
@ -490,6 +541,31 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
return paramNameValuePairs;
|
return paramNameValuePairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getParamAlias() {
|
||||||
|
return paramAlias == null ? Constants.WRAPPER : paramAlias.getStringValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数别名设置,初始化时优先设置该值、重复设置异常
|
||||||
|
*
|
||||||
|
* @param paramAlias 参数别名
|
||||||
|
* @return Children
|
||||||
|
*/
|
||||||
|
public Children setParamAlias(String paramAlias) {
|
||||||
|
Assert.notEmpty(paramAlias, "paramAlias can not be empty!");
|
||||||
|
Assert.isEmpty(paramNameValuePairs, "Please call this method before working!");
|
||||||
|
Assert.isNull(this.paramAlias, "Please do not call the method repeatedly!");
|
||||||
|
this.paramAlias = new SharedString(paramAlias);
|
||||||
|
return typedThis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 columnName
|
||||||
|
*/
|
||||||
|
protected final <X> ISqlSegment columnToSqlSegment(SFunction<X, ?> column) {
|
||||||
|
return () -> columnToString(column);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 columnName
|
* 获取 columnName
|
||||||
*/
|
*/
|
||||||
@ -511,4 +587,13 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
public Children clone() {
|
public Children clone() {
|
||||||
return SerializationUtils.clone(typedThis);
|
return SerializationUtils.clone(typedThis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 做事函数
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface DoSomething {
|
||||||
|
|
||||||
|
void doIt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
public final <S> MPJLambdaWrapper<T> select(SFunction<S, ?>... columns) {
|
public final <S> MPJLambdaWrapper<T> select(SFunction<S, ?>... columns) {
|
||||||
if (ArrayUtils.isNotEmpty(columns)) {
|
if (ArrayUtils.isNotEmpty(columns)) {
|
||||||
for (SFunction<S, ?> s : columns) {
|
for (SFunction<S, ?> s : columns) {
|
||||||
selectColumns.add(new SelectColumn(LambdaUtils.getEntityClass(s), getCache(s).getColumn(), null));
|
selectColumns.add(new SelectColumn(com.github.yulichang.toolkit.LambdaUtils.getEntityClass(s), getCache(s).getColumn(), null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return typedThis;
|
return typedThis;
|
||||||
@ -113,14 +113,14 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final <S, X> MPJLambdaWrapper<T> selectAs(SFunction<S, ?> columns, SFunction<X, ?> alias) {
|
public final <S, X> MPJLambdaWrapper<T> selectAs(SFunction<S, ?> columns, SFunction<X, ?> alias) {
|
||||||
return selectAs(columns, LambdaUtils.getName(alias));
|
return selectAs(columns, com.github.yulichang.toolkit.LambdaUtils.getName(alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 1.1.3
|
* @since 1.1.3
|
||||||
*/
|
*/
|
||||||
public final <S, X> MPJLambdaWrapper<T> selectAs(SFunction<S, ?> columns, String alias) {
|
public final <S, X> MPJLambdaWrapper<T> selectAs(SFunction<S, ?> columns, String alias) {
|
||||||
selectColumns.add(new SelectColumn(LambdaUtils.getEntityClass(columns), getCache(columns).getColumn(), alias));
|
selectColumns.add(new SelectColumn(com.github.yulichang.toolkit.LambdaUtils.getEntityClass(columns), getCache(columns).getColumn(), alias));
|
||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
public final <S> MPJLambdaWrapper<T> selectIgnore(SFunction<S, ?>... columns) {
|
public final <S> MPJLambdaWrapper<T> selectIgnore(SFunction<S, ?>... columns) {
|
||||||
if (ArrayUtils.isNotEmpty(columns)) {
|
if (ArrayUtils.isNotEmpty(columns)) {
|
||||||
for (SFunction<S, ?> s : columns) {
|
for (SFunction<S, ?> s : columns) {
|
||||||
ignoreColumns.add(new SelectColumn(LambdaUtils.getEntityClass(s), getCache(s).getColumn(), null));
|
ignoreColumns.add(new SelectColumn(com.github.yulichang.toolkit.LambdaUtils.getEntityClass(s), getCache(s).getColumn(), null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return typedThis;
|
return typedThis;
|
||||||
|
@ -3,13 +3,9 @@ package com.github.yulichang.wrapper.interfaces;
|
|||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将原来的泛型R改成SFunction<R, ?>
|
* 将原来的泛型R改成SFunction<R, ?>
|
||||||
* <p>
|
* <p>
|
||||||
@ -63,6 +59,7 @@ public interface Func<Children> extends Serializable {
|
|||||||
* 字段 IN (value.get(0), value.get(1), ...)
|
* 字段 IN (value.get(0), value.get(1), ...)
|
||||||
* <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
|
* <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
|
||||||
*
|
*
|
||||||
|
* <li> 注意!集合为空若存在逻辑错误,请在 condition 条件中判断 </li>
|
||||||
* <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
|
* <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
|
||||||
*
|
*
|
||||||
* @param condition 执行条件
|
* @param condition 执行条件
|
||||||
@ -83,6 +80,7 @@ public interface Func<Children> extends Serializable {
|
|||||||
* 字段 IN (v0, v1, ...)
|
* 字段 IN (v0, v1, ...)
|
||||||
* <p>例: in("id", 1, 2, 3, 4, 5)</p>
|
* <p>例: in("id", 1, 2, 3, 4, 5)</p>
|
||||||
*
|
*
|
||||||
|
* <li> 注意!数组为空若存在逻辑错误,请在 condition 条件中判断 </li>
|
||||||
* <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
|
* <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
|
||||||
*
|
*
|
||||||
* @param condition 执行条件
|
* @param condition 执行条件
|
||||||
@ -90,10 +88,7 @@ public interface Func<Children> extends Serializable {
|
|||||||
* @param values 数据数组
|
* @param values 数据数组
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
default <R> Children in(boolean condition, SFunction<R, ?> column, Object... values) {
|
<R> Children in(boolean condition, SFunction<R, ?> column, Object... values);
|
||||||
return in(condition, column, Arrays.stream(Optional.ofNullable(values).orElseGet(() -> new Object[]{}))
|
|
||||||
.collect(toList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
@ -129,10 +124,7 @@ public interface Func<Children> extends Serializable {
|
|||||||
* @param values 数据数组
|
* @param values 数据数组
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
default <R> Children notIn(boolean condition, SFunction<R, ?> column, Object... values) {
|
<R> Children notIn(boolean condition, SFunction<R, ?> column, Object... values);
|
||||||
return notIn(condition, column, Arrays.stream(Optional.ofNullable(values).orElseGet(() -> new Object[]{}))
|
|
||||||
.collect(toList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
@ -177,15 +169,8 @@ public interface Func<Children> extends Serializable {
|
|||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
*/
|
*/
|
||||||
default <R> Children groupBy(SFunction<R, ?> column) {
|
default <R> Children groupBy(SFunction<R, ?> column, SFunction<R, ?>... columns) {
|
||||||
return groupBy(true, column);
|
return groupBy(true, column, columns);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ignore
|
|
||||||
*/
|
|
||||||
default <R> Children groupBy(SFunction<R, ?>... columns) {
|
|
||||||
return groupBy(true, columns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,23 +178,17 @@ public interface Func<Children> extends Serializable {
|
|||||||
* <p>例: groupBy("id", "name")</p>
|
* <p>例: groupBy("id", "name")</p>
|
||||||
*
|
*
|
||||||
* @param condition 执行条件
|
* @param condition 执行条件
|
||||||
|
* @param column 单个字段
|
||||||
* @param columns 字段数组
|
* @param columns 字段数组
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
<R> Children groupBy(boolean condition, SFunction<R, ?>... columns);
|
<R> Children groupBy(boolean condition, SFunction<R, ?> column, SFunction<R, ?>... columns);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
*/
|
*/
|
||||||
default <R> Children orderByAsc(SFunction<R, ?> column) {
|
default <R> Children orderByAsc(SFunction<R, ?> column, SFunction<R, ?>... columns) {
|
||||||
return orderByAsc(true, column);
|
return orderByAsc(true, column, columns);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ignore
|
|
||||||
*/
|
|
||||||
default <R> Children orderByAsc(SFunction<R, ?>... columns) {
|
|
||||||
return orderByAsc(true, columns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,25 +196,19 @@ public interface Func<Children> extends Serializable {
|
|||||||
* <p>例: orderByAsc("id", "name")</p>
|
* <p>例: orderByAsc("id", "name")</p>
|
||||||
*
|
*
|
||||||
* @param condition 执行条件
|
* @param condition 执行条件
|
||||||
|
* @param column 单个字段
|
||||||
* @param columns 字段数组
|
* @param columns 字段数组
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
default <R> Children orderByAsc(boolean condition, SFunction<R, ?>... columns) {
|
default <R> Children orderByAsc(boolean condition, SFunction<R, ?> column, SFunction<R, ?>... columns) {
|
||||||
return orderBy(condition, true, columns);
|
return orderBy(condition, true, column, columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
*/
|
*/
|
||||||
default <R> Children orderByDesc(SFunction<R, ?> column) {
|
default <R> Children orderByDesc(SFunction<R, ?> column, SFunction<R, ?>... columns) {
|
||||||
return orderByDesc(true, column);
|
return orderByDesc(true, column, columns);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ignore
|
|
||||||
*/
|
|
||||||
default <R> Children orderByDesc(SFunction<R, ?>... columns) {
|
|
||||||
return orderByDesc(true, columns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -243,11 +216,12 @@ public interface Func<Children> extends Serializable {
|
|||||||
* <p>例: orderByDesc("id", "name")</p>
|
* <p>例: orderByDesc("id", "name")</p>
|
||||||
*
|
*
|
||||||
* @param condition 执行条件
|
* @param condition 执行条件
|
||||||
|
* @param column 单个字段
|
||||||
* @param columns 字段数组
|
* @param columns 字段数组
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
default <R> Children orderByDesc(boolean condition, SFunction<R, ?>... columns) {
|
default <R> Children orderByDesc(boolean condition, SFunction<R, ?> column, SFunction<R, ?>... columns) {
|
||||||
return orderBy(condition, false, columns);
|
return orderBy(condition, false, column, columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,10 +230,11 @@ public interface Func<Children> extends Serializable {
|
|||||||
*
|
*
|
||||||
* @param condition 执行条件
|
* @param condition 执行条件
|
||||||
* @param isAsc 是否是 ASC 排序
|
* @param isAsc 是否是 ASC 排序
|
||||||
|
* @param column 单个字段
|
||||||
* @param columns 字段数组
|
* @param columns 字段数组
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
<R> Children orderBy(boolean condition, boolean isAsc, SFunction<R, ?>... columns);
|
<R> Children orderBy(boolean condition, boolean isAsc, SFunction<R, ?> column, SFunction<R, ?>... columns);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
|
136
src/main/java/com/github/yulichang/wrapper/interfaces/Join.java
Normal file
136
src/main/java/com/github/yulichang/wrapper/interfaces/Join.java
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
package com.github.yulichang.wrapper.interfaces;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy {@link com.baomidou.mybatisplus.core.conditions.interfaces.Join}
|
||||||
|
* <p>
|
||||||
|
* 无改动 在mybatis 3.4.2 升级 3.4.3 后有改动 exists 和 not exists
|
||||||
|
* 为了保证 mybatis plus 3.4.3之前的也能正常使用
|
||||||
|
*/
|
||||||
|
public interface Join<Children> extends Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ignore
|
||||||
|
*/
|
||||||
|
default Children or() {
|
||||||
|
return or(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接 OR
|
||||||
|
*
|
||||||
|
* @param condition 执行条件
|
||||||
|
* @return children
|
||||||
|
*/
|
||||||
|
Children or(boolean condition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ignore
|
||||||
|
*/
|
||||||
|
default Children apply(String applySql, Object... values) {
|
||||||
|
return apply(true, applySql, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接 sql
|
||||||
|
* <p>!! 会有 sql 注入风险 !!</p>
|
||||||
|
* <p>例1: apply("id = 1")</p>
|
||||||
|
* <p>例2: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")</p>
|
||||||
|
* <p>例3: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", LocalDate.now())</p>
|
||||||
|
*
|
||||||
|
* @param condition 执行条件
|
||||||
|
* @param values 数据数组
|
||||||
|
* @return children
|
||||||
|
*/
|
||||||
|
Children apply(boolean condition, String applySql, Object... values);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ignore
|
||||||
|
*/
|
||||||
|
default Children last(String lastSql) {
|
||||||
|
return last(true, lastSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无视优化规则直接拼接到 sql 的最后(有sql注入的风险,请谨慎使用)
|
||||||
|
* <p>例: last("limit 1")</p>
|
||||||
|
* <p>注意只能调用一次,多次调用以最后一次为准</p>
|
||||||
|
*
|
||||||
|
* @param condition 执行条件
|
||||||
|
* @param lastSql sql语句
|
||||||
|
* @return children
|
||||||
|
*/
|
||||||
|
Children last(boolean condition, String lastSql);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ignore
|
||||||
|
*/
|
||||||
|
default Children comment(String comment) {
|
||||||
|
return comment(true, comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sql 注释(会拼接在 sql 的最后面)
|
||||||
|
*
|
||||||
|
* @param condition 执行条件
|
||||||
|
* @param comment sql注释
|
||||||
|
* @return children
|
||||||
|
*/
|
||||||
|
Children comment(boolean condition, String comment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ignore
|
||||||
|
*/
|
||||||
|
default Children first(String firstSql) {
|
||||||
|
return first(true, firstSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sql 起始句(会拼接在SQL语句的起始处)
|
||||||
|
*
|
||||||
|
* @param condition 执行条件
|
||||||
|
* @param firstSql 起始语句
|
||||||
|
* @return children
|
||||||
|
* @since 3.3.1
|
||||||
|
*/
|
||||||
|
Children first(boolean condition, String firstSql);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ignore
|
||||||
|
*/
|
||||||
|
default Children exists(String existsSql, Object... values) {
|
||||||
|
return exists(true, existsSql, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接 EXISTS ( sql语句 )
|
||||||
|
* <p>!! sql 注入方法 !!</p>
|
||||||
|
* <p>例: exists("select id from table where age = 1")</p>
|
||||||
|
*
|
||||||
|
* @param condition 执行条件
|
||||||
|
* @param existsSql sql语句
|
||||||
|
* @param values 数据数组
|
||||||
|
* @return children
|
||||||
|
*/
|
||||||
|
Children exists(boolean condition, String existsSql, Object... values);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ignore
|
||||||
|
*/
|
||||||
|
default Children notExists(String existsSql, Object... values) {
|
||||||
|
return notExists(true, existsSql, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接 NOT EXISTS ( sql语句 )
|
||||||
|
* <p>!! sql 注入方法 !!</p>
|
||||||
|
* <p>例: notExists("select id from table where age = 1")</p>
|
||||||
|
*
|
||||||
|
* @param condition 执行条件
|
||||||
|
* @param existsSql sql语句
|
||||||
|
* @param values 数据数组
|
||||||
|
* @return children
|
||||||
|
*/
|
||||||
|
Children notExists(boolean condition, String existsSql, Object... values);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user