mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-11 00:02:22 +08:00
1.2.5版本临时分支
This commit is contained in:
parent
758df4c136
commit
f020d64af3
@ -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);
|
||||
|
28
src/main/java/com/github/yulichang/toolkit/BiHashMap.java
Normal file
28
src/main/java/com/github/yulichang/toolkit/BiHashMap.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
||||
* 获取该类的所有属性列表
|
||||
|
@ -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()))) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.github.yulichang.wrapper.resultmap;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MFunc<T> {
|
||||
|
||||
T apply(T t);
|
||||
}
|
@ -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;
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user