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
|
* @author yulichang
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("SpringJavaAutowiredMembersInspection")
|
@SuppressWarnings("NullableProblems")
|
||||||
public class InterceptorConfig implements ApplicationListener<ApplicationReadyEvent> {
|
public class InterceptorConfig implements ApplicationListener<ApplicationReadyEvent> {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(InterceptorConfig.class);
|
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.apache.ibatis.logging.LogFactory;
|
||||||
import org.springframework.core.GenericTypeResolver;
|
import org.springframework.core.GenericTypeResolver;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.*;
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -101,6 +100,28 @@ public final class ReflectionKit {
|
|||||||
return null == typeArguments ? null : typeArguments[index];
|
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>
|
* <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.StringPool;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
|
import com.github.yulichang.exception.MPJException;
|
||||||
import com.github.yulichang.toolkit.*;
|
import com.github.yulichang.toolkit.*;
|
||||||
import com.github.yulichang.toolkit.support.ColumnCache;
|
import com.github.yulichang.toolkit.support.ColumnCache;
|
||||||
import com.github.yulichang.toolkit.support.SelectColumn;
|
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.LambdaJoin;
|
||||||
import com.github.yulichang.wrapper.interfaces.Query;
|
import com.github.yulichang.wrapper.interfaces.Query;
|
||||||
import com.github.yulichang.wrapper.interfaces.on.OnFunction;
|
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 lombok.Getter;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@ -36,7 +39,7 @@ import java.util.stream.Collectors;
|
|||||||
* @author yulichang
|
* @author yulichang
|
||||||
* @see MPJWrappers
|
* @see MPJWrappers
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings({"unused", "unchecked"})
|
||||||
public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWrapper<T>>
|
public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWrapper<T>>
|
||||||
implements Query<MPJLambdaWrapper<T>>, LambdaJoin<MPJLambdaWrapper<T>, T> {
|
implements Query<MPJLambdaWrapper<T>>, LambdaJoin<MPJLambdaWrapper<T>, T> {
|
||||||
|
|
||||||
@ -57,6 +60,16 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
* ON sql wrapper集合
|
* ON sql wrapper集合
|
||||||
*/
|
*/
|
||||||
private final List<MPJLambdaWrapper<?>> onWrappers = new ArrayList<>();
|
private final List<MPJLambdaWrapper<?>> onWrappers = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* 敌对多映射关系
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private final List<Collection<?, ?>> resultMapCollection = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* 是否构建是否存在一对多
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private boolean resultMap = false;
|
||||||
/**
|
/**
|
||||||
* 查询字段 sql
|
* 查询字段 sql
|
||||||
*/
|
*/
|
||||||
@ -65,11 +78,6 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
* 是否 select distinct
|
* 是否 select distinct
|
||||||
*/
|
*/
|
||||||
private boolean selectDistinct = false;
|
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;
|
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
|
@Override
|
||||||
public <E> MPJLambdaWrapper<T> select(Class<E> entityClass, Predicate<TableFieldInfo> predicate) {
|
public <E> MPJLambdaWrapper<T> select(Class<E> entityClass, Predicate<TableFieldInfo> predicate) {
|
||||||
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
|
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(
|
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(
|
||||||
i -> selectColumns.add(SelectColumn.of(entityClass, i.getColumn(), i, null, i.getProperty(), null)));
|
i -> selectColumns.add(SelectColumn.of(entityClass, i.getColumn(), i, null, i.getProperty(), null)));
|
||||||
return typedThis;
|
return typedThis;
|
||||||
@ -150,7 +201,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
@Override
|
@Override
|
||||||
public <E> MPJLambdaWrapper<T> selectAsClass(Class<E> source, Class<?> tag) {
|
public <E> MPJLambdaWrapper<T> selectAsClass(Class<E> source, Class<?> tag) {
|
||||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(source);
|
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);
|
List<Field> tagFields = ReflectionKit.getFieldList(tag);
|
||||||
tableInfo.getFieldList().forEach(i -> {
|
tableInfo.getFieldList().forEach(i -> {
|
||||||
if (tagFields.stream().anyMatch(f -> f.getName().equals(i.getProperty()))) {
|
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