mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-11 00:02:22 +08:00
支持选择映射
This commit is contained in:
parent
a8f0c43464
commit
2c5772d09d
@ -15,7 +15,6 @@ import lombok.ToString;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -40,6 +39,10 @@ public class MPJTableFieldInfo {
|
||||
* 属性
|
||||
*/
|
||||
private Field field;
|
||||
/**
|
||||
* 属性名
|
||||
*/
|
||||
private String property;
|
||||
/**
|
||||
* 数据结构是否是Map或者List<Map>
|
||||
*/
|
||||
@ -67,7 +70,7 @@ public class MPJTableFieldInfo {
|
||||
/**
|
||||
* 映射实体类
|
||||
*/
|
||||
private final Class<?> joinClass;
|
||||
private Class<?> joinClass;
|
||||
/**
|
||||
* 映射属性名
|
||||
*/
|
||||
@ -102,15 +105,17 @@ public class MPJTableFieldInfo {
|
||||
/**
|
||||
* 初始化关联字段信息
|
||||
*/
|
||||
public MPJTableFieldInfo(Class<?> entityType, MPJMapping mapping, Field field1) {
|
||||
initField(field1);
|
||||
public MPJTableFieldInfo(Class<?> entityType, MPJMapping mapping, Field field) {
|
||||
initField(field);
|
||||
if (mapping.tag() != Object.class) {
|
||||
this.joinClass = mapping.tag();
|
||||
}
|
||||
this.entityType = entityType;
|
||||
this.joinClass = mapping.tag();
|
||||
this.isThrowExp = mapping.isThrowExp();
|
||||
this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey();
|
||||
this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy();
|
||||
this.wrapper = new MPJMappingWrapper(mapping);
|
||||
if (this.isCollection && this.field.getType() != List.class && this.field.getType() != ArrayList.class) {
|
||||
if (this.isCollection && !List.class.isAssignableFrom(this.field.getType())) {
|
||||
throw new MPJException("对多关系的数据结构目前只支持 <List> 暂不支持其他Collection实现 " + this.field.getType().getTypeName());
|
||||
}
|
||||
if (StringUtils.isNotBlank(mapping.joinField())) {
|
||||
@ -132,6 +137,7 @@ public class MPJTableFieldInfo {
|
||||
private void initField(Field field) {
|
||||
field.setAccessible(true);
|
||||
this.field = field;
|
||||
this.property = field.getName();
|
||||
this.isCollection = Collection.class.isAssignableFrom(field.getType());
|
||||
|
||||
if (Map.class.isAssignableFrom(field.getType())) {
|
||||
@ -149,6 +155,15 @@ public class MPJTableFieldInfo {
|
||||
this.fieldIsMap = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
if (field.getGenericType() instanceof ParameterizedType) {
|
||||
ParameterizedType t = (ParameterizedType) field.getGenericType();
|
||||
this.joinClass = (Class<?>) t.getActualTypeArguments()[0];
|
||||
}
|
||||
} else {
|
||||
this.joinClass = field.getType();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@ -269,28 +284,28 @@ public class MPJTableFieldInfo {
|
||||
}
|
||||
|
||||
public static <T> void bind(MPJTableFieldInfo fieldInfo, T i, List<?> data) {
|
||||
if (!fieldInfo.isCollection()) {
|
||||
if (fieldInfo.isCollection()) {
|
||||
fieldInfo.fieldSet(i, data);
|
||||
} else {
|
||||
if (data.size() > 1 && fieldInfo.isThrowExp()) {
|
||||
throw new MPJException("Expected one result (or null) to be returned by select, but found: " +
|
||||
data.size() + " , " + fieldInfo.getField().getName());
|
||||
} else {
|
||||
fieldInfo.fieldSet(i, data.stream().findFirst().orElse(null));
|
||||
}
|
||||
} else {
|
||||
fieldInfo.fieldSet(i, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindMap(MPJTableFieldInfo fieldInfo, Map<String, Object> i, List<?> data) {
|
||||
if (!fieldInfo.isCollection()) {
|
||||
if (fieldInfo.isCollection()) {
|
||||
i.put(fieldInfo.getField().getName(), data);
|
||||
} else {
|
||||
if (data.size() > 1 && fieldInfo.isThrowExp()) {
|
||||
throw new MPJException("Expected one result (or null) to be returned by select, but found: " +
|
||||
data.size() + " , " + fieldInfo.getField().getName());
|
||||
} else {
|
||||
i.put(fieldInfo.getField().getName(), data.stream().findFirst().orElse(null));
|
||||
}
|
||||
} else {
|
||||
i.put(fieldInfo.getField().getName(), data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,62 +15,63 @@ import java.lang.annotation.*;
|
||||
public @interface MPJMapping {
|
||||
|
||||
/**
|
||||
* 关联的数据库实体类
|
||||
* 关联的数据库实体类<br/>
|
||||
* 默认获取此注解所对应的类
|
||||
*/
|
||||
Class<?> tag();
|
||||
Class<?> tag() default Object.class;
|
||||
|
||||
/**
|
||||
* 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)
|
||||
* 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
|
||||
* 默认获取当前类上定义的主键 @TableId
|
||||
*/
|
||||
String thisField() default "";
|
||||
|
||||
/**
|
||||
* 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)
|
||||
* 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
|
||||
* 默认获取关联类上定义的主键 @TableId
|
||||
*/
|
||||
String joinField() default "";
|
||||
|
||||
/**
|
||||
* 一对一查询时 如果查询到多条记录是否抛出异常
|
||||
* true 抛出异常
|
||||
* false 不抛异常,获取列表第一条数据
|
||||
* 一对一查询时 如果查询到多条记录是否抛出异常<br/>
|
||||
* true 抛出异常<br/>
|
||||
* false 不抛异常,获取列表第一条数据<br/>
|
||||
*/
|
||||
boolean isThrowExp() default true;
|
||||
|
||||
/**
|
||||
* 针对查询结果map的时候使用
|
||||
* 默认为thisField对应的数据库列名
|
||||
* 针对查询结果map的时候使用<br/>
|
||||
* 默认为thisField对应的数据库列名<br/>
|
||||
* <p>
|
||||
* 如果此类是以map方式查询的
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
|
||||
* 如果此类是以map方式查询的<br/>
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
|
||||
*/
|
||||
String thisMapKey() default "";
|
||||
|
||||
/**
|
||||
* isMap为true时生效
|
||||
* 针对查询结果map的时候使用
|
||||
* 默认为joinField对应的数据库列名
|
||||
* isMap为true时生效<br/>
|
||||
* 针对查询结果map的时候使用<br/>
|
||||
* 默认为joinField对应的数据库列名<br/>
|
||||
* <p>
|
||||
* 如果此类是以map方式查询的
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置
|
||||
* 如果此类是以map方式查询的<br/>
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
|
||||
*/
|
||||
String joinMapKsy() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 select
|
||||
* 映射表查询条件之 select<br/>
|
||||
* 等效于 Wrappers.<T>query().select(xxx);
|
||||
*/
|
||||
String select() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 first
|
||||
* 映射表查询条件之 first<br/>
|
||||
* 等效于 Wrappers.<T>query().first(xxx);
|
||||
*/
|
||||
String first() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 apply
|
||||
* 映射表查询条件之 apply<br/>
|
||||
* 等效于 Wrappers.<T>query().apply(xxx);
|
||||
*/
|
||||
MPJMappingApply[] apply() default {};
|
||||
@ -81,8 +82,8 @@ public @interface MPJMapping {
|
||||
MPJMappingCondition[] condition() default {};
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 last
|
||||
* 建议不要在这使用分页语句,会导致关联查的时候查询不全
|
||||
* 映射表查询条件之 last<br/>
|
||||
* 建议不要在这使用分页语句,会导致关联查的时候查询不全<br/>
|
||||
* 等效于 Wrappers.<T>query().last(xxx);
|
||||
*/
|
||||
String last() default "";
|
||||
|
@ -6,30 +6,52 @@ import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.*;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.github.yulichang.toolkit.LambdaUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author yulichang
|
||||
* @see BaseMapper
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
|
||||
/**
|
||||
* 根据 ID 查询
|
||||
* 根据 ID 查询 并关联全部映射
|
||||
*
|
||||
* @param id 主键ID
|
||||
*/
|
||||
default T selectByIdDeep(Serializable id) {
|
||||
return queryMapping(selectById(id));
|
||||
return queryMapping(selectById(id), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 查询 并关联指定映射
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param id 主键ID
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T selectByIdDeep(Serializable id, SFunction<T, R>... property) {
|
||||
return queryMapping(selectById(id), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectByIdDeep(1, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param id 主键ID
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T selectByIdDeep(Serializable id, List<SFunction<T, R>> property) {
|
||||
return queryMapping(selectById(id), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,8 +59,33 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
*
|
||||
* @param idList 主键ID列表(不能为 null 以及 empty)
|
||||
*/
|
||||
default List<T> selectBatchIdsDeep(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList) {
|
||||
return queryMapping(selectBatchIds(idList));
|
||||
default List<T> selectBatchIdsDeep(Collection<? extends Serializable> idList) {
|
||||
return queryMapping(selectBatchIds(idList), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据ID 批量查询)
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param idList 主键ID列表(不能为 null 以及 empty)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> selectBatchIdsDeep(Collection<? extends Serializable> idList, SFunction<T, R>... property) {
|
||||
return queryMapping(selectBatchIds(idList), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectBatchIdsDeep(idList, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param idList 主键ID列表(不能为 null 以及 empty)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> selectBatchIdsDeep(Collection<? extends Serializable> idList, List<SFunction<T, R>> property) {
|
||||
return queryMapping(selectBatchIds(idList), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,8 +93,33 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
*
|
||||
* @param columnMap 表字段 map 对象
|
||||
*/
|
||||
default List<T> selectByMapDeep(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap) {
|
||||
return queryMapping(selectByMap(columnMap));
|
||||
default List<T> selectByMapDeep(Map<String, Object> columnMap) {
|
||||
return queryMapping(selectByMap(columnMap), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据 columnMap 条件)
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param columnMap 表字段 map 对象
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> selectByMapDeep(Map<String, Object> columnMap, SFunction<T, R>... property) {
|
||||
return queryMapping(selectByMap(columnMap), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectByMapDeep(columnMap, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param columnMap 表字段 map 对象
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> selectByMapDeep(Map<String, Object> columnMap, List<SFunction<T, R>> property) {
|
||||
return queryMapping(selectByMap(columnMap), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,8 +127,33 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
default T selectOneDeep(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
|
||||
return queryMapping(selectOne(queryWrapper));
|
||||
default T selectOneDeep(Wrapper<T> queryWrapper) {
|
||||
return queryMapping(selectOne(queryWrapper), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询一条记录
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T selectOneDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return queryMapping(selectOne(queryWrapper), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectOneDeep(queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T selectOneDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return queryMapping(selectOne(queryWrapper), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,8 +161,33 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
default List<T> selectListDeep(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
|
||||
return queryMapping(selectList(queryWrapper));
|
||||
default List<T> selectListDeep(Wrapper<T> queryWrapper) {
|
||||
return queryMapping(selectList(queryWrapper), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询全部记录
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> selectListDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return queryMapping(selectList(queryWrapper), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectListDeep(queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> selectListDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return queryMapping(selectList(queryWrapper), property);
|
||||
}
|
||||
|
||||
|
||||
@ -75,31 +197,68 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
default <E extends IPage<T>> E selectPageDeep(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
|
||||
default <E extends IPage<T>> E selectPageDeep(E page, Wrapper<T> queryWrapper) {
|
||||
E e = selectPage(page, queryWrapper);
|
||||
queryMapping(e.getRecords());
|
||||
queryMapping(e.getRecords(), null);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系
|
||||
* 对结果进行二次查询
|
||||
* 可以自行查询然后在通过此方法进行二次查询
|
||||
* 根据 entity 条件,查询全部记录(并翻页)
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<T>> E selectPageDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
E e = selectPage(page, queryWrapper);
|
||||
queryMapping(e.getRecords(), Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectPageDeep(page, queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<T>> E selectPageDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
E e = selectPage(page, queryWrapper);
|
||||
queryMapping(e.getRecords(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param t 第一次查询结果
|
||||
*/
|
||||
default T queryMapping(T t) {
|
||||
default <R> T queryMapping(T t, List<SFunction<T, R>> property) {
|
||||
if (t == null) {
|
||||
return null;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> list = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
Object get = fieldInfo.thisFieldGet(t);
|
||||
if (get != null) {
|
||||
List<?> o = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(),
|
||||
SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo);
|
||||
MPJTableFieldInfo.bind(fieldInfo, t, o);
|
||||
if (!hasProperty || list.contains(fieldInfo.getProperty())) {
|
||||
Object get = fieldInfo.thisFieldGet(t);
|
||||
if (get != null) {
|
||||
List<?> o = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(),
|
||||
SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo);
|
||||
MPJTableFieldInfo.bind(fieldInfo, t, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,30 +266,36 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系
|
||||
* 对结果进行二次查询
|
||||
* 可以自行查询然后在通过此方法进行二次查询
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param list 第一次查询结果
|
||||
*/
|
||||
default List<T> queryMapping(List<T> list) {
|
||||
default <R> List<T> queryMapping(List<T> list, List<SFunction<T, R>> property) {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return list;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
List<Object> itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(itemList)) {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<?> data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j)
|
||||
.equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bind(fieldInfo, i, data);
|
||||
});
|
||||
} else {
|
||||
list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>()));
|
||||
if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
|
||||
List<Object> itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(itemList)) {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<?> data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j)
|
||||
.equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bind(fieldInfo, i, data);
|
||||
});
|
||||
} else {
|
||||
list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,15 +8,14 @@ import com.baomidou.mybatisplus.core.metadata.MPJTableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.github.yulichang.annotation.MPJMapping;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.github.yulichang.toolkit.LambdaUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -30,7 +29,7 @@ import java.util.stream.Collectors;
|
||||
* @see MPJMapping
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
public interface MPJDeepService<T> extends IService<T> {
|
||||
|
||||
Class<T> currentModelClass();
|
||||
@ -40,10 +39,34 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*
|
||||
* @param id 主键ID列表
|
||||
*/
|
||||
default <R> T getByIdDeep(Serializable id) {
|
||||
default T getByIdDeep(Serializable id) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 深度查询
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param id 主键ID列表
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T getByIdDeep(Serializable id, SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: getByIdDeep(id, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param id 主键ID列表
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T getByIdDeep(Serializable id, List<SFunction<T, R>> property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据ID 批量查询)
|
||||
@ -54,6 +77,31 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据ID 批量查询)
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param idList 主键ID列表
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> listByIdsDeep(Collection<? extends Serializable> idList, SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据ID 批量查询)
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: listByIdsDeep(idList, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param idList 主键ID列表
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> listByIdsDeep(Collection<? extends Serializable> idList, List<SFunction<T, R>> property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据 columnMap 条件)
|
||||
*
|
||||
@ -63,6 +111,31 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据 columnMap 条件)
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param columnMap 表字段 map 对象
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> listByMapDeep(Map<String, Object> columnMap, SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据 columnMap 条件)
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: listByMapDeep(columnMap, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param columnMap 表字段 map 对象
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> listByMapDeep(Map<String, Object> columnMap, List<SFunction<T, R>> property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, property);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录 <br/>
|
||||
@ -74,6 +147,32 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录 <br/>
|
||||
* <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T getOneDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录 <br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
* <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
|
||||
* <p>
|
||||
* 例: getOneDeep(queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T getOneDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录
|
||||
@ -82,7 +181,34 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param throwEx 有多个 result 是否抛出异常
|
||||
*/
|
||||
default T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx));
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param throwEx 有多个 result 是否抛出异常
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx, SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: getOneDeep(queryWrapper, throwEx, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param throwEx 有多个 result 是否抛出异常
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx, List<SFunction<T, R>> property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapping(getOne(queryWrapper, throwEx), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,23 +217,33 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default Map<String, Object> getMapDeep(Wrapper<T> queryWrapper) {
|
||||
Map<String, Object> map = getMap(queryWrapper);
|
||||
if (CollectionUtils.isNotEmpty(map)) {
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
Object o = map.get(fieldInfo.getThisMapKey());
|
||||
if (o != null) {
|
||||
List<?> data = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(),
|
||||
SqlKeyword.EQ, fieldInfo.getJoinColumn(), o, fieldInfo);
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, map, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
return queryMapMapping(getMap(queryWrapper), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return queryMapMapping(getMap(queryWrapper), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:getMapDeep(queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return queryMapMapping(getMap(queryWrapper), property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
@ -118,6 +254,31 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> listDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:listDeep(queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<T> listDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有
|
||||
*
|
||||
@ -127,6 +288,31 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R> List<T> listDeep(SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:listDeep(Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R> List<T> listDeep(List<SFunction<T, R>> property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
*
|
||||
@ -135,7 +321,38 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
default <E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper) {
|
||||
E e = page(page, queryWrapper);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords());
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords(), null);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
E e = page(page, queryWrapper);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords(), Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:pageDeep(page, queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
E e = page(page, queryWrapper);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -147,7 +364,38 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
default <E extends IPage<T>> E pageDeep(E page) {
|
||||
E e = page(page);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords());
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords(), null);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无条件翻页查询
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R, E extends IPage<T>> E pageDeep(E page, SFunction<T, R>... property) {
|
||||
E e = page(page);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords(), Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无条件翻页查询
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:pageDeep(page, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R, E extends IPage<T>> E pageDeep(E page, List<SFunction<T, R>> property) {
|
||||
E e = page(page);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapping(e.getRecords(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -157,7 +405,32 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper) {
|
||||
return queryMapMapping(listMaps(queryWrapper));
|
||||
return queryMapMapping(listMaps(queryWrapper), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return queryMapMapping(listMaps(queryWrapper), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:listMapsDeep(queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return queryMapMapping(listMaps(queryWrapper), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,9 +439,33 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default List<Map<String, Object>> listMapsDeep() {
|
||||
return queryMapMapping(listMaps());
|
||||
return queryMapMapping(listMaps(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有列表
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(SFunction<T, R>... property) {
|
||||
return queryMapMapping(listMaps(), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有列表
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:listMapsDeep(Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(List<SFunction<T, R>> property) {
|
||||
return queryMapMapping(listMaps(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
@ -178,7 +475,38 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper) {
|
||||
E e = pageMaps(page, queryWrapper);
|
||||
queryMapMapping(e.getRecords());
|
||||
queryMapMapping(e.getRecords(), null);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
E e = pageMaps(page, queryWrapper);
|
||||
queryMapMapping(e.getRecords(), Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:pageMapsDeep(page, queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
E e = pageMaps(page, queryWrapper);
|
||||
queryMapMapping(e.getRecords(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -190,55 +518,121 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page) {
|
||||
E e = pageMaps(page);
|
||||
queryMapMapping(e.getRecords());
|
||||
queryMapMapping(e.getRecords(), null);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无条件翻页查询
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, SFunction<T, R>... property) {
|
||||
E e = pageMaps(page);
|
||||
queryMapMapping(e.getRecords(), Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系
|
||||
* 对结果进行二次查询
|
||||
* 可以自行查询然后在通过此方法进行二次查询
|
||||
* 无条件翻页查询
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例:pageMapsDeep(page, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, List<SFunction<T, R>> property) {
|
||||
E e = pageMaps(page);
|
||||
queryMapMapping(e.getRecords(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param map 第一次查询结果
|
||||
*/
|
||||
default <R> Map<String, Object> queryMapMapping(Map<String, Object> map, List<SFunction<T, R>> property) {
|
||||
if (CollectionUtils.isNotEmpty(map)) {
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> list = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
if (!hasProperty || list.contains(fieldInfo.getProperty())) {
|
||||
Object o = map.get(fieldInfo.getThisMapKey());
|
||||
if (o != null) {
|
||||
List<?> data = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), o, fieldInfo);
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, map, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param list 第一次查询结果
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default List<Map<String, Object>> queryMapMapping(List<Map<String, Object>> list) {
|
||||
default <R> List<Map<String, Object>> queryMapMapping(List<Map<String, Object>> list, List<SFunction<T, R>> property) {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return list;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
List<Object> itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey())).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(itemList)) {
|
||||
if (fieldInfo.isFieldIsMap()) {
|
||||
List<Map<String, Object>> joinList = (List<Map<String, Object>>) fieldInfo.getJoinMapper()
|
||||
.mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN,
|
||||
fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<Map<String, Object>> data = joinList.stream().filter(j -> j.containsKey(fieldInfo.getJoinMapKey())
|
||||
&& j.get(fieldInfo.getJoinMapKey()).equals(i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, i, data);
|
||||
});
|
||||
if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
|
||||
List<Object> itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(itemList)) {
|
||||
if (fieldInfo.isFieldIsMap()) {
|
||||
List<Map<String, Object>> joinList = (List<Map<String, Object>>) fieldInfo.getJoinMapper()
|
||||
.mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN,
|
||||
fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<Map<String, Object>> data = joinList.stream().filter(j -> j.containsKey(
|
||||
fieldInfo.getJoinMapKey()) && j.get(fieldInfo.getJoinMapKey()).equals(
|
||||
i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, i, data);
|
||||
});
|
||||
} else {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<?> data = joinList.stream().filter(j -> {
|
||||
Object o = fieldInfo.joinFieldGet(j);
|
||||
return o != null && o.equals(i.get(fieldInfo.getThisMapKey()));
|
||||
}).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, i, data);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<?> data = joinList.stream().filter(j -> {
|
||||
Object o = fieldInfo.joinFieldGet(j);
|
||||
return o != null && o.equals(i.get(fieldInfo.getThisMapKey()));
|
||||
}).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, i, data);
|
||||
});
|
||||
list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>()));
|
||||
}
|
||||
} else {
|
||||
list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ package com.github.yulichang.injector;
|
||||
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.mapper.Mapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
||||
import com.github.yulichang.method.*;
|
||||
@ -12,6 +14,7 @@ import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -42,7 +45,7 @@ public class MPJSqlInjector extends DefaultSqlInjector {
|
||||
|
||||
@Override
|
||||
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
|
||||
Class<?> modelClass = extractModelClass(mapperClass);
|
||||
Class<?> modelClass = getSuperClassGenericType(mapperClass, Mapper.class, 0);
|
||||
if (modelClass != null) {
|
||||
String className = mapperClass.toString();
|
||||
Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
|
||||
@ -50,14 +53,19 @@ public class MPJSqlInjector extends DefaultSqlInjector {
|
||||
List<AbstractMethod> methodList = this.getMethodList(mapperClass);
|
||||
if (CollectionUtils.isNotEmpty(methodList)) {
|
||||
TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);
|
||||
MPJTableInfoHelper.initTableInfo(builderAssistant, extractModelClass(mapperClass), mapperClass);
|
||||
MPJTableInfoHelper.initTableInfo(builderAssistant, modelClass, mapperClass);
|
||||
// 循环注入自定义方法
|
||||
methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
|
||||
} else {
|
||||
logger.debug(mapperClass + ", No effective injection method was found.");
|
||||
logger.debug(mapperClass.toString() + ", No effective injection method was found.");
|
||||
}
|
||||
mapperRegistryCache.add(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> getSuperClassGenericType(final Class<?> clazz, final Class<?> genericIfc, final int index) {
|
||||
Class<?>[] typeArguments = GenericTypeResolver.resolveTypeArguments(ClassUtils.getUserClass(clazz), genericIfc);
|
||||
return null == typeArguments ? null : typeArguments[index];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user