This commit is contained in:
yulichang 2022-12-06 18:29:11 +08:00
parent 078cc77857
commit 8254727e18
14 changed files with 639 additions and 404 deletions

View File

@ -1,6 +1,5 @@
package com.github.yulichang.interceptor;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.*;
@ -10,10 +9,11 @@ import com.github.yulichang.method.MPJResultType;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.support.SelectColumn;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.github.yulichang.wrapper.resultmap.MybatisLabel;
import com.github.yulichang.wrapper.resultmap.Result;
import com.github.yulichang.wrapper.segments.Select;
import com.github.yulichang.wrapper.segments.SelectLabel;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
@ -28,9 +28,6 @@ import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.ibatis.type.UnknownTypeHandler;
import java.lang.reflect.Field;
import java.util.*;
@ -174,62 +171,31 @@ public class MPJInterceptor implements Interceptor {
}
MPJLambdaWrapper wrapper = (MPJLambdaWrapper) obj;
Map<String, Field> fieldMap = ReflectionKit.getFieldMap(resultType);
List<SelectColumn> columnList = wrapper.getSelectColumns();
List<Select> columnList = wrapper.getSelectColumns();
//移除对多查询列为了可重复使用wrapper
columnList.removeIf(SelectColumn::isLabel);
List<ResultMapping> resultMappings = new ArrayList<>(columnList.size());
for (SelectColumn i : columnList) {
TableFieldInfo info = i.getTableFieldInfo();
if (StringUtils.isNotBlank(i.getAlias())) {
//优先别名查询 selectFunc selectAs
Class<?> aliasField = fieldMap.containsKey(i.getAlias()) ? fieldMap.get(i.getAlias()).getType() : null;
if (aliasField == null) {
continue;
for (Select s : columnList) {
System.out.println(s);
}
columnList.removeIf(Select::isLabel);
List<ResultMapping> resultMappings = new ArrayList<>();
for (Select i : columnList) {
if (i.isHasAlias()) {
Field field = fieldMap.get(i.getAlias());
if (Objects.nonNull(field)) {
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), i.getAlias(),
i.getAlias(), aliasField);
if (i.getFuncEnum() == null || StringUtils.isBlank(i.getFuncEnum().getSql())) {
Field f = fieldMap.get(i.getAlias());
if (f == null) {
continue;
}
if (info != null && info.getTypeHandler() != null && info.getTypeHandler() != UnknownTypeHandler.class) {
if (f.getType() == info.getField().getType()) {
builder.typeHandler(getTypeHandler(ms, info));
}
}
}
resultMappings.add(builder.build());
} else if (info != null) {
// select selectAll selectAsClass
if (i.getFuncEnum() == null || StringUtils.isBlank(i.getFuncEnum().getSql())) {
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), info.getProperty(),
StringUtils.getTargetColumn(info.getColumn()), info.getPropertyType());
Field f = fieldMap.get(info.getProperty());
if (f == null) {
continue;
}
if (f.getType() == info.getField().getType()) {
if (info.getTypeHandler() != null && info.getTypeHandler() != UnknownTypeHandler.class) {
builder.typeHandler(getTypeHandler(ms, info));
}
}
builder.javaType(f.getType());
resultMappings.add(builder.build());
} else {
resultMappings.add(new ResultMapping.Builder(ms.getConfiguration(), info.getProperty(),
StringUtils.getTargetColumn(info.getColumn()), info.getPropertyType()).build());
i.getAlias(), field.getType());
resultMappings.add(selectToResult(wrapper.getEntityClass(), i, field.getType(), builder));
}
} else {
// 主键列
resultMappings.add(new ResultMapping.Builder(ms.getConfiguration(), i.getTagProperty(),
StringUtils.getTargetColumn(i.getColumnName()), i.getKeyType())
.flags(Collections.singletonList(ResultFlag.ID)).build());
Field field = fieldMap.get(i.getColumProperty());
if (Objects.nonNull(field)) {
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), i.getColumProperty(),
i.getTagColumn(), field.getType());
resultMappings.add(selectToResult(wrapper.getEntityClass(), i, field.getType(), builder));
}
}
}
Set<String> columnSet = resultMappings.stream().map(ResultMapping::getColumn).collect(Collectors.toSet());
//移除result中不存在的标签
resultMappings.removeIf(i -> !fieldMap.containsKey(i.getProperty()));
if (wrapper.isResultMap()) {
for (Object o : wrapper.getResultMapMybatisLabel()) {
MybatisLabel<?, ?> label = (MybatisLabel<?, ?>) o;
@ -240,6 +206,16 @@ public class MPJInterceptor implements Interceptor {
return result;
}
private ResultMapping selectToResult(Class<?> entity, Select select, Class<?> type, ResultMapping.Builder builder) {
if (select.hasTypeHandle() && select.getTableFieldInfo().getPropertyType().isAssignableFrom(type)) {
builder.typeHandler(select.getTypeHandle());
}
if (select.isPk() && entity == select.getClazz()) {
builder.flags(Collections.singletonList(ResultFlag.ID));
}
return builder.build();
}
//fix 重上往下会有resultMap覆盖问题,应该从根节点开始,id向上传递
@ -247,40 +223,56 @@ public class MPJInterceptor implements Interceptor {
* @return 返回节点id
*/
private ResultMapping buildResult(MappedStatement ms, MybatisLabel<?, ?> mybatisLabel, Set<String> columnSet,
List<SelectColumn> columnList) {
List<Select> columnList) {
List<Result> resultList = mybatisLabel.getResultList();
if (CollectionUtils.isEmpty(resultList)) {
return null;
}
StringBuilder childId = new StringBuilder("MPJ_")
.append(mybatisLabel.getEntityClass().getName())
.append(StringPool.UNDERSCORE)
.append(mybatisLabel.getOfType().getName())
.append(StringPool.UNDERSCORE);
List<ResultMapping> childMapping = new ArrayList<>(resultList.size());
for (Result r : resultList) {
String columnName = r.getColumn();
childId.append("(");
Map<String, Field> ofTypeField = MPJReflectionKit.getFieldMap(mybatisLabel.getOfType());
//列名去重
columnName = getColumn(columnSet, StringUtils.getTargetColumn(columnName));
columnList.add(SelectColumn.of(mybatisLabel.getEntityClass(), r.getColumn(), null,
Objects.equals(columnName, r.getColumn()) ? null : columnName, null, null, true, null));
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), r.getProperty(),
StringUtils.getTargetColumn(columnName), r.getJavaType());
String columnName = StringUtils.getTargetColumn(r.getSelectNormal().getColumn());
SelectLabel label;
Field field = ofTypeField.get(r.getProperty());
if (columnSet.contains(columnName)) {
columnName = getColumn(columnSet, columnName);
label = new SelectLabel(r.getSelectNormal(), mybatisLabel.getOfType(), field, columnName);
} else {
label = new SelectLabel(r.getSelectNormal(), mybatisLabel.getOfType(), field);
}
columnList.add(label);
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), r.getProperty(), columnName, r.getJavaType());
if (r.isId()) {//主键标记为id标签
builder.flags(Collections.singletonList(ResultFlag.ID));
childId.append(ResultFlag.ID);
} else {
childId.append(ResultFlag.CONSTRUCTOR);
}
//TypeHandle
TableFieldInfo info = r.getTableFieldInfo();
if (info != null && info.getTypeHandler() != null && info.getTypeHandler() != UnknownTypeHandler.class) {
builder.typeHandler(getTypeHandler(ms, info));
if (label.hasTypeHandle() && label.getColumnType().isAssignableFrom(field.getType())) {
builder.typeHandler(label.getTypeHandle());
}
if (Objects.nonNull(r.getJdbcType())) {
builder.jdbcType(r.getJdbcType());
}
childMapping.add(builder.build());
childId.append(StringPool.DASH)
.append(columnName)
.append(StringPool.DASH)
.append(r.getProperty())
.append(")");
}
String childId;
if (CollectionUtils.isEmpty(mybatisLabel.getMybatisLabels())) {
childId = "MPJ_" + mybatisLabel.getEntityClass().getName() + StringPool.UNDERSCORE + mybatisLabel.getOfType().getName() +
StringPool.UNDERSCORE + childMapping.stream().map(i -> "(" + (CollectionUtils.isEmpty(i.getFlags()) ?
ResultFlag.CONSTRUCTOR : i.getFlags().get(0)) + "-" + i.getProperty() + "-" + i.getColumn() + ")")
.collect(Collectors.joining(StringPool.DASH));
} else {
if (CollectionUtils.isNotEmpty(mybatisLabel.getMybatisLabels())) {
//递归调用
StringBuilder sb = new StringBuilder("MPJ_[");
childId.append("[");
for (MybatisLabel<?, ?> o : mybatisLabel.getMybatisLabels()) {
if (Objects.isNull(o)) {
continue;
@ -290,42 +282,23 @@ public class MPJInterceptor implements Interceptor {
continue;
}
childMapping.add(result);
sb.append(result.getNestedResultMapId());
sb.append("@");
childId.append(result.getNestedResultMapId());
childId.append("@");
}
sb.append("]");
sb.append("_MPJ_")
.append(mybatisLabel.getEntityClass().getName())
.append(StringPool.UNDERSCORE)
.append(mybatisLabel.getOfType().getName())
.append(StringPool.UNDERSCORE);
childId = sb + childMapping.stream().map(i -> "(" + (CollectionUtils.isEmpty(i.getFlags()) ?
ResultFlag.CONSTRUCTOR : i.getFlags().get(0)) + "-" + i.getProperty() + "-" + i.getColumn() + ")")
.collect(Collectors.joining(StringPool.DASH));
childId.append("]");
}
//双检
if (!ms.getConfiguration().hasResultMap(childId)) {
ResultMap build = new ResultMap.Builder(ms.getConfiguration(), childId, mybatisLabel.getOfType(), childMapping).build();
MPJInterceptor.addResultMap(ms, childId, build);
String id = childId.toString();
if (!ms.getConfiguration().hasResultMap(id)) {
ResultMap build = new ResultMap.Builder(ms.getConfiguration(), id, mybatisLabel.getOfType(), childMapping).build();
MPJInterceptor.addResultMap(ms, id, build);
}
return new ResultMapping.Builder(ms.getConfiguration(), mybatisLabel.getProperty())
.javaType(mybatisLabel.getJavaType())
.nestedResultMapId(childId)
.nestedResultMapId(id)
.build();
}
/**
* 获取字段typeHandle
*/
private TypeHandler<?> getTypeHandler(MappedStatement ms, TableFieldInfo info) {
TypeHandlerRegistry registry = ms.getConfiguration().getTypeHandlerRegistry();
TypeHandler<?> typeHandler = registry.getMappingTypeHandler(info.getTypeHandler());
if (typeHandler == null) {
typeHandler = registry.getInstance(info.getPropertyType(), info.getTypeHandler());
}
return typeHandler;
}
/**
* 列名去重 重复的添加 mpj 前缀 再重复走递归
*
@ -334,11 +307,11 @@ public class MPJInterceptor implements Interceptor {
* @return 唯一列名
*/
private String getColumn(Set<String> pool, String columnName) {
columnName = "join_" + columnName;
if (!pool.contains(columnName)) {
pool.add(columnName);
return columnName;
}
columnName = "join_" + columnName;
return getColumn(pool, columnName);
}

View File

@ -1,9 +1,6 @@
package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.support.*;
import org.apache.ibatis.reflection.property.PropertyNamer;
@ -12,9 +9,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.Locale.ENGLISH;
/**
* copy {@link com.baomidou.mybatisplus.core.toolkit.LambdaUtils}
@ -22,7 +16,6 @@ import static java.util.Locale.ENGLISH;
@SuppressWarnings("unused")
public final class LambdaUtils {
/* ******* 自定义方法 *********** */
public static <T> String getName(SFunction<T, ?> fn) {
LambdaMeta extract = extract(fn);
String name = PropertyNamer.methodToProperty(extract.getImplMethodName());
@ -42,10 +35,6 @@ public final class LambdaUtils {
public static <T> Class<T> getEntityClass(SFunction<T, ?> fn) {
return (Class<T>) extract(fn).getInstantiatedClass();
}
/* ******* 自定义方法 结束 以下代码均为拷贝 *********** */
private static final Map<String, Map<String, ColumnCache>> COLUMN_CACHE_MAP = new ConcurrentHashMap<>();
/**
* 该缓存可能会在任意不定的时间被清除
@ -68,63 +57,4 @@ public final class LambdaUtils {
return new ShadowLambdaMeta(SerializedLambda.extract(func));
}
}
/**
* 格式化 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(),
null, info.getKeyProperty(), true, info.getKeyType()));
} else {
map = CollectionUtils.newHashMapWithExpectedSize(info.getFieldList().size());
}
info.getFieldList().forEach(i ->
map.put(formatKey(i.getProperty()), new ColumnCache(i.getColumn(), i.getSqlSelect(), i, null, false, null))
);
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);
});
}
}

View File

@ -1,45 +1,43 @@
package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import lombok.Getter;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.github.yulichang.wrapper.segments.SelectNormal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 缓存添加tableInfo信息
* select缓存
*
* @author yulichang
* @see com.baomidou.mybatisplus.core.toolkit.support.ColumnCache
* @since 1.3.0
* @since 1.3.10
*/
public class ColumnCache extends com.baomidou.mybatisplus.core.toolkit.support.ColumnCache {
public class ColumnCache {
@Getter
private TableFieldInfo tableFieldInfo;
private static final Map<Class<?>, List<SelectNormal>> LIST_CACHE = new ConcurrentHashMap<>();
@Getter
private String keyProperty;
private static final Map<Class<?>, Map<String, SelectNormal>> MAP_CACHE = new ConcurrentHashMap<>();
@Getter
private boolean isPK;
@Getter
private Class<?> keyType;
@Deprecated
public ColumnCache(String column, String columnSelect) {
super(column, columnSelect);
public static List<SelectNormal> getListField(Class<?> clazz) {
return LIST_CACHE.computeIfAbsent(clazz, c -> {
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
Assert.notNull(tableInfo, "table not find by class <%s>", c.getSimpleName());
List<SelectNormal> list = new ArrayList<>();
if (tableInfo.havePK()) {
list.add(new SelectNormal(clazz, true, tableInfo.getKeyColumn(), tableInfo.getKeyType(), tableInfo.getKeyProperty(), null));
}
list.addAll(tableInfo.getFieldList().stream().map(f -> new SelectNormal(clazz, false, f.getColumn(), f.getPropertyType(), f.getProperty(), f)).collect(Collectors.toList()));
return list;
});
}
@Deprecated
public ColumnCache(String column, String columnSelect, String mapping) {
super(column, columnSelect, mapping);
}
public ColumnCache(String column, String columnSelect, TableFieldInfo tableFieldInfo, String keyProperty, boolean isPK, Class<?> keyType) {
super(column, columnSelect);
this.tableFieldInfo = tableFieldInfo;
this.keyProperty = keyProperty;
this.isPK = isPK;
this.keyType = keyType;
public static Map<String, SelectNormal> getMapField(Class<?> clazz) {
return MAP_CACHE.computeIfAbsent(clazz, c -> getListField(c).stream().collect(Collectors.toMap(SelectNormal::getColumProperty, Function.identity(), (i, j) -> j)));
}
}

View File

@ -1,76 +0,0 @@
package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import lombok.Getter;
/**
* MPJLambdaWrapper 查询字段
*
* @author yulichang
* @since 1.3.0
*/
@Getter
public class SelectColumn {
/**
* 字段实体类
*/
private final Class<?> clazz;
/**
* 数据库字段名
*/
private final String columnName;
/**
* 字段信息
*/
private final TableFieldInfo tableFieldInfo;
/**
* 字段别名
*/
private final String alias;
/**
* 目标属性
*/
private final String tagProperty;
/**
* 主键类型
*/
private final Class<?> keyType;
/**
* 是否是对多的列
*/
private final boolean label;
/**
* 字段函数
*/
private final BaseFuncEnum funcEnum;
private SelectColumn(Class<?> clazz, String columnName, TableFieldInfo tableFieldInfo, String alias,
String tagProperty, Class<?> keyType, boolean label, BaseFuncEnum funcEnum) {
this.clazz = clazz;
this.columnName = columnName;
this.tableFieldInfo = tableFieldInfo;
this.alias = alias;
this.tagProperty = tagProperty;
this.keyType = keyType;
this.label = label;
this.funcEnum = funcEnum;
}
public static SelectColumn of(Class<?> clazz, String columnName, TableFieldInfo tableFieldInfo, String alias,
String tagProperty, Class<?> keyType, boolean label, BaseFuncEnum funcEnum) {
if (tagProperty != null)
tagProperty = StringUtils.getTargetColumn(tagProperty);
return new SelectColumn(clazz, columnName, tableFieldInfo, alias, tagProperty, keyType, label, funcEnum);
}
}

View File

@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.support.ColumnCache;
import lombok.Getter;
import com.github.yulichang.wrapper.segments.SelectNormal;
import java.util.Arrays;
import java.util.HashMap;
@ -27,11 +27,6 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
*/
protected Map<Class<?>, Integer> subTable = new HashMap<>();
/**
* 缓存字段
*/
protected Map<Class<?>, Map<String, ColumnCache>> columnMap = new HashMap<>();
@Override
protected <X> String columnToString(X column, boolean isJoin) {
return columnToString((SFunction<?, ?>) column, isJoin);
@ -46,17 +41,13 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
protected String columnToString(SFunction<?, ?> column, boolean isJoin) {
Class<?> entityClass = LambdaUtils.getEntityClass(column);
return Constant.TABLE_ALIAS + getDefault(entityClass, isJoin) + StringPool.DOT +
getCache(column).getColumn();
getCache(column).getTagColumn();
}
protected ColumnCache getCache(SFunction<?, ?> fn) {
protected SelectNormal getCache(SFunction<?, ?> fn) {
Class<?> aClass = LambdaUtils.getEntityClass(fn);
Map<String, ColumnCache> cacheMap = columnMap.get(aClass);
if (cacheMap == null) {
cacheMap = LambdaUtils.getColumnMap(aClass);
columnMap.put(aClass, cacheMap);
}
return cacheMap.get(LambdaUtils.formatKey(LambdaUtils.getName(fn)));
Map<String, SelectNormal> cacheMap = ColumnCache.getMapField(aClass);
return cacheMap.get(LambdaUtils.getName(fn));
}
protected String getDefault(Class<?> clazz, boolean isJoin) {

View File

@ -9,16 +9,18 @@ import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.ReflectionKit;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.SelectColumn;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import com.github.yulichang.wrapper.interfaces.LambdaJoin;
import com.github.yulichang.wrapper.interfaces.Query;
import com.github.yulichang.wrapper.interfaces.on.OnFunction;
import com.github.yulichang.wrapper.resultmap.MFunc;
import com.github.yulichang.wrapper.resultmap.MybatisLabel;
import com.github.yulichang.wrapper.segments.Select;
import com.github.yulichang.wrapper.segments.SelectAlias;
import com.github.yulichang.wrapper.segments.SelectFunc;
import com.github.yulichang.wrapper.segments.SelectNormal;
import lombok.Getter;
import java.lang.reflect.Field;
@ -53,7 +55,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
* 查询的字段
*/
@Getter
private final List<SelectColumn> selectColumns = new ArrayList<>();
private final List<Select> selectColumns = new ArrayList<>();
/**
* 映射关系
*/
@ -139,10 +141,8 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
public final <S> MPJLambdaWrapper<T> select(SFunction<S, ?>... columns) {
if (ArrayUtils.isNotEmpty(columns)) {
for (SFunction<S, ?> s : columns) {
ColumnCache cache = getCache(s);
selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(s), cache.getColumn(), cache.getTableFieldInfo(),
null, cache.getTableFieldInfo() == null ? cache.getKeyProperty() : cache.getTableFieldInfo().getProperty(),
cache.getKeyType(), false, null));
SelectNormal cache = getCache(s);
selectColumns.add(cache);
}
}
return typedThis;
@ -275,59 +275,43 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
@Override
public <E> MPJLambdaWrapper<T> select(Class<E> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
Assert.notNull(info, "table not find by class <%s>", entityClass.getName());
Map<String, SelectNormal> cacheMap = ColumnCache.getMapField(entityClass);
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(
i -> selectColumns.add(SelectColumn.of(entityClass, i.getColumn(), i, null, i.getProperty(), null, false, null)));
i -> selectColumns.add(cacheMap.get(i.getProperty())));
return typedThis;
}
@Override
public <E> MPJLambdaWrapper<T> selectAsClass(Class<E> source, Class<?> tag) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(source);
Assert.notNull(tableInfo, "table not find by class <%s>", source.getName());
List<Field> tagFields = ReflectionKit.getFieldList(tag);
tableInfo.getFieldList().forEach(i -> {
if (tagFields.stream().anyMatch(f -> f.getName().equals(i.getProperty()))) {
selectColumns.add(SelectColumn.of(source, i.getColumn(), i, null, i.getProperty(), null, false, null));
List<SelectNormal> normalList = ColumnCache.getListField(source);
Map<String, Field> fieldMap = MPJReflectionKit.getFieldMap(tag);
for (SelectNormal cache : normalList) {
if (fieldMap.containsKey(cache.getColumProperty())) {
selectColumns.add(cache);
}
});
if (tableInfo.havePK() && tagFields.stream().anyMatch(i -> i.getName().equals(tableInfo.getKeyProperty()))) {
selectColumns.add(SelectColumn.of(source, tableInfo.getKeyColumn(), null, null,
tableInfo.getKeyProperty(), tableInfo.getKeyType(), false, null));
}
return typedThis;
}
@Override
public <S> MPJLambdaWrapper<T> selectAs(SFunction<S, ?> column, String alias) {
ColumnCache cache = getCache(column);
selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(column), cache.getColumn(), cache.getTableFieldInfo(),
alias, null, cache.getKeyType(), false, null));
selectColumns.add(new SelectAlias(getCache(column), alias));
return typedThis;
}
public <S> MPJLambdaWrapper<T> selectFunc(BaseFuncEnum funcEnum, SFunction<S, ?> column, String alias) {
ColumnCache cache = getCache(column);
selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(column), cache.getColumn(),
cache.getTableFieldInfo(), alias, alias, cache.getKeyType(), false, funcEnum));
selectColumns.add(new SelectFunc(getCache(column), alias, funcEnum));
return typedThis;
}
@Override
public MPJLambdaWrapper<T> selectFunc(BaseFuncEnum funcEnum, Object column, String alias) {
selectColumns.add(SelectColumn.of(null, column.toString(), null, alias, alias, null, false, funcEnum));
selectColumns.add(new SelectFunc(alias, funcEnum, column.toString()));
return typedThis;
}
public final MPJLambdaWrapper<T> selectAll(Class<?> clazz) {
TableInfo info = TableInfoHelper.getTableInfo(clazz);
Assert.notNull(info, "table can not be find -> %s", clazz);
if (info.havePK()) {
selectColumns.add(SelectColumn.of(clazz, info.getKeyColumn(), null, null,
info.getKeyProperty(), info.getKeyType(), false, null));
}
info.getFieldList().forEach(c ->
selectColumns.add(SelectColumn.of(clazz, c.getColumn(), c, null, c.getProperty(), null, false, null)));
selectColumns.addAll(ColumnCache.getListField(clazz));
return typedThis;
}
@ -338,9 +322,8 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
public String getSqlSelect() {
if (StringUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumns)) {
String s = selectColumns.stream().map(i -> {
String str = Constant.TABLE_ALIAS + getDefaultSelect(i.getClazz(), (i.getClazz() == getEntityClass() && !i.isLabel())) + StringPool.DOT + i.getColumnName();
return (i.getFuncEnum() == null ? str : String.format(i.getFuncEnum().getSql(), str)) +
(StringUtils.isBlank(i.getAlias()) ? StringPool.EMPTY : (Constant.AS + i.getAlias()));
String str = Constant.TABLE_ALIAS + getDefaultSelect(i.getClazz(), (i.getClazz() == getEntityClass() && !i.isLabel())) + StringPool.DOT + i.getColumn();
return i.isFunc() ? (String.format(i.getFunc().getSql(), str) + Constant.AS + i.getAlias()) : (i.isHasAlias() ? (str + Constant.AS + i.getAlias()) : str);
}).collect(Collectors.joining(StringPool.COMMA));
sqlSelect.setStringValue(s);
}

View File

@ -1,6 +1,5 @@
package com.github.yulichang.wrapper.resultmap;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
@ -8,14 +7,12 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.segments.SelectNormal;
import lombok.Getter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -178,7 +175,7 @@ public class MybatisLabel<E, T> {
return this;
}
public boolean hasCustom(){
public boolean hasCustom() {
return CollectionUtils.isNotEmpty(mybatisLabel.resultList) || CollectionUtils.isNotEmpty(mybatisLabel.mybatisLabels);
}
@ -193,39 +190,31 @@ public class MybatisLabel<E, T> {
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
Map<String, Field> tagMap = MPJReflectionKit.getFieldMap(tagClass);
if (auto && !tagMap.isEmpty()) {
Function<TableFieldInfo, Result> build = field -> {
List<SelectNormal> listField = ColumnCache.getListField(entityClass);
if (entityClass.isAssignableFrom(tagClass)) {
mybatisLabel.resultList.addAll(listField.stream().map(i -> {
Result result = new Result();
result.setId(false);
result.setTableFieldInfo(field);
result.setColumn(field.getColumn());
result.setProperty(field.getProperty());
result.setJavaType(field.getField().getType());
result.setJdbcType(field.getJdbcType());
result.setTypeHandle(field.getTypeHandler());
result.setId(i.isPk());
result.setProperty(i.getColumProperty());
result.setJavaType(i.getColumnType());
result.setJdbcType(Objects.isNull(i.getTableFieldInfo()) ? null : i.getTableFieldInfo().getJdbcType());
result.setSelectNormal(i);
return result;
};
if (entityClass == tagClass) {
if (tableInfo.havePK()) {
mybatisLabel.resultList.add(pkBuild(tableInfo));
}
mybatisLabel.resultList.addAll(tableInfo.getFieldList().stream().map(build).collect(Collectors.toList()));
}).collect(Collectors.toList()));
} else {
if (tableInfo.havePK() && tagMap.containsKey(tableInfo.getKeyProperty())) {
mybatisLabel.resultList.add(pkBuild(tableInfo));
}
mybatisLabel.resultList.addAll(tableInfo.getFieldList().stream().filter(i ->
tagMap.containsKey(i.getProperty())).map(build).collect(Collectors.toList()));
}
}
}
private Result pkBuild(TableInfo tableInfo) {
for (SelectNormal s : listField) {
Field field = tagMap.get(s.getColumProperty());
if (Objects.nonNull(field)) {
Result result = new Result();
result.setId(true);
result.setColumn(tableInfo.getKeyColumn());
result.setProperty(tableInfo.getKeyProperty());
result.setJavaType(tableInfo.getKeyType());
return result;
result.setId(s.isPk());
result.setProperty(s.getColumProperty());
result.setJavaType(field.getType());
result.setSelectNormal(s);
mybatisLabel.resultList.add(result);
}
}
}
}
}
}
}

View File

@ -1,17 +1,17 @@
package com.github.yulichang.wrapper.resultmap;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.segments.SelectNormal;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.util.Map;
import java.util.Objects;
/**
* result 标签
@ -25,18 +25,14 @@ public class Result {
private boolean isId;
private SelectNormal selectNormal;
private String property;
private String column;
private TableFieldInfo tableFieldInfo;
private Class<?> javaType;
private JdbcType jdbcType;
private Class<? extends TypeHandler<?>> typeHandle;
public Result() {
}
@ -58,26 +54,18 @@ public class Result {
public Builder<E, T> column(SFunction<E, ?> column) {
Class<E> entityClass = LambdaUtils.getEntityClass(column);
Map<String, SelectNormal> normalMap = ColumnCache.getMapField(entityClass);
String name = LambdaUtils.getName(column);
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
Assert.notNull(tableInfo, "table not find by class <%s>", tableInfo);
if (tableInfo.havePK() && tableInfo.getKeyProperty().equals(name)) {
result.column = tableInfo.getKeyColumn();
SelectNormal normal = normalMap.get(name);
result.selectNormal = normal;
if (StringUtils.isBlank(result.property)) {
result.property = tableInfo.getKeyProperty();
result.property = normal.getColumProperty();
}
result.javaType = tableInfo.getKeyType();
} else {
TableFieldInfo fieldInfo = tableInfo.getFieldList().stream().filter(i -> i.getField().getName().equals(name)).findFirst().orElse(null);
Assert.notNull(fieldInfo, "table <%s> not find column <%>", tableInfo.getTableName(), name);
result.column = fieldInfo.getColumn();
result.tableFieldInfo = fieldInfo;
if (StringUtils.isBlank(result.property)) {
result.property = fieldInfo.getProperty();
if (Objects.isNull(result.javaType)) {
result.javaType = normal.getColumnType();
}
result.jdbcType = fieldInfo.getJdbcType();
result.javaType = fieldInfo.getField().getType();
result.typeHandle = fieldInfo.getTypeHandler();
if (Objects.isNull(result.jdbcType)) {
result.jdbcType = Objects.isNull(normal.getTableFieldInfo()) ? null : normal.getTableFieldInfo().getJdbcType();
}
return this;
}

View File

@ -0,0 +1,42 @@
package com.github.yulichang.wrapper.segments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import org.apache.ibatis.type.TypeHandler;
/**
* 查询列
*
* @author yulichang
* @since 1.3.10
*/
public interface Select {
Class<?> getClazz();
boolean isPk();
String getColumn();
Class<?> getColumnType();
String getTagColumn();
String getColumProperty();
boolean hasTypeHandle();
TypeHandler<?> getTypeHandle();
boolean isHasAlias();
String getAlias();
TableFieldInfo getTableFieldInfo();
boolean isFunc();
BaseFuncEnum getFunc();
boolean isLabel();
}

View File

@ -0,0 +1,91 @@
package com.github.yulichang.wrapper.segments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import lombok.Getter;
import org.apache.ibatis.type.TypeHandler;
/**
* 别名列
*
* @author yulichang
* @since 1.3.10
*/
@Getter
public class SelectAlias implements Select {
private final SelectNormal selectNormal;
private final boolean hasAlias;
private final String alias;
public SelectAlias(SelectNormal selectNormal, String alias) {
this.selectNormal = selectNormal;
this.hasAlias = true;
this.alias = alias;
}
@Override
public Class<?> getClazz() {
return selectNormal.getClazz();
}
@Override
public boolean isPk() {
return selectNormal.isPk();
}
@Override
public String getColumn() {
return selectNormal.getColumn();
}
@Override
public Class<?> getColumnType() {
return selectNormal.getColumnType();
}
@Override
public String getTagColumn() {
return selectNormal.getTagColumn();
}
@Override
public String getColumProperty() {
return selectNormal.getColumProperty();
}
@Override
public boolean hasTypeHandle() {
return selectNormal.hasTypeHandle();
}
@Override
public TypeHandler<?> getTypeHandle() {
return selectNormal.getTypeHandle();
}
@Override
public TableFieldInfo getTableFieldInfo() {
return selectNormal.getTableFieldInfo();
}
@Override
public boolean isFunc() {
return false;
}
@Override
public BaseFuncEnum getFunc() {
return null;
}
@Override
public boolean isLabel() {
return false;
}
}

View File

@ -0,0 +1,101 @@
package com.github.yulichang.wrapper.segments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import lombok.Getter;
import org.apache.ibatis.type.TypeHandler;
import java.util.Objects;
/**
* 自定义函数列
*
* @author yulichang
* @since 1.3.10
*/
@Getter
public class SelectFunc implements Select {
private final SelectNormal selectNormal;
private final String coloum;
private final boolean hasAlias;
private final String alias;
private final boolean isFunc;
private final BaseFuncEnum func;
public SelectFunc(SelectNormal selectNormal, String alias, BaseFuncEnum func) {
this.selectNormal = selectNormal;
this.coloum = selectNormal.getColumn();
this.hasAlias = true;
this.alias = alias;
this.isFunc = true;
this.func = func;
}
public SelectFunc(String alias, BaseFuncEnum func, String column) {
this.coloum = column;
this.selectNormal = null;
this.hasAlias = true;
this.alias = alias;
this.isFunc = true;
this.func = func;
}
@Override
public Class<?> getClazz() {
return selectNormal.getClazz();
}
@Override
public boolean isPk() {
return false;
}
@Override
public String getColumn() {
return coloum;
}
@Override
public Class<?> getColumnType() {
return Objects.isNull(selectNormal) ? null : selectNormal.getColumnType();
}
@Override
public String getTagColumn() {
return Objects.isNull(selectNormal) ? null : selectNormal.getTagColumn();
}
@Override
public String getColumProperty() {
return Objects.isNull(selectNormal) ? null : selectNormal.getColumProperty();
}
@Override
public boolean hasTypeHandle() {
return !Objects.isNull(selectNormal) && selectNormal.isHasTypeHandle();
}
@Override
public TypeHandler<?> getTypeHandle() {
return Objects.isNull(selectNormal) ? null : selectNormal.getTypeHandle();
}
@Override
public TableFieldInfo getTableFieldInfo() {
return Objects.isNull(selectNormal) ? null : selectNormal.getTableFieldInfo();
}
@Override
public boolean isLabel() {
return false;
}
}

View File

@ -0,0 +1,115 @@
package com.github.yulichang.wrapper.segments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import lombok.Getter;
import org.apache.ibatis.type.TypeHandler;
import java.lang.reflect.Field;
/**
* 对多或对一查询列
*
* @author yulichang
* @since 1.3.10
*/
@Getter
public class SelectLabel implements Select {
private final SelectNormal selectNormal;
private final Class<?> tagClass;
private final Field tagField;
private final boolean hasAlias;
private final String alias;
public SelectLabel(SelectNormal selectNormal, Class<?> tagClass, Field tagField) {
this.selectNormal = selectNormal;
this.tagClass = tagClass;
this.tagField = tagField;
this.hasAlias = false;
this.alias = null;
}
public SelectLabel(SelectNormal selectNormal, Class<?> tagClass, Field tagField, String column) {
this.selectNormal = selectNormal;
this.tagClass = tagClass;
this.tagField = tagField;
this.hasAlias = true;
this.alias = column;
}
@Override
public Class<?> getClazz() {
return selectNormal.getClazz();
}
@Override
public boolean isPk() {
return selectNormal.isPk();
}
@Override
public String getColumn() {
return selectNormal.getColumn();
}
@Override
public Class<?> getColumnType() {
return selectNormal.getColumnType();
}
@Override
public String getTagColumn() {
return selectNormal.getTagColumn();
}
@Override
public String getColumProperty() {
return selectNormal.getColumProperty();
}
@Override
public boolean hasTypeHandle() {
return selectNormal.isHasTypeHandle();
}
@Override
public TypeHandler<?> getTypeHandle() {
return selectNormal.getTypeHandle();
}
@Override
public boolean isHasAlias() {
return hasAlias;
}
@Override
public String getAlias() {
return alias;
}
@Override
public TableFieldInfo getTableFieldInfo() {
return selectNormal.getTableFieldInfo();
}
@Override
public boolean isFunc() {
return false;
}
@Override
public BaseFuncEnum getFunc() {
return null;
}
@Override
public boolean isLabel() {
return true;
}
}

View File

@ -0,0 +1,111 @@
package com.github.yulichang.wrapper.segments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import lombok.Getter;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.ibatis.type.UnknownTypeHandler;
import java.util.Objects;
/**
* 缓存列, 普通列
*
* @author yulichang
* @since 1.3.10
*/
@Getter
public class SelectNormal implements Select {
private final Class<?> clazz;
private final boolean isPk;
private final String column;
private final Class<?> columnType;
private final String tagColumn;
private final String columProperty;
private final TableFieldInfo tableFieldInfo;
private final boolean hasTypeHandle;
private final TypeHandler<?> typeHandler;
public SelectNormal(Class<?> clazz, boolean isPk, String column, Class<?> columnType, String columProperty, TableFieldInfo tableFieldInfo) {
this.clazz = clazz;
this.isPk = isPk;
this.column = column;
this.columnType = columnType;
this.columProperty = columProperty;
this.tagColumn = StringUtils.getTargetColumn(column);
this.tableFieldInfo = tableFieldInfo;
if (Objects.isNull(tableFieldInfo)) {
this.hasTypeHandle = false;
this.typeHandler = null;
} else {
this.hasTypeHandle = this.tableFieldInfo.getTypeHandler() != null && tableFieldInfo.getTypeHandler() != UnknownTypeHandler.class;
if (this.hasTypeHandle) {
TableInfo info = TableInfoHelper.getTableInfo(clazz);
Assert.notNull(info, "table not find by class <%s>", clazz.getSimpleName());
this.typeHandler = getTypeHandler(info.getConfiguration(), tableFieldInfo);
} else {
this.typeHandler = null;
}
}
}
@Override
public boolean hasTypeHandle() {
return hasTypeHandle;
}
@Override
public TypeHandler<?> getTypeHandle() {
return typeHandler;
}
@Override
public boolean isHasAlias() {
return false;
}
@Override
public String getAlias() {
return null;
}
@Override
public boolean isFunc() {
return false;
}
@Override
public BaseFuncEnum getFunc() {
return null;
}
@Override
public boolean isLabel() {
return false;
}
private TypeHandler<?> getTypeHandler(Configuration configuration, TableFieldInfo info) {
TypeHandlerRegistry registry = configuration.getTypeHandlerRegistry();
TypeHandler<?> typeHandler = registry.getMappingTypeHandler(info.getTypeHandler());
if (typeHandler == null) {
typeHandler = registry.getInstance(info.getPropertyType(), info.getTypeHandler());
}
return typeHandler;
}
}

View File

@ -1,6 +1,5 @@
package com.github.yulichang.test.join;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.test.join.dto.AddressDTO;
@ -72,7 +71,7 @@ class LambdaWrapperTest {
MPJLambdaWrapper<UserDO> wrapper1 = new MPJLambdaWrapper<UserDO>()
.select(UserDO::getId)
.selectAs(UserDO::getName,UserDTO::getArea)
.selectAs(UserDO::getName, UserDTO::getArea)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
List<UserDTO> list1 = userMapper.selectJoinList(UserDTO.class, wrapper1);
@ -159,14 +158,14 @@ class LambdaWrapperTest {
*/
@Test
void test6() {
userMapper.selectPage(new Page<>(1, 10), new QueryWrapper<>());
IPage<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class,
MPJWrappers.<UserDO>lambdaJoin()
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.select(AddressDO.class, p -> true)
.select(AddressDO::getAddress)
// .select(AddressDO::getAddress)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.eq(UserDO::getId, 1));
.eq(UserDO::getId, 1);
IPage<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class,
wrapper);
page.getRecords().forEach(System.out::println);
}