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
2c5772d09d
commit
2659497f0a
@ -3,7 +3,6 @@ package com.baomidou.mybatisplus.core.metadata;
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.github.yulichang.annotation.MPJMapping;
|
||||
import com.github.yulichang.annotation.MPJMappingApply;
|
||||
import com.github.yulichang.annotation.MPJMappingCondition;
|
||||
import lombok.AllArgsConstructor;
|
||||
@ -36,36 +35,37 @@ public class MPJMappingWrapper {
|
||||
private final boolean hasLast;
|
||||
private String last;
|
||||
|
||||
public MPJMappingWrapper(MPJMapping mapping) {
|
||||
this.hasFirst = StringUtils.isNotBlank(mapping.first());
|
||||
public MPJMappingWrapper(String first, String select, MPJMappingApply[] applys,
|
||||
MPJMappingCondition[] conditions, String last) {
|
||||
this.hasFirst = StringUtils.isNotBlank(first);
|
||||
if (this.hasFirst) {
|
||||
this.first = mapping.first();
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
this.hasSelect = StringUtils.isNotBlank(mapping.select());
|
||||
this.hasSelect = StringUtils.isNotBlank(select);
|
||||
if (this.hasSelect) {
|
||||
this.select = mapping.select();
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
this.hasApply = mapping.apply().length > 0;
|
||||
this.hasApply = applys.length > 0;
|
||||
if (this.hasApply) {
|
||||
this.applyList = new ArrayList<>();
|
||||
for (MPJMappingApply apply : mapping.apply()) {
|
||||
for (MPJMappingApply apply : applys) {
|
||||
this.applyList.add(new Apply(apply.value(), apply.args()));
|
||||
}
|
||||
}
|
||||
|
||||
this.hasCondition = mapping.condition().length > 0;
|
||||
this.hasCondition = conditions.length > 0;
|
||||
if (this.hasCondition) {
|
||||
this.conditionList = new ArrayList<>();
|
||||
for (MPJMappingCondition condition : mapping.condition()) {
|
||||
for (MPJMappingCondition condition : conditions) {
|
||||
conditionList.add(new Condition(condition.keyWord(), condition.column(), condition.value()));
|
||||
}
|
||||
}
|
||||
|
||||
this.hasLast = StringUtils.isNotBlank(mapping.last());
|
||||
this.hasLast = StringUtils.isNotBlank(last);
|
||||
if (this.hasLast) {
|
||||
this.last = mapping.last();
|
||||
this.last = last;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,61 @@
|
||||
package com.baomidou.mybatisplus.core.metadata;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.github.yulichang.annotation.MPJTableAlias;
|
||||
import com.github.yulichang.toolkit.Constant;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 全局表别名控制,默认表别名为 t t1 t2 ... <br>
|
||||
* 可以通过@MPJTableAlias注解指定表别名<br/>
|
||||
* 仅对MPJLambdaWrapper有效
|
||||
*
|
||||
* @author yulichang
|
||||
* @see com.github.yulichang.wrapper.MPJLambdaWrapper
|
||||
* @see MPJTableAlias
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class MPJTableAliasHelper {
|
||||
|
||||
public static final Map<Class<?>, TableAlias> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 用于生成别名的序号
|
||||
*/
|
||||
private static final AtomicInteger index = new AtomicInteger(1);
|
||||
|
||||
public static void init(Class<?> clazz) {
|
||||
TableAlias alias = new TableAlias();
|
||||
MPJTableAlias tableAlias = clazz.getAnnotation(MPJTableAlias.class);
|
||||
if (tableAlias != null && StringUtils.isNotBlank(tableAlias.value())) {
|
||||
alias.setAlias(tableAlias.value());
|
||||
} else {
|
||||
alias.setAlias(Constant.TABLE_ALIAS + index.getAndIncrement());
|
||||
}
|
||||
alias.setAliasDOT(alias.getAlias() + StringPool.DOT);
|
||||
CACHE.put(clazz, alias);
|
||||
}
|
||||
|
||||
public static TableAlias get(Class<?> clazz) {
|
||||
return CACHE.get(clazz);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class TableAlias {
|
||||
/**
|
||||
* 表别名
|
||||
*/
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
private String aliasDOT;
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
package com.baomidou.mybatisplus.core.metadata;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.github.yulichang.annotation.MPJMapping;
|
||||
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;
|
||||
@ -15,6 +13,7 @@ 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;
|
||||
@ -31,6 +30,22 @@ import java.util.Map;
|
||||
@EqualsAndHashCode
|
||||
public class MPJTableFieldInfo {
|
||||
|
||||
/**
|
||||
* 是否是实体映射
|
||||
*/
|
||||
private final boolean isMappingEntity;
|
||||
/**
|
||||
* 是否是属性映射
|
||||
*/
|
||||
private final boolean isMappingField;
|
||||
/**
|
||||
* 字段映射是绑定的字段
|
||||
*/
|
||||
private Field bindField;
|
||||
/**
|
||||
* 是否移除绑定字段
|
||||
*/
|
||||
private final boolean isRemoveBindField;
|
||||
/**
|
||||
* 实体类
|
||||
*/
|
||||
@ -58,7 +73,7 @@ public class MPJTableFieldInfo {
|
||||
/**
|
||||
* 当前类实体属性
|
||||
*/
|
||||
private final String thisProperty;
|
||||
private String thisProperty;
|
||||
/**
|
||||
* 当前字段信息
|
||||
*/
|
||||
@ -74,7 +89,7 @@ public class MPJTableFieldInfo {
|
||||
/**
|
||||
* 映射属性名
|
||||
*/
|
||||
private final String joinProperty;
|
||||
private String joinProperty;
|
||||
/**
|
||||
* 映射属性数据库列名
|
||||
*/
|
||||
@ -105,33 +120,112 @@ public class MPJTableFieldInfo {
|
||||
/**
|
||||
* 初始化关联字段信息
|
||||
*/
|
||||
public MPJTableFieldInfo(Class<?> entityType, MPJMapping mapping, Field field) {
|
||||
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();
|
||||
this.thisMapKey = StringUtils.isBlank(mapping.thisMapKey()) ? null : mapping.thisMapKey();
|
||||
this.joinMapKey = StringUtils.isBlank(mapping.joinMapKsy()) ? null : mapping.joinMapKsy();
|
||||
this.wrapper = new MPJMappingWrapper(mapping);
|
||||
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());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
if (StringUtils.isNotBlank(mapping.joinField())) {
|
||||
this.joinProperty = mapping.joinField();
|
||||
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());
|
||||
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();
|
||||
}
|
||||
if (StringUtils.isNotBlank(mapping.thisField())) {
|
||||
this.thisProperty = mapping.thisField();
|
||||
|
||||
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, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(),
|
||||
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
|
||||
Assert.notNull(this.joinColumn, "MPJMapping注解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, "MPJMapping注解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, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(),
|
||||
StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty);
|
||||
assert fieldInfo != null;
|
||||
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) {
|
||||
@ -139,7 +233,9 @@ public class MPJTableFieldInfo {
|
||||
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 {
|
||||
@ -156,83 +252,16 @@ public class MPJTableFieldInfo {
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
public Field getThisField() {
|
||||
if (this.thisField == null) {
|
||||
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, "MPJMapping注解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, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(),
|
||||
StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty);
|
||||
this.thisField = fieldInfo.getField();
|
||||
this.thisColumn = fieldInfo.getColumn();
|
||||
}
|
||||
this.thisField.setAccessible(true);
|
||||
}
|
||||
return this.thisField;
|
||||
}
|
||||
|
||||
public String getJoinColumn() {
|
||||
if (StringUtils.isBlank(this.joinColumn)) {
|
||||
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);
|
||||
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.joinColumn = joinFieldInfo.getColumn();
|
||||
this.joinField = joinFieldInfo.getField();
|
||||
this.joinClass = field.getType();
|
||||
}
|
||||
Assert.notNull(this.joinField, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(),
|
||||
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
|
||||
Assert.notNull(this.joinColumn, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(),
|
||||
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
|
||||
this.joinField.setAccessible(true);
|
||||
}
|
||||
return this.joinColumn;
|
||||
}
|
||||
|
||||
public String getThisMapKey() {
|
||||
if (this.thisMapKey == null) {
|
||||
this.thisMapKey = getJoinColumn();
|
||||
}
|
||||
return this.thisMapKey;
|
||||
}
|
||||
|
||||
public Field getJoinField() {
|
||||
if (this.joinField == null) {
|
||||
this.getJoinColumn();
|
||||
}
|
||||
return this.joinField;
|
||||
}
|
||||
|
||||
|
||||
public String getJoinMapKey() {
|
||||
if (this.joinMapKey == null) {
|
||||
this.joinMapKey = getJoinColumn();
|
||||
}
|
||||
return joinMapKey;
|
||||
}
|
||||
|
||||
public MPJBaseMapper<?> getJoinMapper() {
|
||||
@ -283,6 +312,35 @@ public class MPJTableFieldInfo {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@ -308,6 +366,4 @@ public class MPJTableFieldInfo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -25,27 +25,27 @@ public class MPJTableInfo {
|
||||
private TableInfo tableInfo;
|
||||
|
||||
/**
|
||||
* 表别名
|
||||
* 是否包含 MPJMapping 或者 MPJMappingField
|
||||
*/
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
private String aliasDOT;
|
||||
private boolean hasMappingOrField;
|
||||
|
||||
/**
|
||||
* 是否包含映射注解
|
||||
*/
|
||||
private boolean hasMapping;
|
||||
|
||||
/**
|
||||
* 是否包含映射注解
|
||||
*/
|
||||
private boolean hasMappingField;
|
||||
|
||||
/**
|
||||
* mapperClass
|
||||
*/
|
||||
private Class<?> mapperClass;
|
||||
|
||||
/**
|
||||
* 包含映射注解的字段列表
|
||||
* 包含映射实体注解的字段列表
|
||||
*/
|
||||
private List<MPJTableFieldInfo> fieldList;
|
||||
}
|
||||
|
@ -3,9 +3,8 @@ package com.baomidou.mybatisplus.core.metadata;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||
import com.github.yulichang.annotation.MPJMapping;
|
||||
import com.github.yulichang.annotation.MPJTableAlias;
|
||||
import com.github.yulichang.toolkit.Constant;
|
||||
import com.github.yulichang.annotation.EntityMapping;
|
||||
import com.github.yulichang.annotation.FieldMapping;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
@ -19,7 +18,6 @@ import org.apache.ibatis.session.Configuration;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@ -37,10 +35,6 @@ import static java.util.stream.Collectors.toList;
|
||||
*/
|
||||
public class MPJTableInfoHelper {
|
||||
|
||||
/**
|
||||
* 用于生成别名的序号
|
||||
*/
|
||||
private static final AtomicInteger index = new AtomicInteger(1);
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TableInfoHelper.class);
|
||||
|
||||
@ -124,7 +118,6 @@ public class MPJTableInfoHelper {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
|
||||
if (tableInfo != null) {
|
||||
mpjTableInfo.setTableInfo(tableInfo);
|
||||
initTableAlias(mpjTableInfo);
|
||||
initMapping(mpjTableInfo);
|
||||
/* 添加缓存 */
|
||||
TABLE_INFO_CACHE.put(clazz, mpjTableInfo);
|
||||
@ -154,24 +147,11 @@ public class MPJTableInfoHelper {
|
||||
/* 缓存 lambda */
|
||||
LambdaUtils.installCache(tableInfo);
|
||||
|
||||
/* 初始化表别名 */
|
||||
initTableAlias(mpjTableInfo);
|
||||
|
||||
/* 初始化映射关系 */
|
||||
initMapping(mpjTableInfo);
|
||||
return mpjTableInfo;
|
||||
}
|
||||
|
||||
private static void initTableAlias(MPJTableInfo tableInfo) {
|
||||
MPJTableAlias tableAlias = tableInfo.getTableInfo().getEntityType().getAnnotation(MPJTableAlias.class);
|
||||
if (tableAlias != null && StringUtils.isNotBlank(tableAlias.value())) {
|
||||
tableInfo.setAlias(tableAlias.value());
|
||||
return;
|
||||
}
|
||||
tableInfo.setAlias(Constant.TABLE_ALIAS + index.getAndIncrement());
|
||||
tableInfo.setAliasDOT(tableInfo.getAlias() + StringPool.DOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动构建 resultMap 并注入(如果条件符合的话)
|
||||
*/
|
||||
@ -371,7 +351,11 @@ public class MPJTableInfoHelper {
|
||||
}
|
||||
|
||||
private static boolean isExistMapping(Class<?> clazz) {
|
||||
return ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz)).stream().anyMatch(field -> field.isAnnotationPresent(MPJMapping.class));
|
||||
return ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz)).stream().anyMatch(field -> field.isAnnotationPresent(EntityMapping.class));
|
||||
}
|
||||
|
||||
private static boolean isExistMappingField(Class<?> clazz) {
|
||||
return ReflectionKit.getFieldList(ClassUtils.getUserClass(clazz)).stream().anyMatch(field -> field.isAnnotationPresent(FieldMapping.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -512,12 +496,22 @@ public class MPJTableInfoHelper {
|
||||
// 是否存在 @MPJMapping 注解
|
||||
boolean existMapping = isExistMapping(mpjTableInfo.getTableInfo().getEntityType());
|
||||
mpjTableInfo.setHasMapping(existMapping);
|
||||
// 是否存在 @MPJMappingField 注解
|
||||
boolean existMappingField = isExistMappingField(mpjTableInfo.getTableInfo().getEntityType());
|
||||
mpjTableInfo.setHasMappingField(existMappingField);
|
||||
mpjTableInfo.setHasMappingOrField(existMapping || existMappingField);
|
||||
/* 关系映射初始化 */
|
||||
List<MPJTableFieldInfo> mpjFieldList = new ArrayList<>();
|
||||
List<Field> fields = ReflectionKit.getFieldList(ClassUtils.getUserClass(mpjTableInfo.getTableInfo().getEntityType()));
|
||||
for (Field field : fields) {
|
||||
if (existMapping) {
|
||||
MPJMapping mapping = field.getAnnotation(MPJMapping.class);
|
||||
EntityMapping mapping = field.getAnnotation(EntityMapping.class);
|
||||
if (mapping != null) {
|
||||
mpjFieldList.add(new MPJTableFieldInfo(mpjTableInfo.getTableInfo().getEntityType(), mapping, field));
|
||||
}
|
||||
}
|
||||
if (existMappingField) {
|
||||
FieldMapping mapping = field.getAnnotation(FieldMapping.class);
|
||||
if (mapping != null) {
|
||||
mpjFieldList.add(new MPJTableFieldInfo(mpjTableInfo.getTableInfo().getEntityType(), mapping, field));
|
||||
}
|
||||
@ -526,5 +520,4 @@ public class MPJTableInfoHelper {
|
||||
/* 映射字段列表 */
|
||||
mpjTableInfo.setFieldList(mpjFieldList);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ package com.github.yulichang.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 关系映射注解
|
||||
* 实体类关系映射注解
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.2.0
|
||||
@ -12,7 +12,7 @@ import java.lang.annotation.*;
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
|
||||
public @interface MPJMapping {
|
||||
public @interface EntityMapping {
|
||||
|
||||
/**
|
||||
* 关联的数据库实体类<br/>
|
||||
@ -56,7 +56,7 @@ public @interface MPJMapping {
|
||||
* 如果此类是以map方式查询的<br/>
|
||||
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
|
||||
*/
|
||||
String joinMapKsy() default "";
|
||||
String joinMapKey() default "";
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 select<br/>
|
@ -0,0 +1,89 @@
|
||||
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 {};
|
||||
|
||||
/**
|
||||
* 映射表查询条件之 last<br/>
|
||||
* 建议不要在这使用分页语句,会导致关联查的时候查询不全<br/>
|
||||
* 等效于 Wrappers.<T>query().last(xxx);
|
||||
*/
|
||||
String last() default "";
|
||||
}
|
@ -3,12 +3,12 @@ package com.github.yulichang.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 关联查询时的表别名
|
||||
* 框架默认会随机生成 一般是 t1 t2 t3 ...
|
||||
* 不要在程序中使用随机别名,运行期间是不变的,但是重启就不一定了
|
||||
* 如需使用请配合此注解一起使用
|
||||
* 关联查询时的表别名<br/>
|
||||
* 框架默认会随机生成 一般是 t1 t2 t3 ...<br/>
|
||||
* 不要在程序中使用随机别名,运行期间是不变的,但是重启就不一定了<br/>
|
||||
* 如需使用请配合此注解一起使用<br/>
|
||||
* <p>
|
||||
* 这个注解定义的表别名或者随机生成的别名只对MPJLambdaWrapper生效
|
||||
* 这个注解定义的表别名或者随机生成的别名只对MPJLambdaWrapper生效<br/>
|
||||
* 对MPJQueryWrapper不生效,
|
||||
*
|
||||
* @author yulichang
|
||||
@ -21,5 +21,5 @@ import java.lang.annotation.*;
|
||||
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
|
||||
public @interface MPJTableAlias {
|
||||
|
||||
String value() default "";
|
||||
String value();
|
||||
}
|
||||
|
@ -190,6 +190,40 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
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 条件,查询全部记录(并翻页)
|
||||
@ -234,6 +268,54 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
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/>
|
||||
@ -247,17 +329,18 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
return null;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
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 get = fieldInfo.thisFieldGet(t);
|
||||
if (get != null) {
|
||||
List<?> o = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(fieldInfo.isFieldIsMap(),
|
||||
SqlKeyword.EQ, fieldInfo.getJoinColumn(), get, fieldInfo);
|
||||
MPJTableFieldInfo.bind(fieldInfo, t, o);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,6 +348,38 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
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/>
|
||||
@ -278,7 +393,7 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
return list;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
if (tableInfo.isHasMappingOrField()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
@ -287,12 +402,10 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
List<Object> itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(itemList)) {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<?> data = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j)
|
||||
.equals(fieldInfo.thisFieldGet(i))).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bind(fieldInfo, i, data);
|
||||
});
|
||||
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<>()));
|
||||
}
|
||||
@ -302,9 +415,83 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
|
||||
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 构造器
|
||||
* 仅对使用 @MPJMapping 时使用
|
||||
* 仅对使用映射注解时使用
|
||||
*/
|
||||
default Object mappingWrapperConstructor(boolean selectMap, SqlKeyword keyword,
|
||||
String column, Object val, MPJTableFieldInfo fieldInfo) {
|
||||
|
@ -1,22 +1,18 @@
|
||||
package com.github.yulichang.base.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableFieldInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.github.yulichang.annotation.MPJMapping;
|
||||
import com.github.yulichang.annotation.EntityMapping;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.github.yulichang.toolkit.LambdaUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 深度查询
|
||||
@ -26,7 +22,7 @@ import java.util.stream.Collectors;
|
||||
* 多级查询可能存在循环引用的问题,也可能会导致全量查询
|
||||
*
|
||||
* @author yulichang
|
||||
* @see MPJMapping
|
||||
* @see EntityMapping
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
@ -217,7 +213,8 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default Map<String, Object> getMapDeep(Wrapper<T> queryWrapper) {
|
||||
return queryMapMapping(getMap(queryWrapper), null);
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(),
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,7 +226,8 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return queryMapMapping(getMap(queryWrapper), Arrays.asList(property));
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(),
|
||||
Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,7 +240,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return queryMapMapping(getMap(queryWrapper), property);
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(getMap(queryWrapper), currentModelClass(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -405,7 +403,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
|
||||
*/
|
||||
default List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper) {
|
||||
return queryMapMapping(listMaps(queryWrapper), null);
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -417,7 +415,8 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
|
||||
return queryMapMapping(listMaps(queryWrapper), Arrays.asList(property));
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(),
|
||||
Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -430,7 +429,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @param property 需要关联的字段
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
|
||||
return queryMapMapping(listMaps(queryWrapper), property);
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(queryWrapper), currentModelClass(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -439,7 +438,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default List<Map<String, Object>> listMapsDeep() {
|
||||
return queryMapMapping(listMaps(), null);
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -451,7 +450,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(SFunction<T, R>... property) {
|
||||
return queryMapMapping(listMaps(), Arrays.asList(property));
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), Arrays.asList(property));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -464,7 +463,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
* @see Wrappers#emptyWrapper()
|
||||
*/
|
||||
default <R> List<Map<String, Object>> listMapsDeep(List<SFunction<T, R>> property) {
|
||||
return queryMapMapping(listMaps(), property);
|
||||
return ((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(listMaps(), currentModelClass(), property);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -475,7 +474,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper) {
|
||||
E e = pageMaps(page, queryWrapper);
|
||||
queryMapMapping(e.getRecords(), null);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), null);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -490,7 +489,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
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));
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -506,7 +505,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
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);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -518,7 +517,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page) {
|
||||
E e = pageMaps(page);
|
||||
queryMapMapping(e.getRecords(), null);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), null);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -533,7 +532,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
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));
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -549,90 +548,7 @@ public interface MPJDeepService<T> extends IService<T> {
|
||||
*/
|
||||
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);
|
||||
((MPJBaseMapper<T>) getBaseMapper()).queryMapMapping(e.getRecords(), currentModelClass(), property);
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param map 第一次查询结果
|
||||
*/
|
||||
default <R> Map<String, Object> queryMapMapping(Map<String, Object> map, List<SFunction<T, R>> property) {
|
||||
if (CollectionUtils.isNotEmpty(map)) {
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> list = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
if (!hasProperty || list.contains(fieldInfo.getProperty())) {
|
||||
Object o = map.get(fieldInfo.getThisMapKey());
|
||||
if (o != null) {
|
||||
List<?> data = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), o, fieldInfo);
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, map, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射关系<br/>
|
||||
* 对结果进行二次查询<br/>
|
||||
* 可以自行查询然后在通过此方法进行二次查询<br/>
|
||||
* list为null或空,会查询全部映射关系<br/>
|
||||
*
|
||||
* @param list 第一次查询结果
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default <R> List<Map<String, Object>> queryMapMapping(List<Map<String, Object>> list, List<SFunction<T, R>> property) {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return list;
|
||||
}
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(currentModelClass());
|
||||
if (tableInfo.isHasMapping()) {
|
||||
boolean hasProperty = CollectionUtils.isNotEmpty(property);
|
||||
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
|
||||
Collectors.toList()) : null;
|
||||
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
|
||||
if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
|
||||
List<Object> itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(itemList)) {
|
||||
if (fieldInfo.isFieldIsMap()) {
|
||||
List<Map<String, Object>> joinList = (List<Map<String, Object>>) fieldInfo.getJoinMapper()
|
||||
.mappingWrapperConstructor(fieldInfo.isFieldIsMap(), SqlKeyword.IN,
|
||||
fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<Map<String, Object>> data = joinList.stream().filter(j -> j.containsKey(
|
||||
fieldInfo.getJoinMapKey()) && j.get(fieldInfo.getJoinMapKey()).equals(
|
||||
i.get(fieldInfo.getThisMapKey()))).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, i, data);
|
||||
});
|
||||
} else {
|
||||
List<?> joinList = (List<?>) fieldInfo.getJoinMapper().mappingWrapperConstructor(
|
||||
fieldInfo.isFieldIsMap(), SqlKeyword.IN, fieldInfo.getJoinColumn(), itemList, fieldInfo);
|
||||
list.forEach(i -> {
|
||||
List<?> data = joinList.stream().filter(j -> {
|
||||
Object o = fieldInfo.joinFieldGet(j);
|
||||
return o != null && o.equals(i.get(fieldInfo.getThisMapKey()));
|
||||
}).collect(Collectors.toList());
|
||||
MPJTableFieldInfo.bindMap(fieldInfo, i, data);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
@ -3,21 +3,17 @@ package com.github.yulichang.injector;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.mapper.Mapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
||||
import com.github.yulichang.method.*;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* SQL 注入器
|
||||
@ -28,8 +24,6 @@ import java.util.Set;
|
||||
@ConditionalOnMissingBean(DefaultSqlInjector.class)
|
||||
public class MPJSqlInjector extends DefaultSqlInjector {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(MPJSqlInjector.class);
|
||||
|
||||
@Override
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
|
||||
List<AbstractMethod> list = super.getMethodList(mapperClass);
|
||||
@ -45,23 +39,10 @@ public class MPJSqlInjector extends DefaultSqlInjector {
|
||||
|
||||
@Override
|
||||
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
|
||||
Class<?> modelClass = getSuperClassGenericType(mapperClass, Mapper.class, 0);
|
||||
if (modelClass != null) {
|
||||
String className = mapperClass.toString();
|
||||
Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
|
||||
if (!mapperRegistryCache.contains(className)) {
|
||||
List<AbstractMethod> methodList = this.getMethodList(mapperClass);
|
||||
if (CollectionUtils.isNotEmpty(methodList)) {
|
||||
TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);
|
||||
MPJTableInfoHelper.initTableInfo(builderAssistant, modelClass, mapperClass);
|
||||
// 循环注入自定义方法
|
||||
methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
|
||||
} else {
|
||||
logger.debug(mapperClass.toString() + ", No effective injection method was found.");
|
||||
}
|
||||
mapperRegistryCache.add(className);
|
||||
}
|
||||
}
|
||||
MPJTableAliasHelper.init(Objects.requireNonNull(getSuperClassGenericType(mapperClass, Mapper.class, 0)));
|
||||
super.inspectInject(builderAssistant, mapperClass);
|
||||
TableInfoHelper.getTableInfos().forEach(i ->
|
||||
MPJTableInfoHelper.initTableInfo(builderAssistant, i.getEntityType(), mapperClass));
|
||||
}
|
||||
|
||||
public static Class<?> getSuperClassGenericType(final Class<?> clazz, final Class<?> genericIfc, final int index) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.github.yulichang.method;
|
||||
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
|
||||
@ -40,7 +40,7 @@ public abstract class MPJAbstractMethod extends AbstractMethod {
|
||||
String[] columns = selectColumns.split(StringPool.COMMA);
|
||||
List<String> selectColumnList = new ArrayList<>();
|
||||
for (String c : columns) {
|
||||
selectColumnList.add(MPJTableInfoHelper.getTableInfo(table.getEntityType()).getAlias() + StringPool.DOT + c);
|
||||
selectColumnList.add(MPJTableAliasHelper.get(table.getEntityType()).getAlias() + StringPool.DOT + c);
|
||||
}
|
||||
selectColumns = String.join(StringPool.COMMA, selectColumnList);
|
||||
}
|
||||
@ -60,7 +60,7 @@ public abstract class MPJAbstractMethod extends AbstractMethod {
|
||||
|
||||
protected String sqlAlias(Class<?> modelClass) {
|
||||
return SqlScriptUtils.convertChoose(String.format("%s != null and %s != ''", "ew.autoAlias", "ew.autoAlias"),
|
||||
MPJTableInfoHelper.getTableInfo(modelClass).getAlias(), "${ew.alias}");
|
||||
MPJTableAliasHelper.get(modelClass).getAlias(), "${ew.alias}");
|
||||
}
|
||||
|
||||
protected String sqlFrom() {
|
||||
|
@ -194,6 +194,7 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
|
||||
* @param clazz 表实体
|
||||
* @param as 表别名
|
||||
*/
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public final MPJLambdaQueryWrapper<T> selectAll(Class<?> clazz, String as) {
|
||||
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
||||
Assert.notNull(info, "can not find table info");
|
||||
|
@ -189,6 +189,7 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
|
||||
/**
|
||||
* 返回一个支持 lambda 函数写法的 wrapper
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public MPJLambdaQueryWrapper<T> lambda() {
|
||||
return new MPJLambdaQueryWrapper<>(getEntity(), getEntityClass(), from, sqlSelect, paramNameSeq, paramNameValuePairs,
|
||||
expression, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns);
|
||||
|
@ -6,6 +6,7 @@ import com.github.yulichang.toolkit.Constant;
|
||||
/**
|
||||
* @author yulichang
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface MPJJoin<Children> extends MPJBaseJoin {
|
||||
|
||||
default Children leftJoin(String joinSql) {
|
||||
|
@ -11,8 +11,6 @@ public interface Constant {
|
||||
*/
|
||||
String TABLE_ALIAS = "t";
|
||||
|
||||
String AS = " AS ";
|
||||
|
||||
String ON = " ON ";
|
||||
|
||||
String JOIN = "JOIN";
|
||||
|
@ -84,6 +84,7 @@ public final class LambdaUtils {
|
||||
*
|
||||
* @param tableInfo 表信息
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static void installCache(TableInfo tableInfo) {
|
||||
COLUMN_CACHE_MAP.put(tableInfo.getEntityType().getName(), createColumnCacheMap(tableInfo));
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import static java.util.stream.Collectors.toMap;
|
||||
* @author hcl
|
||||
* @since 2016-09-22
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class ReflectionKit {
|
||||
private static final Log logger = LogFactory.getLog(ReflectionKit.class);
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
*
|
||||
* @author yulichang
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class Wrappers {
|
||||
|
||||
/**
|
||||
|
@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* copy mp before 3.4.3 {@link com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda}
|
||||
* copy mp before 3.4.3
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SerializedLambda implements Serializable {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.github.yulichang.wrapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
@ -42,7 +42,7 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
||||
}
|
||||
|
||||
protected String columnToString(SFunction<?, ?> column, boolean hasAlias) {
|
||||
return (hasAlias ? MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(column)).getAliasDOT() :
|
||||
return (hasAlias ? MPJTableAliasHelper.get(LambdaUtils.getEntityClass(column)).getAliasDOT() :
|
||||
StringPool.EMPTY) + getCache(column).getColumn();
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
||||
MPJLambdaWrapper(Class<?> entityClass, AtomicInteger paramNameSeq,
|
||||
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
|
||||
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, boolean hasAlias) {
|
||||
this.entityClass =entityClass;
|
||||
this.entityClass = entityClass;
|
||||
this.paramNameSeq = paramNameSeq;
|
||||
this.paramNameValuePairs = paramNameValuePairs;
|
||||
this.expression = mergeSegments;
|
||||
@ -107,9 +107,9 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
||||
public <E> MPJLambdaWrapper<T> select(Class<E> entityClass, Predicate<TableFieldInfo> predicate) {
|
||||
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
|
||||
Assert.notNull(info, "table can not be find");
|
||||
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(entityClass);
|
||||
MPJTableAliasHelper.TableAlias alias = MPJTableAliasHelper.get(entityClass);
|
||||
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(i ->
|
||||
selectColumns.add((hasAlias ? tableInfo.getAliasDOT() : StringPool.EMPTY) + i.getColumn()));
|
||||
selectColumns.add((hasAlias ? alias.getAliasDOT() : StringPool.EMPTY) + i.getColumn()));
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
||||
public final MPJLambdaWrapper<T> selectAll(Class<?> clazz) {
|
||||
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
||||
Assert.notNull(info, "table can not be find -> %s", clazz);
|
||||
String dot = hasAlias ? MPJTableInfoHelper.getTableInfo(clazz).getAliasDOT() : StringPool.EMPTY;
|
||||
String dot = hasAlias ? MPJTableAliasHelper.get(clazz).getAliasDOT() : StringPool.EMPTY;
|
||||
if (info.havePK()) {
|
||||
selectColumns.add(dot + info.getKeyColumn());
|
||||
}
|
||||
@ -211,14 +211,14 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
||||
public <R> MPJLambdaWrapper<T> join(String keyWord, boolean condition, Class<R> clazz, OnFunction function) {
|
||||
if (condition) {
|
||||
joinSql.add(keyWord + TableInfoHelper.getTableInfo(clazz).getTableName() +
|
||||
Constants.SPACE + MPJTableInfoHelper.getTableInfo(clazz).getAlias() +
|
||||
Constants.SPACE + MPJTableAliasHelper.get(clazz).getAlias() +
|
||||
Constant.ON + function.apply(instance()).getExpression().getNormal().getSqlSegment());
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
private String getThisAlias(SFunction<?, ?> function) {
|
||||
return hasAlias ? MPJTableInfoHelper.getTableInfo(LambdaUtils.getEntityClass(function)).getAliasDOT() :
|
||||
return hasAlias ? MPJTableAliasHelper.get(LambdaUtils.getEntityClass(function)).getAliasDOT() :
|
||||
StringPool.EMPTY;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import java.util.function.BiPredicate;
|
||||
* <p>
|
||||
* {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare}
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Compare<Children> extends Serializable {
|
||||
|
||||
/**
|
||||
@ -65,6 +66,7 @@ public interface Compare<Children> extends Serializable {
|
||||
/**
|
||||
* ignore
|
||||
*/
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
default <R> Children eq(SFunction<R, ?> column, Object val) {
|
||||
return eq(true, column, val);
|
||||
}
|
||||
|
@ -11,12 +11,13 @@ import java.util.function.Consumer;
|
||||
* <p>
|
||||
* copy {@link com.baomidou.mybatisplus.core.conditions.interfaces.Func}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({"unchecked", "unused"})
|
||||
public interface Func<Children> extends Serializable {
|
||||
|
||||
/**
|
||||
* ignore
|
||||
*/
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
default <R> Children isNull(SFunction<R, ?> column) {
|
||||
return isNull(true, column);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import java.io.Serializable;
|
||||
* 无改动 在mybatis 3.4.2 升级 3.4.3 后有改动 exists 和 not exists
|
||||
* 为了保证 mybatis plus 3.4.3之前的也能正常使用
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface Join<Children> extends Serializable {
|
||||
|
||||
/**
|
||||
|
@ -8,55 +8,120 @@ import com.github.yulichang.wrapper.interfaces.on.OnFunction;
|
||||
/**
|
||||
* @author yulichang
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface LambdaJoin<Children> extends MPJBaseJoin {
|
||||
|
||||
/**
|
||||
* left join
|
||||
*
|
||||
* @param clazz 关联的实体类
|
||||
* @param left 条件
|
||||
* @param right 条件
|
||||
*/
|
||||
default <T, X> Children leftJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
|
||||
return leftJoin(true, clazz, left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* left join
|
||||
* <p>
|
||||
* 例 leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
|
||||
*
|
||||
* @param clazz 关联的实体类
|
||||
* @param function 条件
|
||||
*/
|
||||
default <T> Children leftJoin(Class<T> clazz, OnFunction function) {
|
||||
return leftJoin(true, clazz, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* left join
|
||||
*
|
||||
* @param condition 是否执行
|
||||
* @param clazz 关联的实体类
|
||||
* @param left 条件
|
||||
* @param right 条件
|
||||
*/
|
||||
default <T, X> Children leftJoin(boolean condition, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
|
||||
return leftJoin(condition, clazz, on -> on.eq(left, right));
|
||||
}
|
||||
|
||||
/**
|
||||
* left join
|
||||
* <p>
|
||||
* 例 leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
|
||||
*
|
||||
* @param condition 是否执行
|
||||
* @param clazz 关联实体类
|
||||
* @param function 条件
|
||||
*/
|
||||
default <T> Children leftJoin(boolean condition, Class<T> clazz, OnFunction function) {
|
||||
return join(Constant.LEFT_JOIN, condition, clazz, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T, X> Children rightJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
|
||||
return rightJoin(true, clazz, left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children rightJoin(Class<T> clazz, OnFunction function) {
|
||||
return rightJoin(true, clazz, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T, X> Children rightJoin(boolean condition, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
|
||||
return rightJoin(condition, clazz, on -> on.eq(left, right));
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children rightJoin(boolean condition, Class<T> clazz, OnFunction function) {
|
||||
return join(Constant.RIGHT_JOIN, condition, clazz, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T, X> Children innerJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
|
||||
return innerJoin(true, clazz, left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children innerJoin(Class<T> clazz, OnFunction function) {
|
||||
return innerJoin(true, clazz, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T, X> Children innerJoin(boolean condition, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
|
||||
return innerJoin(condition, clazz, on -> on.eq(left, right));
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children innerJoin(boolean condition, Class<T> clazz, OnFunction function) {
|
||||
return join(Constant.INNER_JOIN, condition, clazz, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询基类 可以直接调用此方法实现以上所有功能
|
||||
*
|
||||
* @param keyWord 连表关键字
|
||||
* @param condition 是否执行
|
||||
* @param clazz 连表实体类
|
||||
* @param function 关联条件
|
||||
*/
|
||||
<T> Children join(String keyWord, boolean condition, Class<T> clazz, OnFunction function);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user