001/* 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.mybatisflex.core.field; 018 019import com.mybatisflex.core.BaseMapper; 020import com.mybatisflex.core.exception.FlexExceptions; 021import com.mybatisflex.core.query.QueryWrapper; 022import com.mybatisflex.core.row.Row; 023import com.mybatisflex.core.util.ClassUtil; 024import com.mybatisflex.core.util.CollectionUtil; 025 026import java.lang.reflect.Array; 027import java.util.*; 028 029/** 030 * 属性查询管理。 031 * 032 * @author 王帅 033 * @since 2023-07-15 034 */ 035public class FieldQueryManager { 036 037 private FieldQueryManager() { 038 } 039 040 public static void queryFields(BaseMapper<?> mapper, Collection<?> entities, Map<String, FieldQuery> fieldQueryMap) { 041 for (Object entity : entities) { 042 fieldQueryMap.forEach((key, fieldQuery) -> { 043 //不是当前类的内容 044 if (!key.startsWith(entity.getClass().getName() + "#")) { 045 return; 046 } 047 048 QueryWrapper queryWrapper = fieldQuery.getQueryBuilder().build(entity); 049 Class<?> filedType = fieldQuery.getFieldWrapper().getFieldType(); 050 Object value; 051 052 if (Collection.class.isAssignableFrom(filedType)) { 053 Class<?> mappingType = fieldQuery.getFieldWrapper().getMappingType(); 054 List<?> list = mapper.selectListByQueryAs(queryWrapper, mappingType); 055 // 转换成 Collection 子类,或者空 Collection 对象,避免 NPE 056 value = getCollectionValue(filedType, list); 057 // 循环查询泛型实体类 058 if ((!Number.class.isAssignableFrom(mappingType) 059 || !String.class.isAssignableFrom(mappingType) 060 || !Map.class.isAssignableFrom(mappingType)) 061 && !fieldQuery.isPrevent()) { 062 queryFields(mapper, (Collection<?>) value, fieldQueryMap); 063 } 064 } else if (Map.class.isAssignableFrom(filedType)) { 065 List<Row> rows = mapper.selectRowsByQuery(queryWrapper); 066 // 转换成 Map 子类,或者空 Map 对象,避免 NPE 067 if (rows != null && !rows.isEmpty() && rows.get(0) != null) { 068 value = getMapValue(filedType, rows.get(0)); 069 } else { 070 value = new HashMap<>(); 071 } 072 } else if (filedType.isArray()) { 073 Class<?> componentType = filedType.getComponentType(); 074 List<?> objects = mapper.selectListByQueryAs(queryWrapper, componentType); 075 value = getArrayValue(componentType, objects); 076 } 077 // 实体类 078 else { 079 value = mapper.selectOneByQueryAs(queryWrapper, filedType); 080 // 循环查询嵌套类 081 if (!fieldQuery.isPrevent()) { 082 queryFields(mapper, Collections.singletonList(value), fieldQueryMap); 083 } 084 } 085 // 属性查询出来的值不为 null 时,为属性设置值 086 if (value != null) { 087 fieldQuery.getFieldWrapper().set(value, entity); 088 } 089 }); 090 } 091 } 092 093 094 @SuppressWarnings({"rawtypes", "unchecked"}) 095 private static Object getCollectionValue(Class<?> fieldType, Collection value) { 096 if (value == null) { 097 if (fieldType == List.class) { 098 return Collections.emptyList(); 099 } else if (fieldType == Set.class) { 100 return Collections.emptySet(); 101 } 102 } 103 104 if (ClassUtil.canInstance(fieldType.getModifiers())) { 105 Collection collection = (Collection) ClassUtil.newInstance(fieldType); 106 collection.addAll(value); 107 return collection; 108 } 109 110 if (List.class.isAssignableFrom(fieldType)) { 111 return value; 112 } 113 114 if (Set.class.isAssignableFrom(fieldType)) { 115 return new HashSet<>(value); 116 } 117 118 throw FlexExceptions.wrap("Unsupported collection type: " + fieldType); 119 } 120 121 @SuppressWarnings({"rawtypes", "unchecked"}) 122 private static Object getMapValue(Class<?> fieldType, Map value) { 123 if (ClassUtil.canInstance(fieldType.getModifiers())) { 124 Map map = (Map) ClassUtil.newInstance(fieldType); 125 map.putAll(value); 126 return map; 127 } 128 129 return new HashMap<>(value); 130 } 131 132 @SuppressWarnings("unchecked") 133 private static <T> Object getArrayValue(Class<?> componentType, List<T> list) { 134 if (CollectionUtil.isEmpty(list)) { 135 return Array.newInstance(componentType, 0); 136 } 137 138 T[] array = (T[]) Array.newInstance(componentType, list.size()); 139 140 for (int rows = 0; rows < list.size(); rows++) { 141 array[rows] = list.get(rows); 142 } 143 144 return array; 145 } 146 147}