支持选择映射

This commit is contained in:
bjdys 2021-08-20 14:32:38 +08:00
parent a8f0c43464
commit 2c5772d09d
5 changed files with 718 additions and 135 deletions

View File

@ -15,7 +15,6 @@ import lombok.ToString;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -40,6 +39,10 @@ public class MPJTableFieldInfo {
* 属性 * 属性
*/ */
private Field field; private Field field;
/**
* 属性名
*/
private String property;
/** /**
* 数据结构是否是Map或者List<Map> * 数据结构是否是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) { public MPJTableFieldInfo(Class<?> entityType, MPJMapping mapping, Field field) {
initField(field1); initField(field);
if (mapping.tag() != Object.class) {
this.joinClass = mapping.tag();
}
this.entityType = entityType; this.entityType = entityType;
this.joinClass = mapping.tag();
this.isThrowExp = mapping.isThrowExp(); this.isThrowExp = mapping.isThrowExp();
this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey(); this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey();
this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy(); this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy();
this.wrapper = new MPJMappingWrapper(mapping); 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()); throw new MPJException("对多关系的数据结构目前只支持 <List> 暂不支持其他Collection实现 " + this.field.getType().getTypeName());
} }
if (StringUtils.isNotBlank(mapping.joinField())) { if (StringUtils.isNotBlank(mapping.joinField())) {
@ -132,6 +137,7 @@ public class MPJTableFieldInfo {
private void initField(Field field) { private void initField(Field field) {
field.setAccessible(true); field.setAccessible(true);
this.field = field; this.field = field;
this.property = field.getName();
this.isCollection = Collection.class.isAssignableFrom(field.getType()); this.isCollection = Collection.class.isAssignableFrom(field.getType());
if (Map.class.isAssignableFrom(field.getType())) { if (Map.class.isAssignableFrom(field.getType())) {
@ -149,6 +155,15 @@ public class MPJTableFieldInfo {
this.fieldIsMap = false; 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") @SuppressWarnings("ConstantConditions")
@ -269,28 +284,28 @@ public class MPJTableFieldInfo {
} }
public static <T> void bind(MPJTableFieldInfo fieldInfo, T i, List<?> data) { 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()) { if (data.size() > 1 && fieldInfo.isThrowExp()) {
throw new MPJException("Expected one result (or null) to be returned by select, but found: " + throw new MPJException("Expected one result (or null) to be returned by select, but found: " +
data.size() + " , " + fieldInfo.getField().getName()); data.size() + " , " + fieldInfo.getField().getName());
} else { } else {
fieldInfo.fieldSet(i, data.stream().findFirst().orElse(null)); 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) { 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()) { if (data.size() > 1 && fieldInfo.isThrowExp()) {
throw new MPJException("Expected one result (or null) to be returned by select, but found: " + throw new MPJException("Expected one result (or null) to be returned by select, but found: " +
data.size() + " , " + fieldInfo.getField().getName()); data.size() + " , " + fieldInfo.getField().getName());
} else { } else {
i.put(fieldInfo.getField().getName(), data.stream().findFirst().orElse(null)); i.put(fieldInfo.getField().getName(), data.stream().findFirst().orElse(null));
} }
} else {
i.put(fieldInfo.getField().getName(), data);
} }
} }

View File

@ -15,62 +15,63 @@ import java.lang.annotation.*;
public @interface MPJMapping { public @interface MPJMapping {
/** /**
* 关联的数据库实体类 * 关联的数据库实体类<br/>
* 默认获取此注解所对应的类
*/ */
Class<?> tag(); Class<?> tag() default Object.class;
/** /**
* 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称) * 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
* 默认获取当前类上定义的主键 @TableId * 默认获取当前类上定义的主键 @TableId
*/ */
String thisField() default ""; String thisField() default "";
/** /**
* 关联类的字段名称 (是实体类字段名称而不是数据库字段名称) * 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
* 默认获取关联类上定义的主键 @TableId * 默认获取关联类上定义的主键 @TableId
*/ */
String joinField() default ""; String joinField() default "";
/** /**
* 一对一查询时 如果查询到多条记录是否抛出异常 * 一对一查询时 如果查询到多条记录是否抛出异常<br/>
* true 抛出异常 * true 抛出异常<br/>
* false 不抛异常获取列表第一条数据 * false 不抛异常获取列表第一条数据<br/>
*/ */
boolean isThrowExp() default true; boolean isThrowExp() default true;
/** /**
* 针对查询结果map的时候使用 * 针对查询结果map的时候使用<br/>
* 默认为thisField对应的数据库列名 * 默认为thisField对应的数据库列名<br/>
* <p> * <p>
* 如果此类是以map方式查询的 * 如果此类是以map方式查询的<br/>
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置 * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
*/ */
String thisMapKey() default ""; String thisMapKey() default "";
/** /**
* isMap为true时生效 * isMap为true时生效<br/>
* 针对查询结果map的时候使用 * 针对查询结果map的时候使用<br/>
* 默认为joinField对应的数据库列名 * 默认为joinField对应的数据库列名<br/>
* <p> * <p>
* 如果此类是以map方式查询的 * 如果此类是以map方式查询的<br/>
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置 * 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
*/ */
String joinMapKsy() default ""; String joinMapKsy() default "";
/** /**
* 映射表查询条件之 select * 映射表查询条件之 select<br/>
* 等效于 Wrappers.<T>query().select(xxx); * 等效于 Wrappers.<T>query().select(xxx);
*/ */
String select() default ""; String select() default "";
/** /**
* 映射表查询条件之 first * 映射表查询条件之 first<br/>
* 等效于 Wrappers.<T>query().first(xxx); * 等效于 Wrappers.<T>query().first(xxx);
*/ */
String first() default ""; String first() default "";
/** /**
* 映射表查询条件之 apply * 映射表查询条件之 apply<br/>
* 等效于 Wrappers.<T>query().apply(xxx); * 等效于 Wrappers.<T>query().apply(xxx);
*/ */
MPJMappingApply[] apply() default {}; MPJMappingApply[] apply() default {};
@ -81,8 +82,8 @@ public @interface MPJMapping {
MPJMappingCondition[] condition() default {}; MPJMappingCondition[] condition() default {};
/** /**
* 映射表查询条件之 last * 映射表查询条件之 last<br/>
* 建议不要在这使用分页语句会导致关联查的时候查询不全 * 建议不要在这使用分页语句会导致关联查的时候查询不全<br/>
* 等效于 Wrappers.<T>query().last(xxx); * 等效于 Wrappers.<T>query().last(xxx);
*/ */
String last() default ""; String last() default "";

View File

@ -6,30 +6,52 @@ import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.*; import com.baomidou.mybatisplus.core.metadata.*;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.annotations.Param; import com.github.yulichang.toolkit.LambdaUtils;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* @author yulichang * @author yulichang
* @see BaseMapper * @see BaseMapper
*/ */
@SuppressWarnings("unused") @SuppressWarnings({"unused", "unchecked"})
public interface MPJDeepMapper<T> extends BaseMapper<T> { public interface MPJDeepMapper<T> extends BaseMapper<T> {
/** /**
* 根据 ID 查询 * 根据 ID 查询 并关联全部映射
* *
* @param id 主键ID * @param id 主键ID
*/ */
default T selectByIdDeep(Serializable 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) * @param idList 主键ID列表(不能为 null 以及 empty)
*/ */
default List<T> selectBatchIdsDeep(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList) { default List<T> selectBatchIdsDeep(Collection<? extends Serializable> idList) {
return queryMapping(selectBatchIds(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 对象 * @param columnMap 表字段 map 对象
*/ */
default List<T> selectByMapDeep(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap) { default List<T> selectByMapDeep(Map<String, Object> columnMap) {
return queryMapping(selectByMap(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 * @param queryWrapper 实体对象封装操作类可以为 null
*/ */
default T selectOneDeep(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) { default T selectOneDeep(Wrapper<T> queryWrapper) {
return queryMapping(selectOne(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 * @param queryWrapper 实体对象封装操作类可以为 null
*/ */
default List<T> selectListDeep(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) { default List<T> selectListDeep(Wrapper<T> queryWrapper) {
return queryMapping(selectList(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 page 分页查询条件可以为 RowBounds.DEFAULT
* @param queryWrapper 实体对象封装操作类可以为 null * @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); E e = selectPage(page, queryWrapper);
queryMapping(e.getRecords()); queryMapping(e.getRecords(), null);
return e; 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 第一次查询结果 * @param t 第一次查询结果
*/ */
default T queryMapping(T t) { default <R> T queryMapping(T t, List<SFunction<T, R>> property) {
if (t == null) { if (t == null) {
return null; return null;
} }
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass()); MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass());
if (tableInfo.isHasMapping()) { 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()) { for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
Object get = fieldInfo.thisFieldGet(t); if (!hasProperty || list.contains(fieldInfo.getProperty())) {
if (get != null) { Object get = fieldInfo.thisFieldGet(t);
List<?> o = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(), if (get != null) {
SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo); List<?> o = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(),
MPJTableFieldInfo.bind(fieldInfo, t, o); 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 第一次查询结果 * @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)) { if (CollectionUtils.isEmpty(list)) {
return list; return list;
} }
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass()); MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass());
if (tableInfo.isHasMapping()) { 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()) { for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
List<Object> itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList()); if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
if (CollectionUtils.isNotEmpty(itemList)) { List<Object> itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList());
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor( if (CollectionUtils.isNotEmpty(itemList)) {
fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo); List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
list.forEach(i -> { fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo);
List<?> data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j) list.forEach(i -> {
.equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList()); List<?> data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j)
MPJTableFieldInfo.bind(fieldInfo, i, data); .equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList());
}); MPJTableFieldInfo.bind(fieldInfo, i, data);
} else { });
list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>())); } else {
list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>()));
}
} }
} }
} }

View File

@ -8,15 +8,14 @@ import com.baomidou.mybatisplus.core.metadata.MPJTableInfo;
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper; import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.annotation.MPJMapping; import com.github.yulichang.annotation.MPJMapping;
import com.github.yulichang.base.MPJBaseMapper; import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.toolkit.LambdaUtils;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -30,7 +29,7 @@ import java.util.stream.Collectors;
* @see MPJMapping * @see MPJMapping
* @since 1.2.0 * @since 1.2.0
*/ */
@SuppressWarnings("unused") @SuppressWarnings({"unused", "unchecked"})
public interface MPJDeepService<T> extends IService<T> { public interface MPJDeepService<T> extends IService<T> {
Class<T> currentModelClass(); Class<T> currentModelClass();
@ -40,10 +39,34 @@ public interface MPJDeepService<T> extends IService<T> {
* *
* @param id 主键ID列表 * @param id 主键ID列表
*/ */
default <R> T getByIdDeep(Serializable id) { default T getByIdDeep(Serializable id) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(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 批量查询 * 查询根据ID 批量查询
@ -54,6 +77,31 @@ public interface MPJDeepService<T> extends IService<T> {
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList); 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 条件 * 查询根据 columnMap 条件
* *
@ -63,6 +111,31 @@ public interface MPJDeepService<T> extends IService<T> {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap); 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/> * 根据 Wrapper查询一条记录 <br/>
@ -74,6 +147,32 @@ public interface MPJDeepService<T> extends IService<T> {
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper); 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查询一条记录 * 根据 Wrapper查询一条记录
@ -82,7 +181,34 @@ public interface MPJDeepService<T> extends IService<T> {
* @param throwEx 有多个 result 是否抛出异常 * @param throwEx 有多个 result 是否抛出异常
*/ */
default T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx) { 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} * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/ */
default Map<String, Object> getMapDeep(Wrapper<T> queryWrapper) { default Map<String, Object> getMapDeep(Wrapper<T> queryWrapper) {
Map<String, Object> map = getMap(queryWrapper); return queryMapMapping(getMap(queryWrapper), null);
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;
} }
/**
* 根据 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); 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()); 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) { default <E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper) {
E e = page(page, 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; return e;
} }
@ -147,7 +364,38 @@ public interface MPJDeepService<T> extends IService<T> {
*/ */
default <E extends IPage<T>> E pageDeep(E page) { default <E extends IPage<T>> E pageDeep(E page) {
E e = page(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; return e;
} }
@ -157,7 +405,32 @@ public interface MPJDeepService<T> extends IService<T> {
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/ */
default List<Map<String, Object>> listMapsDeep(Wrapper<T> 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() * @see Wrappers#emptyWrapper()
*/ */
default List<Map<String, Object>> listMapsDeep() { 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) { default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper) {
E e = pageMaps(page, 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; return e;
} }
@ -190,55 +518,121 @@ public interface MPJDeepService<T> extends IService<T> {
*/ */
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page) { default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page) {
E e = pageMaps(page); E e = pageMaps(page);
queryMapMapping(e.getRecords()); queryMapMapping(e.getRecords(), null);
return e; 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 第一次查询结果 * @param list 第一次查询结果
*/ */
@SuppressWarnings("unchecked") @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)) { if (CollectionUtils.isEmpty(list)) {
return list; return list;
} }
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass()); MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass());
if (tableInfo.isHasMapping()) { 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()) { for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
List<Object> itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey())).collect(Collectors.toList()); if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
if (CollectionUtils.isNotEmpty(itemList)) { List<Object> itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey()))
if (fieldInfo.isFieldIsMap()) { .collect(Collectors.toList());
List<Map<String, Object>> joinList = (List<Map<String, Object>>) fieldInfo.getJoinMapper() if (CollectionUtils.isNotEmpty(itemList)) {
.mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN, if (fieldInfo.isFieldIsMap()) {
fieldInfo.getJoinColumn(), itemList, fieldInfo); List<Map<String, Object>> joinList = (List<Map<String, Object>>) fieldInfo.getJoinMapper()
list.forEach(i -> { .mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN,
List<Map<String, Object>> data = joinList.stream().filter(j -> j.containsKey(fieldInfo.getJoinMapKey()) fieldInfo.getJoinColumn(), itemList, fieldInfo);
&& j.get(fieldInfo.getJoinMapKey()).equals(i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList()); list.forEach(i -> {
MPJTableFieldInfo.bindMap(fieldInfo, i, data); 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 { } else {
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor( list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>()));
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.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>()));
} }
} }
} }
return list; return list;
} }
} }

View File

@ -2,9 +2,11 @@ package com.github.yulichang.injector;
import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; 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.MPJTableInfoHelper;
import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; 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.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.github.yulichang.method.*; 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.Log;
import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.logging.LogFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.core.GenericTypeResolver;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -42,7 +45,7 @@ public class MPJSqlInjector extends DefaultSqlInjector {
@Override @Override
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) { public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
Class<?> modelClass = extractModelClass(mapperClass); Class<?> modelClass = getSuperClassGenericType(mapperClass, Mapper.class, 0);
if (modelClass != null) { if (modelClass != null) {
String className = mapperClass.toString(); String className = mapperClass.toString();
Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
@ -50,14 +53,19 @@ public class MPJSqlInjector extends DefaultSqlInjector {
List<AbstractMethod> methodList = this.getMethodList(mapperClass); List<AbstractMethod> methodList = this.getMethodList(mapperClass);
if (CollectionUtils.isNotEmpty(methodList)) { if (CollectionUtils.isNotEmpty(methodList)) {
TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass); 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)); methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
} else { } else {
logger.debug(mapperClass + ", No effective injection method was found."); logger.debug(mapperClass.toString() + ", No effective injection method was found.");
} }
mapperRegistryCache.add(className); 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];
}
} }