cn.com.gpic.ini.common.util.wrapper.WrapperUtils Maven / Gradle / Ivy
The newest version!
package cn.com.gpic.ini.common.util.wrapper;
import cn.com.gpic.ini.common.util.wrapper.condition.annotations.*;
import cn.com.gpic.ini.common.util.wrapper.condition.domain.SqlLogical;
import cn.com.gpic.ini.common.util.wrapper.condition.domain.SqlSymbol;
import cn.com.gpic.ini.common.util.wrapper.condition.util.ClassUtils;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.AbstractChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.ibatis.reflection.property.PropertyNamer;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class WrapperUtils {
private static final Field PARAM_NAME_SEQ_FIELD;
private static FieldStrategy whereStrategy;
private static boolean mapUnderscoreToCamelCase;
private static boolean capitalMode;
private static String columnFormat;
private static String logicNotDeleteValue;
private WrapperUtils() {
throw new AssertionError();
}
public static QueryWrapper query() {
return Wrappers.query();
}
public static UpdateWrapper update() {
return Wrappers.update();
}
public static QueryWrapper query(@Nullable Object parameters) {
return query(parameters, Wrappers.query());
}
public static QueryWrapper query(@Nullable Object parameters, Class entityClass) {
QueryWrapper wrapper = query(parameters, Wrappers.query());
wrapper.setEntityClass(entityClass);
return wrapper;
}
public static UpdateWrapper update(@Nullable Object parameters) {
return update(parameters, Wrappers.update());
}
public static QueryWrapper query(@Nullable Object parameters, @Nonnull QueryWrapper wrapper) {
return (QueryWrapper) buildWrapper(parameters, (AbstractWrapper) wrapper);
}
public static UpdateWrapper update(@Nullable Object parameters, @Nonnull UpdateWrapper wrapper) {
return (UpdateWrapper) buildWrapper(parameters, (AbstractWrapper) wrapper);
}
public static QueryChainWrapper query(@Nullable Object parameters, @Nonnull QueryChainWrapper wrapper) {
return (QueryChainWrapper) buildWrapper(parameters, (AbstractChainWrapper) wrapper);
}
public static UpdateChainWrapper update(@Nullable Object parameters, @Nonnull UpdateChainWrapper wrapper) {
return (UpdateChainWrapper) buildWrapper(parameters, (AbstractChainWrapper) wrapper);
}
public static > Children buildWrapper(@Nullable Object parameters, @Nonnull AbstractWrapper wrapper) {
if (!Objects.isNull(parameters) && !ClassUtils.isSimpleProperty(parameters.getClass())) {
if (parameters instanceof Map) {
return (Children) buildWrapperByMap((Map) parameters, wrapper);
} else {
return !ClassUtils.isCollectionType(parameters.getClass()) && ClassUtils.isNormalClass(parameters.getClass()) ? buildWrapperByJavaBean(parameters, wrapper) : (Children) wrapper;
}
} else {
return (Children) wrapper;
}
}
public static , Param extends AbstractWrapper> Children buildWrapper(@Nullable Object parameters, @Nonnull AbstractChainWrapper wrapper) {
buildWrapper(parameters, wrapper.getWrapper());
return (Children) wrapper;
}
public static > Children buildWrapperByMap(@Nullable Map parameters, @Nonnull AbstractWrapper wrapper) {
return MapUtil.isEmpty(parameters) ? (Children) wrapper : wrapper.allEq(parameters);
}
public static > Children buildWrapperByJavaBean(@Nullable Object parameters, @Nonnull AbstractWrapper wrapper) {
if (!Objects.isNull(parameters)) {
Class> javaBeanType = parameters.getClass();
PropertyDescriptor[] descriptors = BeanUtil.getPropertyDescriptors(javaBeanType);
Map orderByMap = new HashMap<>();
for (PropertyDescriptor descriptor : descriptors) {
Method readMethod = descriptor.getReadMethod();
Method writeMethod = descriptor.getWriteMethod();
if (!Objects.isNull(readMethod) && !readMethod.getDeclaringClass().isAssignableFrom(Object.class)) {
ReflectionUtils.makeAccessible(readMethod);
getFieldAnnotation(javaBeanType, readMethod, writeMethod, SqlOrderBy.class).ifPresent(orderBy -> {
String column = StrUtil.isNotEmpty(orderBy.column()) ? getColumn(orderBy.column(), true) :
getFieldAnnotation(javaBeanType, readMethod, writeMethod, TableField.class).map(WrapperUtils::getColumn)
.orElse(Optional.ofNullable(getColumn(descriptor.getName(), true)).orElse(descriptor.getName()));
orderByMap.put(orderBy, column);
});
Object value = ReflectionUtils.invokeMethod(readMethod, parameters);
if (!Objects.isNull(value)) {
Optional tableFieldOptional = getFieldAnnotation(javaBeanType, readMethod, writeMethod, TableField.class);
if (validFieldStrategy(tableFieldOptional.map(TableField::whereStrategy).orElseGet(WrapperUtils::getWhereStrategy), value)) {
I18n i18n = getFieldAnnotation(javaBeanType, readMethod, writeMethod, I18n.class).orElse(null);
Optional sqlConditionOptional = getFieldAnnotation(javaBeanType, readMethod, writeMethod, SqlCondition.class);
SqlSymbol sqlSymbol = sqlConditionOptional.map(SqlCondition::symbol).orElse(SqlSymbol.EQ);
SqlLogical sqlLogical = sqlConditionOptional.map(SqlCondition::columnLogical).orElse(SqlLogical.OR);
boolean keepColumn = Objects.equals(sqlSymbol, SqlSymbol.EXISTS) || Objects.equals(sqlSymbol, SqlSymbol.NOT_EXISTS);
String[] columns = sqlConditionOptional.map((sqlCondition) -> keepColumn ? sqlCondition.columns() : getColumn(sqlCondition.columns()))
.orElseGet(() -> new String[]{tableFieldOptional.map(WrapperUtils::getColumn).orElseGet(() -> Optional.ofNullable(getColumn(descriptor.getName(), true)).orElse(descriptor.getName()))});
int columnLength = columns.length;
if (columnLength == 1) {
addCondition(wrapper, sqlSymbol, columns[0], value, i18n);
} else {
boolean logicalIsAnd = SqlLogical.AND.equals(sqlLogical);
wrapper.and((children) -> {
IntStream.range(0, columnLength).forEach((i) -> {
if (logicalIsAnd) {
children.and((and) -> addCondition(and, sqlSymbol, columns[i], value, i18n));
} else {
children.or((or) -> addCondition(or, sqlSymbol, columns[i], value, i18n));
}
});
});
}
}
}
}
}
if (CollUtil.isNotEmpty(orderByMap.keySet())) {
orderByMap.keySet().stream().sorted(Comparator.comparing(SqlOrderBy::sortNum))
.forEachOrdered(order -> wrapper.orderBy(true, order.isAsc(), orderByMap.get(order)));
}
}
return (Children) wrapper;
}
public static > void addCondition(@Nonnull AbstractWrapper wrapper, @Nonnull SqlSymbol sqlSymbol, @Nonnull String column, @Nullable Object value, I18n i18n) {
if (Objects.isNull(i18n)) {
sqlSymbol.getValue().accept(wrapper, column, value);
} else {
addI18nCondition(wrapper, sqlSymbol, column, value, i18n.value());
}
}
public static > void addI18nCondition(@Nonnull AbstractWrapper wrapper, @Nonnull SqlSymbol sqlSymbol, @Nonnull String column, @Nullable Object value, @Nullable String basename) {
QueryWrapper