feat: Relation 注解添加支持递归查询的功能

This commit is contained in:
开源海哥 2023-07-12 10:14:08 +08:00
parent d88aeb7cc5
commit 767eaf293d
3 changed files with 77 additions and 71 deletions

View File

@ -68,7 +68,6 @@ public @interface RelationManyToMany {
*/ */
String orderBy() default ""; String orderBy() default "";
/** /**
* 默认使用哪个数据源若系统找不到该指定的数据源时默认使用第一个数据源 * 默认使用哪个数据源若系统找不到该指定的数据源时默认使用第一个数据源
*/ */

View File

@ -32,7 +32,6 @@ public @interface RelationManyToOne {
*/ */
String selfField(); String selfField();
/** /**
* 目标对象的关联属性 * 目标对象的关联属性
* *

View File

@ -28,9 +28,7 @@ import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.util.MapUtil; import org.apache.ibatis.util.MapUtil;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
@ -38,83 +36,93 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
public class RelationManager { public class RelationManager {
private static Map<Class<?>, List<AbstractRelation>> classRelations = new ConcurrentHashMap<>(); private static Map<Class<?>, List<AbstractRelation>> classRelations = new ConcurrentHashMap<>();
private static List<AbstractRelation> getRelations(Class<?> clazz) { private static List<AbstractRelation> getRelations(Class<?> clazz) {
return MapUtil.computeIfAbsent(classRelations, clazz, RelationManager::doGetRelations); return MapUtil.computeIfAbsent(classRelations, clazz, RelationManager::doGetRelations);
} }
private static List<AbstractRelation> doGetRelations(Class<?> entityClass) { private static List<AbstractRelation> doGetRelations(Class<?> entityClass) {
List<Field> allFields = ClassUtil.getAllFields(entityClass); List<Field> allFields = ClassUtil.getAllFields(entityClass);
List<AbstractRelation> relations = new ArrayList<>(); List<AbstractRelation> relations = new ArrayList<>();
for (Field field : allFields) { for (Field field : allFields) {
RelationManyToMany manyToManyAnnotation = field.getAnnotation(RelationManyToMany.class); RelationManyToMany manyToManyAnnotation = field.getAnnotation(RelationManyToMany.class);
if (manyToManyAnnotation != null) { if (manyToManyAnnotation != null) {
relations.add(new ManyToMany<>(manyToManyAnnotation, entityClass, field)); relations.add(new ManyToMany<>(manyToManyAnnotation, entityClass, field));
} }
RelationManyToOne manyToOneAnnotation = field.getAnnotation(RelationManyToOne.class); RelationManyToOne manyToOneAnnotation = field.getAnnotation(RelationManyToOne.class);
if (manyToOneAnnotation != null) { if (manyToOneAnnotation != null) {
relations.add(new ManyToOne<>(manyToOneAnnotation, entityClass, field)); relations.add(new ManyToOne<>(manyToOneAnnotation, entityClass, field));
} }
RelationOneToMany oneToManyAnnotation = field.getAnnotation(RelationOneToMany.class); RelationOneToMany oneToManyAnnotation = field.getAnnotation(RelationOneToMany.class);
if (oneToManyAnnotation != null) { if (oneToManyAnnotation != null) {
relations.add(new OneToMany<>(oneToManyAnnotation, entityClass, field)); relations.add(new OneToMany<>(oneToManyAnnotation, entityClass, field));
} }
RelationOneToOne oneToOneAnnotation = field.getAnnotation(RelationOneToOne.class); RelationOneToOne oneToOneAnnotation = field.getAnnotation(RelationOneToOne.class);
if (oneToOneAnnotation != null) { if (oneToOneAnnotation != null) {
relations.add(new OneToOne<>(oneToOneAnnotation, entityClass, field)); relations.add(new OneToOne<>(oneToOneAnnotation, entityClass, field));
} }
} }
return relations; return relations;
} }
@SuppressWarnings({"rawtypes", "unchecked"}) public static <Entity> void queryRelations(BaseMapper<?> mapper, List<Entity> entities) {
public static <Entity> void queryRelations(BaseMapper<?> mapper, List<Entity> entities) { doQueryRelations(mapper, entities, new HashSet<>());
if (CollectionUtil.isEmpty(entities)) { }
return;
}
Class<Entity> objectClass = (Class<Entity>) entities.get(0).getClass();
List<AbstractRelation> relations = getRelations(objectClass);
if (relations.isEmpty()) {
return;
}
String currentDsKey = DataSourceKey.get(); @SuppressWarnings({"rawtypes", "unchecked"})
private static <Entity> void doQueryRelations(BaseMapper<?> mapper, List<Entity> entities, Set<Class<?>> queriedClass) {
if (CollectionUtil.isEmpty(entities)) {
return;
}
Class<Entity> objectClass = (Class<Entity>) entities.get(0).getClass();
if (queriedClass.contains(objectClass)) {
return;
} else {
queriedClass.add(objectClass);
}
List<AbstractRelation> relations = getRelations(objectClass);
if (relations.isEmpty()) {
return;
}
String currentDsKey = DataSourceKey.get();
try {
relations.forEach(relation -> {
try { QueryWrapper queryWrapper = relation.toQueryWrapper(entities);
relations.forEach(relation -> { Class<?> mappingType = relation.getMappingType();
QueryWrapper queryWrapper = relation.toQueryWrapper(entities); String dataSource = relation.getDataSource();
Class<?> mappingType = relation.getMappingType(); if (StringUtil.isBlank(dataSource) && currentDsKey != null) {
dataSource = currentDsKey;
}
String dataSource = relation.getDataSource(); try {
if (StringUtil.isBlank(dataSource) && currentDsKey != null) { if (StringUtil.isNotBlank(dataSource)) {
dataSource = currentDsKey; DataSourceKey.use(dataSource);
} }
try { List<?> targetObjectList = mapper.selectListByQueryAs(queryWrapper, mappingType);
if (StringUtil.isNotBlank(dataSource)) { doQueryRelations(mapper, targetObjectList, queriedClass);
DataSourceKey.use(dataSource);
} if (CollectionUtil.isNotEmpty(targetObjectList)) {
List<?> targetObjectList = mapper.selectListByQueryAs(queryWrapper, mappingType); relation.join(entities, targetObjectList, mapper);
if (CollectionUtil.isNotEmpty(targetObjectList)) { }
relation.join(entities, targetObjectList, mapper); } finally {
} if (StringUtil.isNotBlank(dataSource)) {
} finally { DataSourceKey.clear();
if (StringUtil.isNotBlank(dataSource)) { }
DataSourceKey.clear(); }
} });
} } finally {
}); if (currentDsKey != null) {
} finally { DataSourceKey.use(currentDsKey);
if (currentDsKey != null) { }
DataSourceKey.use(currentDsKey); }
} }
}
}
} }