1.2.5版本临时分支

This commit is contained in:
yulichang 2022-11-04 17:26:51 +08:00
parent 758df4c136
commit f020d64af3
8 changed files with 299 additions and 11 deletions

View File

@ -25,7 +25,7 @@ import java.util.Objects;
*
* @author yulichang
*/
@SuppressWarnings("SpringJavaAutowiredMembersInspection")
@SuppressWarnings("NullableProblems")
public class InterceptorConfig implements ApplicationListener<ApplicationReadyEvent> {
private static final Log logger = LogFactory.getLog(InterceptorConfig.class);

View File

@ -0,0 +1,28 @@
package com.github.yulichang.toolkit;
import java.util.HashMap;
import java.util.Map;
public class BiHashMap<K, V, E> {
private final Map<K, Map<V, E>> map;
public BiHashMap() {
this.map = new HashMap<>();
}
public E get(K k, V v) {
return map.containsKey(k) ? map.get(k).get(v) : null;
}
public void put(K k, V v, E e) {
if (map.containsKey(k)) {
map.get(k).put(v, e);
} else {
Map<V, E> veMap = new HashMap<>();
veMap.put(v, e);
map.put(k, veMap);
}
}
}

View File

@ -23,8 +23,7 @@ import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.springframework.core.GenericTypeResolver;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@ -101,6 +100,28 @@ public final class ReflectionKit {
return null == typeArguments ? null : typeArguments[index];
}
/**
* Collection字段的泛型
*/
public static Class<?> getGenericType(Field field) {
Type type = field.getGenericType();
//没有写泛型
if (!(type instanceof ParameterizedType)) {
return Object.class;
}
ParameterizedType pt = (ParameterizedType) type;
Type[] actualTypeArguments = pt.getActualTypeArguments();
Type argument = actualTypeArguments[0];
//通配符泛型 ? , ? extends XXX , ? super XXX
if (argument instanceof WildcardType) {
//获取上界
Type[] types = ((WildcardType) argument).getUpperBounds();
return (Class<?>) types[0];
}
return (Class<?>) argument;
}
/**
* <p>
* 获取该类的所有属性列表

View File

@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.exception.MPJException;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.SelectColumn;
@ -17,6 +18,8 @@ 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.Collection;
import com.github.yulichang.wrapper.resultmap.MFunc;
import lombok.Getter;
import java.lang.reflect.Field;
@ -36,7 +39,7 @@ import java.util.stream.Collectors;
* @author yulichang
* @see MPJWrappers
*/
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "unchecked"})
public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWrapper<T>>
implements Query<MPJLambdaWrapper<T>>, LambdaJoin<MPJLambdaWrapper<T>, T> {
@ -57,6 +60,16 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
* ON sql wrapper集合
*/
private final List<MPJLambdaWrapper<?>> onWrappers = new ArrayList<>();
/**
* 敌对多映射关系
*/
@Getter
private final List<Collection<?, ?>> resultMapCollection = new ArrayList<>();
/**
* 是否构建是否存在一对多
*/
@Getter
private boolean resultMap = false;
/**
* 查询字段 sql
*/
@ -65,11 +78,6 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
* 是否 select distinct
*/
private boolean selectDistinct = false;
/**
* 是否构建resultMap
*/
@Getter
private final boolean resultMap = false;
/**
* 表序号
*/
@ -138,10 +146,53 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
return typedThis;
}
// TODO 重载重复代码简化
public <S, C, Z, F extends java.util.Collection<?>> MPJLambdaWrapper<T> selectCollection(Class<C> child, SFunction<S, F> dtoField) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
Map<String, Field> fieldMap = ReflectionKit.getFieldMap(dtoClass);
Field field = fieldMap.get(dtoFieldName);
this.resultMap = true;
Class<?> genericType = ReflectionKit.getGenericType(field);
Collection.Builder<C, Z> builder;
if (genericType == null || genericType.isAssignableFrom(child)) {
//找不到集合泛型 List List<?> List<Object> 直接查询数据库实体
builder = new Collection.Builder<>(dtoFieldName, child, field.getType());
} else {
Class<Z> ofType = (Class<Z>) genericType;
if (ReflectionKit.isPrimitiveOrWrapper(ofType) || fieldMap.isEmpty()) {
throw new MPJException("collection 不支持基本数据类型");
}
builder = new Collection.Builder<>(dtoFieldName, child, field.getType(), ofType);
}
this.resultMapCollection.add(builder.build());
return typedThis;
}
public <S, C, Z, F extends java.util.Collection<Z>> MPJLambdaWrapper<T>
selectCollection(Class<C> child, SFunction<S, F> dtoField, MFunc<Collection.Builder<C, Z>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
Field field = ReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
this.resultMap = true;
//获取集合泛型
Class<?> genericType = ReflectionKit.getGenericType(field);
Class<Z> ofType = (Class<Z>) genericType;
Collection.Builder<C, Z> builder = new Collection.Builder<>(dtoFieldName, child, field.getType(), ofType);
this.resultMapCollection.add(collection.apply(builder).build());
return typedThis;
}
public <S, C, Z, F> MPJLambdaWrapper<T> selectAssociation(Class<C> child, SFunction<S, F> dtoField, MFunc<Collection.Builder<C, F>> collection) {
//TODO
return typedThis;
}
@Override
public <E> MPJLambdaWrapper<T> select(Class<E> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
Assert.notNull(info, "table can not be find");
Assert.notNull(info, "table not find by class <%s>", entityClass.getName());
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(
i -> selectColumns.add(SelectColumn.of(entityClass, i.getColumn(), i, null, i.getProperty(), null)));
return typedThis;
@ -150,7 +201,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
@Override
public <E> MPJLambdaWrapper<T> selectAsClass(Class<E> source, Class<?> tag) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(source);
Assert.notNull(tableInfo, "table can not be find");
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()))) {

View File

@ -0,0 +1,84 @@
package com.github.yulichang.wrapper.resultmap;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
/**
* collection 标签 目前先支持这几个属性 后续在扩展
*
* @author yulichang
* @since 1.2.5
*/
@Getter
public class Collection<E, T> {
private String property;
private Class<E> entityClass;
private Class<?> javaType;
private Class<T> ofType;
private List<Result> resultList;
//collection嵌套
// private List<Collection> collectionList;
private Collection() {
}
public static class Builder<E, T> {
private final Collection<E, T> collection;
/**
* 自动构建
*/
@SuppressWarnings("unchecked")
public Builder(String property, Class<E> entityClass, Class<?> javaType) {
this.collection = new Collection<>();
collection.property = property;
collection.entityClass = entityClass;
collection.javaType = javaType;
collection.ofType = (Class<T>) entityClass;
collection.resultList = new ArrayList<>();
// TODO 构建entityClass所有的字段
}
/**
* 手动构建
*
* @param property property
* @param entityClass 数据库实体类
* @param javaType javaType
* @param ofType 映射类
*/
public Builder(String property, Class<E> entityClass, Class<?> javaType, Class<T> ofType) {
this.collection = new Collection<>();
collection.property = property;
collection.entityClass = entityClass;
collection.javaType = javaType;
collection.ofType = ofType;
collection.resultList = new ArrayList<>();
}
public Builder<E, T> id(MFunc<Result.Builder<E, T>> result) {
Result r = result.apply(new Result.Builder<>(true)).build();
collection.resultList.add(r);
return this;
}
public Builder<E, T> result(MFunc<Result.Builder<E, T>> result) {
Result r = result.apply(new Result.Builder<>(false)).build();
collection.resultList.add(r);
return this;
}
public Collection<E, T> build() {
return collection;
}
}
}

View File

@ -0,0 +1,7 @@
package com.github.yulichang.wrapper.resultmap;
@FunctionalInterface
public interface MFunc<T> {
T apply(T t);
}

View File

@ -0,0 +1,12 @@
package com.github.yulichang.wrapper.resultmap;
import lombok.Getter;
import org.apache.ibatis.mapping.ResultMap;
public class MPJResultMap {
@Getter
private ResultMap resultMap;
}

View File

@ -0,0 +1,85 @@
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.support.SFunction;
import com.github.yulichang.toolkit.LambdaUtils;
import lombok.Getter;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
/**
* result 标签
*
* @author yulichang
* @since 1.2.5
*/
@Getter
public class Result {
private boolean isId;
private String property;
private String column;
private TableFieldInfo tableFieldInfo;
private Class<?> javaType;
private JdbcType jdbcType;
private TypeHandler<?> typeHandle;
private Result() {
}
public static class Builder<E, T> {
private final Result result;
public Builder(boolean isId) {
this.result = new Result();
result.isId = isId;
}
public Builder<E, T> property(SFunction<T, ?> property) {
result.property = LambdaUtils.getName(property);
return this;
}
public Builder<E, T> column(SFunction<E, ?> column) {
Class<E> entityClass = LambdaUtils.getEntityClass(column);
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();
} 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;
}
return this;
}
public Builder<E, T> javaType(Class<?> javaType) {
result.javaType = javaType;
return this;
}
public Builder<E, T> jdbcType(JdbcType jdbcType) {
result.jdbcType = jdbcType;
return this;
}
public Result build() {
//TODO 检查数据完整性
return result;
}
}
}