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
2851cd8f5b
commit
3ff34db2ab
@ -0,0 +1,104 @@
|
||||
package com.baomidou.mybatisplus.core.metadata;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.github.yulichang.annotation.MPJMappingApply;
|
||||
import com.github.yulichang.annotation.MPJMappingCondition;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 关联查询条件
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Getter
|
||||
public class MPJMappingWrapper {
|
||||
|
||||
private final boolean hasFirst;
|
||||
private String first;
|
||||
|
||||
private final boolean hasSelect;
|
||||
private String select;
|
||||
|
||||
private final boolean hasApply;
|
||||
private List<Apply> applyList;
|
||||
|
||||
private final boolean hasCondition;
|
||||
private List<Condition> conditionList;
|
||||
|
||||
private final boolean hasLast;
|
||||
private String last;
|
||||
|
||||
private final boolean hasOrderByAsc;
|
||||
private List<String> orderByAsc;
|
||||
|
||||
private final boolean hasOrderByDesc;
|
||||
private List<String> orderByDesc;
|
||||
|
||||
public MPJMappingWrapper(String first, String select, MPJMappingApply[] applys,
|
||||
MPJMappingCondition[] conditions, String last, String orderByAsc, String orderByDesc) {
|
||||
this.hasFirst = StringUtils.isNotBlank(first);
|
||||
if (this.hasFirst) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
this.hasSelect = StringUtils.isNotBlank(select);
|
||||
if (this.hasSelect) {
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
this.hasApply = applys.length > 0;
|
||||
if (this.hasApply) {
|
||||
this.applyList = new ArrayList<>();
|
||||
for (MPJMappingApply apply : applys) {
|
||||
this.applyList.add(new Apply(apply.value(), apply.args()));
|
||||
}
|
||||
}
|
||||
|
||||
this.hasCondition = conditions.length > 0;
|
||||
if (this.hasCondition) {
|
||||
this.conditionList = new ArrayList<>();
|
||||
for (MPJMappingCondition condition : conditions) {
|
||||
conditionList.add(new Condition(condition.keyWord(), condition.column(), condition.value()));
|
||||
}
|
||||
}
|
||||
|
||||
this.hasLast = StringUtils.isNotBlank(last);
|
||||
if (this.hasLast) {
|
||||
this.last = last;
|
||||
}
|
||||
|
||||
this.hasOrderByAsc = StringUtils.isNotBlank(orderByAsc);
|
||||
if (this.hasOrderByAsc) {
|
||||
this.orderByAsc = Arrays.asList(orderByAsc.split(StringPool.COMMA));
|
||||
}
|
||||
|
||||
this.hasOrderByDesc = StringUtils.isNotBlank(orderByDesc);
|
||||
if (this.hasOrderByDesc) {
|
||||
this.orderByDesc = Arrays.asList(orderByDesc.split(StringPool.COMMA));
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class Apply {
|
||||
private final String sql;
|
||||
private final String[] val;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class Condition {
|
||||
private final SqlKeyword keyword;
|
||||
private final String column;
|
||||
private final String[] val;
|
||||
}
|
||||
}
|
@ -0,0 +1,368 @@
|
||||
package com.baomidou.mybatisplus.core.metadata;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||
import com.github.yulichang.annotation.EntityMapping;
|
||||
import com.github.yulichang.annotation.FieldMapping;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.github.yulichang.exception.MPJException;
|
||||
import com.github.yulichang.toolkit.SpringContentUtils;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字段属性
|
||||
*
|
||||
* @author yulichang
|
||||
* @see TableFieldInfo
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class MPJTableFieldInfo {
|
||||
|
||||
/**
|
||||
* 是否是实体映射
|
||||
*/
|
||||
private final boolean isMappingEntity;
|
||||
/**
|
||||
* 是否是属性映射
|
||||
*/
|
||||
private final boolean isMappingField;
|
||||
/**
|
||||
* 字段映射是绑定的字段
|
||||
*/
|
||||
private Field bindField;
|
||||
/**
|
||||
* 是否移除绑定字段
|
||||
*/
|
||||
private final boolean isRemoveBindField;
|
||||
/**
|
||||
* 实体类
|
||||
*/
|
||||
private final Class<?> entityType;
|
||||
/**
|
||||
* 属性
|
||||
*/
|
||||
private Field field;
|
||||
/**
|
||||
* 属性名
|
||||
*/
|
||||
private String property;
|
||||
/**
|
||||
* 数据结构是否是Map或者List<Map>
|
||||
*/
|
||||
private boolean fieldIsMap;
|
||||
/**
|
||||
* 属性是否是集合
|
||||
*/
|
||||
private boolean isCollection;
|
||||
/**
|
||||
* 当前映射属性
|
||||
*/
|
||||
private Field thisField;
|
||||
/**
|
||||
* 当前类实体属性
|
||||
*/
|
||||
private String thisProperty;
|
||||
/**
|
||||
* 当前字段信息
|
||||
*/
|
||||
private String thisColumn;
|
||||
/**
|
||||
* 当前字段信息
|
||||
*/
|
||||
private String thisMapKey;
|
||||
/**
|
||||
* 映射实体类
|
||||
*/
|
||||
private Class<?> joinClass;
|
||||
/**
|
||||
* 映射属性名
|
||||
*/
|
||||
private String joinProperty;
|
||||
/**
|
||||
* 映射属性数据库列名
|
||||
*/
|
||||
private String joinColumn;
|
||||
/**
|
||||
* 映射属性字段
|
||||
*/
|
||||
private Field joinField;
|
||||
/**
|
||||
* fieldIsMap 为true时使用
|
||||
* 映射查询Map 的key
|
||||
* 默认为 关联字段的数据库列名
|
||||
*/
|
||||
private String joinMapKey;
|
||||
/**
|
||||
* 关联的mapper引用
|
||||
*/
|
||||
private MPJBaseMapper<?> joinMapper;
|
||||
/**
|
||||
* 关联查询条件配置
|
||||
*/
|
||||
private final MPJMappingWrapper wrapper;
|
||||
/**
|
||||
* 一对一查询结果数量不匹配是是否抛出异常
|
||||
*/
|
||||
private final boolean isThrowExp;
|
||||
|
||||
/**
|
||||
* 初始化关联字段信息
|
||||
*/
|
||||
public MPJTableFieldInfo(Class<?> entityType, EntityMapping mapping, Field field) {
|
||||
this.isMappingEntity = true;
|
||||
this.isMappingField = false;
|
||||
initField(field);
|
||||
if (mapping.tag() != Object.class) {
|
||||
this.joinClass = mapping.tag();
|
||||
}
|
||||
this.entityType = entityType;
|
||||
this.isThrowExp = mapping.isThrowExp();
|
||||
initThisField(mapping.thisMapKey(), mapping.thisField());
|
||||
initJoinField(mapping.joinMapKey(), mapping.joinField());
|
||||
this.isRemoveBindField = StringUtils.isNotBlank(mapping.select()) && (!Arrays.asList(mapping.select().split(
|
||||
StringPool.COMMA)).contains(this.joinColumn.trim()));
|
||||
this.wrapper = new MPJMappingWrapper(mapping.first(), StringUtils.isBlank(mapping.select()) ? null :
|
||||
(this.isRemoveBindField ? this.joinColumn + StringPool.COMMA + mapping.select() : mapping.select()),
|
||||
mapping.apply(), mapping.condition(), mapping.last(), mapping.orderByAsc(), mapping.orderByDesc());
|
||||
}
|
||||
|
||||
public MPJTableFieldInfo(Class<?> entityType, FieldMapping mappingField, Field field) {
|
||||
this.isMappingEntity = false;
|
||||
this.isMappingField = true;
|
||||
field.setAccessible(true);
|
||||
this.field = field;
|
||||
this.property = field.getName();
|
||||
this.isCollection = Collection.class.isAssignableFrom(field.getType());
|
||||
if (this.isCollection && !List.class.isAssignableFrom(this.field.getType())) {
|
||||
throw new MPJException("对多关系的数据结构目前只支持 <List> 暂不支持其他Collection实现 " + this.field.getType().getTypeName());
|
||||
}
|
||||
this.joinClass = mappingField.tag();
|
||||
this.entityType = entityType;
|
||||
this.isThrowExp = mappingField.isThrowExp();
|
||||
initThisField(mappingField.thisMapKey(), mappingField.thisField());
|
||||
initJoinField(mappingField.joinMapKey(), mappingField.joinField());
|
||||
this.isRemoveBindField = !mappingField.select().equals(this.joinColumn.trim());
|
||||
this.wrapper = new MPJMappingWrapper(mappingField.first(), this.isRemoveBindField ? this.joinColumn +
|
||||
StringPool.COMMA + mappingField.select() : mappingField.select(), mappingField.apply(),
|
||||
mappingField.condition(), mappingField.last(), mappingField.orderByAsc(), mappingField.orderByDesc());
|
||||
initBindField(mappingField.select());
|
||||
}
|
||||
|
||||
private void initBindField(String bindName) {
|
||||
List<Field> fields = ReflectionKit.getFieldList(ClassUtils.getUserClass(this.joinClass));
|
||||
Field field = fields.stream().filter(f -> f.getName().equals(bindName)).findFirst().orElse(null);
|
||||
if (field == null) {
|
||||
throw new MPJException("字段不存在 " + this.joinClass.getName() + " ," + bindName);
|
||||
}
|
||||
this.bindField = field;
|
||||
}
|
||||
|
||||
private void initJoinField(String joinMapKey, String joinField) {
|
||||
if (StringUtils.isNotBlank(joinField)) {
|
||||
this.joinProperty = joinField;
|
||||
} else {
|
||||
TableInfo info = getTableInfo(this.joinClass);
|
||||
Assert.isTrue(info.havePK(), "实体未定义主键 %s ", this.joinClass.getName());
|
||||
this.joinProperty = info.getKeyProperty();
|
||||
}
|
||||
|
||||
TableInfo joinTableInfo = getTableInfo(this.joinClass);
|
||||
TableFieldInfo joinFieldInfo = joinTableInfo.getFieldList().stream().filter(f ->
|
||||
f.getField().getName().equals(this.joinProperty)).findFirst().orElse(null);
|
||||
if (joinFieldInfo == null) {
|
||||
if (joinTableInfo.havePK() && this.joinProperty.equals(joinTableInfo.getKeyProperty())) {
|
||||
this.joinColumn = joinTableInfo.getKeyColumn();
|
||||
this.joinField = ReflectionKit.getFieldList(this.joinClass).stream().filter(i ->
|
||||
i.getName().equals(joinTableInfo.getKeyProperty())).findFirst().orElse(null);
|
||||
}
|
||||
} else {
|
||||
this.joinColumn = joinFieldInfo.getColumn();
|
||||
this.joinField = joinFieldInfo.getField();
|
||||
}
|
||||
Assert.notNull(this.joinField, "注解属性thisField不存在 %s , %s", this.joinClass.getName(),
|
||||
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
|
||||
Assert.notNull(this.joinColumn, "注解属性thisField不存在 %s , %s", this.joinClass.getName(),
|
||||
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
|
||||
this.joinField.setAccessible(true);
|
||||
this.joinMapKey = StringUtils.isBlank(joinMapKey) ? this.joinColumn : joinMapKey;
|
||||
}
|
||||
|
||||
private void initThisField(String thisMapKey, String thisField) {
|
||||
if (StringUtils.isNotBlank(thisField)) {
|
||||
this.thisProperty = thisField;
|
||||
} else {
|
||||
TableInfo info = getTableInfo(this.entityType);
|
||||
Assert.isTrue(info.havePK(), "实体未定义主键 %s ", this.entityType.getName());
|
||||
this.thisProperty = info.getKeyProperty();
|
||||
}
|
||||
|
||||
TableInfo tableInfo = getTableInfo(this.entityType);
|
||||
if (tableInfo.havePK() && this.thisProperty.equals(tableInfo.getKeyProperty())) {
|
||||
this.thisField = ReflectionKit.getFieldList(ClassUtils.getUserClass(entityType)).stream().filter(f ->
|
||||
f.getName().equals(tableInfo.getKeyProperty())).findFirst().orElse(null);
|
||||
Assert.notNull(this.thisField, "注解属性thisField不存在 %s , %s", entityType.getName(),
|
||||
StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty);
|
||||
this.thisColumn = tableInfo.getKeyColumn();
|
||||
} else {
|
||||
TableFieldInfo fieldInfo = tableInfo.getFieldList().stream().filter(f ->
|
||||
f.getField().getName().equals(this.thisProperty)).findFirst().orElse(null);
|
||||
Assert.notNull(fieldInfo, "注解属性thisField不存在 %s , %s", entityType.getName(),
|
||||
StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty);
|
||||
this.thisField = fieldInfo.getField();
|
||||
this.thisColumn = fieldInfo.getColumn();
|
||||
}
|
||||
this.thisField.setAccessible(true);
|
||||
this.thisMapKey = StringUtils.isBlank(thisMapKey) ? this.thisColumn : thisMapKey;
|
||||
}
|
||||
|
||||
private void initField(Field field) {
|
||||
field.setAccessible(true);
|
||||
this.field = field;
|
||||
this.property = field.getName();
|
||||
this.isCollection = Collection.class.isAssignableFrom(field.getType());
|
||||
if (this.isCollection && !List.class.isAssignableFrom(this.field.getType())) {
|
||||
throw new MPJException("对多关系的数据结构目前只支持 <List> 暂不支持其他Collection实现 " + this.field.getType().getTypeName());
|
||||
}
|
||||
if (Map.class.isAssignableFrom(field.getType())) {
|
||||
this.fieldIsMap = true;
|
||||
} else {
|
||||
if (field.getGenericType() instanceof ParameterizedType) {
|
||||
ParameterizedType t = (ParameterizedType) field.getGenericType();
|
||||
Type type = t.getActualTypeArguments()[0];
|
||||
if (type instanceof ParameterizedType) {
|
||||
this.fieldIsMap = ((ParameterizedType) type).getRawType() == Map.class;
|
||||
} else {
|
||||
this.fieldIsMap = false;
|
||||
}
|
||||
} else {
|
||||
this.fieldIsMap = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.fieldIsMap) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MPJBaseMapper<?> getJoinMapper() {
|
||||
if (this.joinMapper == null) {
|
||||
MPJTableInfo joinTableInfo = MPJTableInfoHelper.getTableInfos().stream().filter(table ->
|
||||
table.getTableInfo().getEntityType() == this.joinClass).findFirst().orElse(null);
|
||||
if (joinTableInfo == null) {
|
||||
throw new MPJException("未注册 mapper " + this.joinClass.getName());
|
||||
}
|
||||
this.joinMapper = (MPJBaseMapper<?>) SpringContentUtils.getApplicationContext().getBean(joinTableInfo.getMapperClass());
|
||||
}
|
||||
return this.joinMapper;
|
||||
}
|
||||
|
||||
private TableInfo getTableInfo(Class<?> clazz) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
|
||||
if (tableInfo == null) {
|
||||
throw new MPJException("未注册 mapper " + clazz.getName());
|
||||
}
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
|
||||
public void fieldSet(Object o, Object val) {
|
||||
try {
|
||||
this.field.set(o, val);
|
||||
} catch (Exception e) {
|
||||
throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.entityType.getName() +
|
||||
" , " + this.field.getName() + " , " + o.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public Object thisFieldGet(Object o) {
|
||||
try {
|
||||
return getThisField().get(o);
|
||||
} catch (Exception e) {
|
||||
throw new MPJException("无法获取当前关联字段,请检查关联字段是否匹配 " + this.entityType.getName() + " , " +
|
||||
this.thisField.getName() + " , " + o.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public Object joinFieldGet(Object o) {
|
||||
try {
|
||||
return getJoinField().get(o);
|
||||
} catch (Exception e) {
|
||||
throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.joinClass.getName() + " , " +
|
||||
this.joinField.getName() + " , " + o.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public Object bindFieldGet(Object o) {
|
||||
try {
|
||||
return getBindField().get(o);
|
||||
} catch (Exception e) {
|
||||
throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.joinClass.getName() + " , " +
|
||||
this.bindField.getName() + " , " + o.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void joinFieldSetNull(Object o) {
|
||||
try {
|
||||
this.joinField.set(o, null);
|
||||
} catch (Exception e) {
|
||||
throw new MPJException("无法设置关联字段,请检查关联字段数据类型是否匹配 " + this.entityType.getName() +
|
||||
" , " + this.joinField.getName() + " , " + o.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
public void removeJoinField(List<?> joinList) {
|
||||
if (this.isMappingEntity() && this.isRemoveBindField()) {
|
||||
if (this.isFieldIsMap()) {
|
||||
((List<Map<String, Object>>) joinList).forEach(m -> m.remove(this.getJoinMapKey()));
|
||||
} else {
|
||||
joinList.forEach(this::joinFieldSetNull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void bind(MPJTableFieldInfo fieldInfo, T i, List<?> data) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindMap(MPJTableFieldInfo fieldInfo, Map<String, Object> i, List<?> data) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.baomidou.mybatisplus.core.metadata;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据库表反射信息
|
||||
*
|
||||
* @author yulichang
|
||||
* @see TableInfo
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Data
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Accessors(chain = true)
|
||||
public class MPJTableInfo {
|
||||
|
||||
/**
|
||||
* mybatis-plus 表信息
|
||||
*/
|
||||
private TableInfo tableInfo;
|
||||
|
||||
/**
|
||||
* 是否包含 EntityMapping 或者 FieldMapping
|
||||
*/
|
||||
private boolean hasMappingOrField;
|
||||
|
||||
/**
|
||||
* 是否包含映射注解
|
||||
*/
|
||||
private boolean hasMapping;
|
||||
|
||||
/**
|
||||
* 是否包含映射注解
|
||||
*/
|
||||
private boolean hasMappingField;
|
||||
|
||||
/**
|
||||
* mapperClass
|
||||
*/
|
||||
private Class<?> mapperClass;
|
||||
|
||||
/**
|
||||
* 包含映射实体注解的字段列表
|
||||
*/
|
||||
private List<MPJTableFieldInfo> fieldList;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.baomidou.mybatisplus.core.metadata;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 实体类对应的mapper管理
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class MPJTableMapperHelper {
|
||||
|
||||
private static final Map<Class<?>, Class<?>> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
public static void init(Class<?> clazz, Class<?> mapper) {
|
||||
CACHE.put(clazz, mapper);
|
||||
}
|
||||
|
||||
public static Class<?> get(Class<?> clazz) {
|
||||
return CACHE.get(clazz);
|
||||
}
|
||||
}
|
102
src/main/java/com/github/yulichang/annotation/EntityMapping.java
Normal file
102
src/main/java/com/github/yulichang/annotation/EntityMapping.java
Normal file
@ -0,0 +1,102 @@
|
||||
package com.github.yulichang.annotation;
|
||||
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 实体类关系映射注解
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
|
||||
public @interface EntityMapping {
|
||||
|
||||
/**
|
||||
* 关联的数据库实体类<br/>
|
||||
* 默认获取此注解所对应的类
|
||||
*/
|
||||
Class<?> tag() default Object.class;
|
||||
|
||||
/**
|
||||
* 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
|
||||
* 默认获取当前类上定义的主键 @TableId
|
||||
*/
|
||||
String thisField() default "";
|
||||
|
||||
/**
|
||||
* 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
|
||||
* 默认获取关联类上定义的主键 @TableId
|
||||
*/
|
||||
String joinField() default "";
|
||||
|
||||
/**
|
||||
* 一对一查询时 如果查询到多条记录是否抛出异常<br/>
|
||||
* true 抛出异常<br/>
|
||||
* false 不抛异常,获取列表第一条数据<br/>
|
||||
*/
|
||||
boolean isThrowExp() default true;
|
||||
|
||||
/**
|
||||
* 针对查询结果map的时候使用<br/>
|
||||
* 默认为thisField对应的数据库列名<br/>
|
||||
* <p>
|
||||
* 如果此类是以map方式查询的<br/>
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
|
||||
*/
|
||||
String thisMapKey() default "";
|
||||
|
||||
/**
|
||||
* isMap为true时生效<br/>
|
||||
* 针对查询结果map的时候使用<br/>
|
||||
* 默认为joinField对应的数据库列名<br/>
|
||||
* <p>
|
||||
* 如果此类是以map方式查询的<br/>
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
|
||||
*/
|
||||
String joinMapKey() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 select<br/>
|
||||
* 等效于 Wrappers.<T>query().select(xxx);
|
||||
*/
|
||||
String select() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 first<br/>
|
||||
* 等效于 Wrappers.<T>query().first(xxx);
|
||||
*/
|
||||
String first() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 apply<br/>
|
||||
* 等效于 Wrappers.<T>query().apply(xxx);
|
||||
*/
|
||||
MPJMappingApply[] apply() default {};
|
||||
|
||||
/**
|
||||
* 映射表查询条件
|
||||
*/
|
||||
MPJMappingCondition[] condition() default {};
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 orderBy<br/>
|
||||
* 等效于 Wrappers.<T>query().orderByAsc(xxx);
|
||||
*/
|
||||
String orderByAsc() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 orderByDesc<br/>
|
||||
* 等效于 Wrappers.<T>query().orderByDesc(xxx);
|
||||
*/
|
||||
String orderByDesc() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 last<br/>
|
||||
* 建议不要在这使用分页语句,会导致关联查的时候查询不全<br/>
|
||||
* 等效于 Wrappers.<T>query().last(xxx);
|
||||
*/
|
||||
String last() default "";
|
||||
}
|
101
src/main/java/com/github/yulichang/annotation/FieldMapping.java
Normal file
101
src/main/java/com/github/yulichang/annotation/FieldMapping.java
Normal file
@ -0,0 +1,101 @@
|
||||
package com.github.yulichang.annotation;
|
||||
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 字段关系映射注解
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
|
||||
public @interface FieldMapping {
|
||||
|
||||
/**
|
||||
* 关联的数据库实体类<br/>
|
||||
* 默认获取此注解所对应的类
|
||||
*/
|
||||
Class<?> tag();
|
||||
|
||||
/**
|
||||
* 当前类的关联的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
|
||||
* 默认获取当前类上定义的主键 @TableId
|
||||
*/
|
||||
String thisField() default "";
|
||||
|
||||
/**
|
||||
* 关联类的字段名称 (是实体类字段名称而不是数据库字段名称)<br/>
|
||||
* 默认获取关联类上定义的主键 @TableId
|
||||
*/
|
||||
String joinField() default "";
|
||||
|
||||
/**
|
||||
* 一对一查询时 如果查询到多条记录是否抛出异常<br/>
|
||||
* true 抛出异常<br/>
|
||||
* false 不抛异常,获取列表第一条数据<br/>
|
||||
*/
|
||||
boolean isThrowExp() default true;
|
||||
|
||||
/**
|
||||
* 字段映射对应的属性名
|
||||
*/
|
||||
String select();
|
||||
|
||||
/**
|
||||
* 针对查询结果map的时候使用<br/>
|
||||
* 默认为thisField对应的数据库列名<br/>
|
||||
* <p>
|
||||
* 如果此类是以map方式查询的<br/>
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
|
||||
*/
|
||||
String thisMapKey() default "";
|
||||
|
||||
/**
|
||||
* isMap为true时生效<br/>
|
||||
* 针对查询结果map的时候使用<br/>
|
||||
* 默认为joinField对应的数据库列名<br/>
|
||||
* <p>
|
||||
* 如果此类是以map方式查询的<br/>
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
|
||||
*/
|
||||
String joinMapKey() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 first<br/>
|
||||
* 等效于 Wrappers.<T>query().first(xxx);
|
||||
*/
|
||||
String first() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 apply<br/>
|
||||
* 等效于 Wrappers.<T>query().apply(xxx);
|
||||
*/
|
||||
MPJMappingApply[] apply() default {};
|
||||
|
||||
/**
|
||||
* 映射表查询条件
|
||||
*/
|
||||
MPJMappingCondition[] condition() default {};
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 orderBy<br/>
|
||||
* 等效于 Wrappers.<T>query().orderByAsc(xxx);
|
||||
*/
|
||||
String orderByAsc() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 orderByDesc<br/>
|
||||
* 等效于 Wrappers.<T>query().orderByDesc(xxx);
|
||||
*/
|
||||
String orderByDesc() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 last<br/>
|
||||
* 建议不要在这使用分页语句,会导致关联查的时候查询不全<br/>
|
||||
* 等效于 Wrappers.<T>query().last(xxx);
|
||||
*/
|
||||
String last() default "";
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.github.yulichang.annotation;
|
||||
|
||||
/**
|
||||
* 映射表条件
|
||||
* 用法参考 mybatis plus wrapper 的 .apply()方法
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public @interface MPJMappingApply {
|
||||
|
||||
/**
|
||||
* sql片段
|
||||
*/
|
||||
String value();
|
||||
|
||||
/**
|
||||
* .apply() 对应的可变参数
|
||||
*/
|
||||
String[] args() default {};
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.github.yulichang.annotation;
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
||||
|
||||
/**
|
||||
* 映射表条件
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public @interface MPJMappingCondition {
|
||||
|
||||
/**
|
||||
* 条件枚举
|
||||
* 目前只实现了 = != > >= < <=
|
||||
* 其他的暂未实现 TODO
|
||||
*
|
||||
* @see SqlKeyword
|
||||
*/
|
||||
SqlKeyword keyWord() default SqlKeyword.EQ;
|
||||
|
||||
/**
|
||||
* 数据库列名
|
||||
*/
|
||||
String column();
|
||||
|
||||
/**
|
||||
* 对应的值
|
||||
* 一般是一个值
|
||||
* 如果条件是 between 会取前两个
|
||||
* 如果条件是 in 就会取全部
|
||||
*/
|
||||
String[] value();
|
||||
}
|
@ -0,0 +1,534 @@
|
||||
package com.github.yulichang.base.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
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.support.SFunction;
|
||||
import com.github.yulichang.toolkit.LambdaUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author yulichang
|
||||
* @see BaseMapper
|
||||
*/
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
|
||||
/**
|
||||
* 根据 ID 查询 并关联全部映射
|
||||
*
|
||||
* @param id 主键ID
|
||||
*/
|
||||
default T selectByIdDeep(Serializable 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据ID 批量查询)
|
||||
*
|
||||
* @param idList 主键ID列表(不能为 null 以及 empty)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询(根据 columnMap 条件)
|
||||
*
|
||||
* @param columnMap 表字段 map 对象
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询一条记录
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询全部记录
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper 条件,查询全部记录
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
default List<Map<String, Object>> selectMapsDeep(Class<T> clazz, Wrapper<T> queryWrapper) {
|
||||
return queryMapMapping(selectMaps(queryWrapper), clazz, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询全部记录(并翻页)
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param clazz 实体类class
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<Map<String, Object>> selectMapsDeep(Class<T> clazz, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return queryMapMapping(selectMaps(queryWrapper), clazz, Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectMapsDeep(UserDO.class, queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<Map<String, Object>> selectMapsDeep(Class<T> clazz, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return queryMapMapping(selectMaps(queryWrapper), clazz, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询全部记录(并翻页)
|
||||
*
|
||||
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
default <E extends IPage<T>> E selectPageDeep(E page, Wrapper<T> queryWrapper) {
|
||||
E e = selectPage(page, queryWrapper);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询全部记录(并翻页)
|
||||
*
|
||||
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
*/
|
||||
default <R, E extends IPage<Map<String, Object>>> E selectMapsPageDeep(E page, Class<T> clazz, Wrapper<T> queryWrapper) {
|
||||
E e = selectMapsPage(page, queryWrapper);
|
||||
queryMapMapping(e.getRecords(), clazz, null);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 entity 条件,查询全部记录(并翻页)
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<Map<String, Object>>> E selectMapsPageDeep(E page, Class<T> clazz, Wrapper<T> queryWrapper,
|
||||
SFunction<T, R>... property) {
|
||||
E e = selectMapsPage(page, queryWrapper);
|
||||
queryMapMapping(e.getRecords(), clazz, Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 针对可变参数堆污染提供的重载
|
||||
* list为null或空,会查询全部映射关系
|
||||
* <p>
|
||||
* 例: selectMapsPage(page, UserDO.class, queryWrapper, Arrays.asList(User::getId, ... ))
|
||||
*
|
||||
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
|
||||
* @param queryWrapper 实体对象封装操作类(可以为 null)
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R, E extends IPage<Map<String, Object>>> E selectMapsPageDeep(E page, Class<T> clazz, Wrapper<T> queryWrapper,
|
||||
List<SFunction<T, R>> property) {
|
||||
E e = selectMapsPage(page, queryWrapper);
|
||||
queryMapMapping(e.getRecords(), clazz, property);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param 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.isHasMappingOrField()) {
|
||||
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 obj = fieldInfo.thisFieldGet(t);
|
||||
if (obj != null) {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), obj, fieldInfo);
|
||||
bindData(t, fieldInfo, joinList);
|
||||
fieldInfo.removeJoinField(joinList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param map 第一次查询结果
|
||||
*/
|
||||
default <R> Map<String, Object> queryMapMapping(Map<String, Object> map, Class<T> clazz, List<SFunction<T, R>> property) {
|
||||
if (CollectionUtils.isEmpty(map)) {
|
||||
return map;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(clazz);
|
||||
if (tableInfo.isHasMappingOrField()) {
|
||||
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 obj = map.get(fieldInfo.getThisMapKey());
|
||||
if (obj != null) {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), obj, fieldInfo);
|
||||
bindMap(map, fieldInfo, joinList);
|
||||
fieldInfo.removeJoinField(joinList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param 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.isHasMappingOrField()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
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.isMappingEntity() && fieldInfo.isFieldIsMap(), SqlKeyword.IN,
|
||||
fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> bindData(i, fieldInfo, joinList));
|
||||
fieldInfo.removeJoinField(joinList);
|
||||
} else {
|
||||
list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param list 第一次查询结果
|
||||
*/
|
||||
default <R> List<Map<String, Object>> queryMapMapping(List<Map<String, Object>> list, Class<T> clazz, List<SFunction<T, R>> property) {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return list;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(clazz);
|
||||
if (tableInfo.isHasMappingOrField()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
|
||||
List<Object> itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(itemList)) {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isMappingEntity() && fieldInfo.isFieldIsMap(), SqlKeyword.IN,
|
||||
fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> bindMap(i, fieldInfo, joinList));
|
||||
fieldInfo.removeJoinField(joinList);
|
||||
} else {
|
||||
list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定数据
|
||||
*/
|
||||
default void bindData(T t, MPJTableFieldInfo fieldInfo, List<?> joinList) {
|
||||
if (fieldInfo.isMappingEntity()) {
|
||||
List<?> list = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(fieldInfo.thisFieldGet(t)))
|
||||
.collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bind(fieldInfo, t, list);
|
||||
}
|
||||
if (fieldInfo.isMappingField()) {
|
||||
MPJTableFieldInfo.bind(fieldInfo, t, joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(
|
||||
fieldInfo.thisFieldGet(t))).map(fieldInfo::bindFieldGet).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定数据
|
||||
*/
|
||||
default void bindMap(Map<String, Object> t, MPJTableFieldInfo fieldInfo, List<?> joinList) {
|
||||
List<?> list = null;
|
||||
if (fieldInfo.isMappingEntity()) {
|
||||
if (fieldInfo.isFieldIsMap()) {
|
||||
list = ((List<Map<String, Object>>) joinList).stream().filter(j ->
|
||||
j.get(fieldInfo.getJoinMapKey()).equals(t.get(fieldInfo.getThisMapKey())))
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
list = joinList.stream().filter(j ->
|
||||
fieldInfo.joinFieldGet(j).equals(t.get(fieldInfo.getThisMapKey())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
if (fieldInfo.isMappingField()) {
|
||||
list = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(
|
||||
t.get(fieldInfo.getThisMapKey()))).map(fieldInfo::bindFieldGet).collect(Collectors.toList());
|
||||
}
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, t, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射 wrapper 构造器
|
||||
* 仅对使用映射注解时使用
|
||||
*/
|
||||
default Object mappingWrapperConstructor(boolean selectMap, SqlKeyword keyword,
|
||||
String column, Object val, MPJTableFieldInfo fieldInfo) {
|
||||
MPJMappingWrapper infoWrapper = fieldInfo.getWrapper();
|
||||
MappingQuery<T> wrapper = new MappingQuery<>();
|
||||
if (infoWrapper.isHasCondition()) {
|
||||
infoWrapper.getConditionList().forEach(c -> wrapper.addCondition(true, c.getColumn(),
|
||||
c.getKeyword(), c.getVal()));
|
||||
}
|
||||
wrapper.eq(SqlKeyword.EQ == keyword, column, val)
|
||||
.first(infoWrapper.isHasFirst(), infoWrapper.getFirst())
|
||||
.orderByAsc(infoWrapper.isHasOrderByAsc(), infoWrapper.getOrderByAsc())
|
||||
.orderByDesc(infoWrapper.isHasOrderByDesc(), infoWrapper.getOrderByDesc())
|
||||
.last(infoWrapper.isHasLast(), infoWrapper.getLast());
|
||||
if (SqlKeyword.IN == keyword) {
|
||||
//由于Java发放调用机制 无法使用链式
|
||||
wrapper.in(column, (List<?>) val);
|
||||
}
|
||||
if (infoWrapper.isHasSelect()) {
|
||||
wrapper.select(infoWrapper.getSelect());
|
||||
}
|
||||
if (infoWrapper.isHasApply()) {
|
||||
infoWrapper.getApplyList().forEach(a -> wrapper.apply(a.getSql(), (Object[]) a.getVal()));
|
||||
}
|
||||
if (selectMap) {
|
||||
return selectMaps(wrapper);
|
||||
}
|
||||
return selectList(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公开 addCondition 方法
|
||||
*/
|
||||
class MappingQuery<T> extends QueryWrapper<T> {
|
||||
@Override
|
||||
public QueryWrapper<T> addCondition(boolean condition, String column, SqlKeyword sqlKeyword, Object val) {
|
||||
return super.addCondition(condition, column, sqlKeyword, val);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.github.yulichang.base.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.github.yulichang.interfaces.MPJBaseJoin;
|
||||
import com.github.yulichang.toolkit.Constant;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yulichang
|
||||
* @see BaseMapper
|
||||
*/
|
||||
public interface MPJJoinMapper<T> extends BaseMapper<T> {
|
||||
|
||||
/**
|
||||
* 根据 Wrapper 条件,查询总记录数
|
||||
*
|
||||
* @param wrapper joinWrapper
|
||||
*/
|
||||
Integer selectJoinCount(@Param(Constants.WRAPPER) MPJBaseJoin wrapper);
|
||||
|
||||
/**
|
||||
* 连表查询返回一条记录
|
||||
*
|
||||
* @param wrapper joinWrapper
|
||||
* @param clazz resultType
|
||||
*/
|
||||
<DTO> DTO selectJoinOne(@Param(Constant.CLAZZ) Class<DTO> clazz,
|
||||
@Param(Constants.WRAPPER) MPJBaseJoin wrapper);
|
||||
|
||||
/**
|
||||
* 连表查询返回Map
|
||||
*
|
||||
* @param wrapper joinWrapper
|
||||
*/
|
||||
Map<String, Object> selectJoinMap(@Param(Constants.WRAPPER) MPJBaseJoin wrapper);
|
||||
|
||||
/**
|
||||
* 连表查询返回记录集合
|
||||
*
|
||||
* @param wrapper joinWrapper
|
||||
* @param clazz resultType
|
||||
*/
|
||||
<DTO> List<DTO> selectJoinList(@Param(Constant.CLAZZ) Class<DTO> clazz,
|
||||
@Param(Constants.WRAPPER) MPJBaseJoin wrapper);
|
||||
|
||||
/**
|
||||
* 连表查询返回Map集合
|
||||
*
|
||||
* @param wrapper joinWrapper
|
||||
*/
|
||||
List<Map<String, Object>> selectJoinMaps(@Param(Constants.WRAPPER) MPJBaseJoin wrapper);
|
||||
|
||||
/**
|
||||
* 连表查询返回记录集合并分页
|
||||
*
|
||||
* @param wrapper joinWrapper
|
||||
* @param clazz resultType
|
||||
* @param <DTO> 分页返回对象
|
||||
*/
|
||||
<DTO, P extends IPage<?>> IPage<DTO> selectJoinPage(P page,
|
||||
@Param(Constant.CLAZZ) Class<DTO> clazz,
|
||||
@Param(Constants.WRAPPER) MPJBaseJoin wrapper);
|
||||
|
||||
/**
|
||||
* 连表查询返回Map集合并分页
|
||||
*
|
||||
* @param wrapper joinWrapper
|
||||
*/
|
||||
<P extends IPage<?>> IPage<Map<String, Object>> selectJoinMapsPage(P page,
|
||||
@Param(Constants.WRAPPER) MPJBaseJoin wrapper);
|
||||
}
|
@ -0,0 +1,556 @@
|
||||
package com.github.yulichang.base.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
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.EntityMapping;
|
||||
import com.github.yulichang.annotation.FieldMapping;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 深度查询
|
||||
* <p>
|
||||
* 对配置了映射注解的字段进行查询
|
||||
* 目前查询深度只支持2级(只解析当前实体类的映射注解,不会对查询结果再次解析注解)
|
||||
* 多级查询可能存在循环引用的问题,也可能会导致全量查询
|
||||
*
|
||||
* @author yulichang
|
||||
* @see EntityMapping
|
||||
* @see FieldMapping
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
public interface MPJDeepService<T> extends IService<T> {
|
||||
|
||||
Class<T> currentModelClass();
|
||||
|
||||
/**
|
||||
* 根据 ID 深度查询
|
||||
*
|
||||
* @param id 主键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 批量查询)
|
||||
*
|
||||
* @param idList 主键ID列表
|
||||
*/
|
||||
default List<T> listByIdsDeep(Collection<? extends Serializable> 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 条件)
|
||||
*
|
||||
* @param columnMap 表字段 map 对象
|
||||
*/
|
||||
default List<T> listByMapDeep(Map<String, Object> 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/>
|
||||
* <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default T getOneDeep(Wrapper<T> 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,查询一条记录
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
* @param throwEx 有多个 result 是否抛出异常
|
||||
*/
|
||||
default T getOneDeep(Wrapper<T> queryWrapper, boolean 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Wrapper,查询一条记录
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default Map<String, Object> getMapDeep(Wrapper<T> queryWrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(),
|
||||
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 ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(),
|
||||
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 ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default List<T> listDeep(Wrapper<T> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有
|
||||
*
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default List<T> listDeep() {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default <E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper) {
|
||||
E e = page(page, queryWrapper);
|
||||
((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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无条件翻页查询
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <E extends IPage<T>> E pageDeep(E page) {
|
||||
E e = page(page);
|
||||
((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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), 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 ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(),
|
||||
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 ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有列表
|
||||
*
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default List<Map<String, Object>> listMapsDeep() {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有列表
|
||||
* <p>
|
||||
* JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
|
||||
*
|
||||
* @param property 需要关联的字段
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(SFunction<T, R>... property) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), 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 ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻页查询
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper) {
|
||||
E e = pageMaps(page, queryWrapper);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), 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);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), 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);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无条件翻页查询
|
||||
*
|
||||
* @param page 翻页对象
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page) {
|
||||
E e = pageMaps(page);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), 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);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), 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);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property);
|
||||
return e;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.github.yulichang.base.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.github.yulichang.interfaces.MPJBaseJoin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yulichang
|
||||
* @see IService
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface MPJJoinService<T> extends IService<T> {
|
||||
|
||||
/**
|
||||
* 根据 Wrapper 条件,查询总记录数
|
||||
*/
|
||||
default Integer selectJoinCount(MPJBaseJoin wrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接查询返回一条记录
|
||||
*/
|
||||
default <DTO> DTO selectJoinOne(Class<DTO> clazz, MPJBaseJoin wrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinOne(clazz, wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接查询返回集合
|
||||
*/
|
||||
default <DTO> List<DTO> selectJoinList(Class<DTO> clazz, MPJBaseJoin wrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinList(clazz, wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接查询返回集合并分页
|
||||
*/
|
||||
default <DTO, P extends IPage<?>> IPage<DTO> selectJoinListPage(P page, Class<DTO> clazz, MPJBaseJoin wrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinPage(page, clazz, wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接查询返回Map
|
||||
*/
|
||||
default Map<String, Object> selectJoinMap(MPJBaseJoin wrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinMap(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接查询返回Map集合
|
||||
*/
|
||||
default List<Map<String, Object>> selectJoinMaps(MPJBaseJoin wrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinMaps(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接查询返回Map集合并分页
|
||||
*/
|
||||
default <P extends IPage<Map<String, Object>>> IPage<Map<String, Object>> selectJoinMapsPage(P page, MPJBaseJoin wrapper) {
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinMapsPage(page, wrapper);
|
||||
}
|
||||
}
|
22
src/main/java/com/github/yulichang/config/MappingConfig.java
Normal file
22
src/main/java/com/github/yulichang/config/MappingConfig.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.github.yulichang.config;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableMapperHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
||||
/**
|
||||
* 关系映射配置
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class MappingConfig implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
TableInfoHelper.getTableInfos().forEach(i ->
|
||||
MPJTableInfoHelper.initTableInfo(i.getEntityType(), MPJTableMapperHelper.get(i.getEntityType())));
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.github.yulichang.toolkit;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
* spring容器工具类
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class SpringContentUtils implements ApplicationContextAware {
|
||||
|
||||
private static ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
context = applicationContext;
|
||||
}
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user