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 029import static com.mybatisflex.core.table.TableInfoFactory.defaultSupportColumnTypes; 030 031/** 032 * 属性查询管理。 033 * 034 * @author 王帅 035 * @since 2023-07-15 036 */ 037public class FieldQueryManager { 038 039 private FieldQueryManager() { 040 } 041 042 public static void queryFields(BaseMapper<?> mapper, Collection<?> entities, Map<String, FieldQuery> fieldQueryMap) { 043 for (Object entity : entities) { 044 045 if (entity == null) { 046 continue; 047 } 048 049 String className = ClassUtil.getUsefulClass(entity.getClass()).getName(); 050 051 fieldQueryMap.forEach((key, fieldQuery) -> { 052 // 不是当前类的内容 053 if (!key.startsWith(className + "#")) { 054 return; 055 } 056 057 @SuppressWarnings("unchecked") 058 QueryWrapper queryWrapper = fieldQuery.getQueryBuilder().build(entity); 059 060 // QueryWrapper 为 null 值时,不进行属性查询 061 if (queryWrapper == null) { 062 return; 063 } 064 065 Class<?> filedType = fieldQuery.getFieldWrapper().getFieldType(); 066 Object value; 067 068 if (Collection.class.isAssignableFrom(filedType)) { 069 Class<?> mappingType = fieldQuery.getFieldWrapper().getMappingType(); 070 List<?> list = mapper.selectListByQueryAs(queryWrapper, mappingType); 071 // 转换成 Collection 子类,或者空 Collection 对象,避免 NPE 072 value = getCollectionValue(filedType, list); 073 // 循环查询泛型实体类 074 if ((!Number.class.isAssignableFrom(mappingType) 075 || !String.class.isAssignableFrom(mappingType) 076 || !Map.class.isAssignableFrom(mappingType)) 077 && !fieldQuery.isPrevent()) { 078 queryFields(mapper, (Collection<?>) value, fieldQueryMap); 079 } 080 } else if (Map.class.isAssignableFrom(filedType)) { 081 List<Row> rows = mapper.selectRowsByQuery(queryWrapper); 082 // 转换成 Map 子类,或者空 Map 对象,避免 NPE 083 if (rows != null && !rows.isEmpty() && rows.get(0) != null) { 084 value = getMapValue(filedType, rows.get(0)); 085 } else { 086 value = new HashMap<>(); 087 } 088 } else if (filedType.isArray()) { 089 Class<?> componentType = filedType.getComponentType(); 090 List<?> objects = mapper.selectListByQueryAs(queryWrapper, componentType); 091 value = getArrayValue(componentType, objects); 092 } else if (defaultSupportColumnTypes.contains(filedType)) { 093 value = mapper.selectObjectByQueryAs(queryWrapper, filedType); 094 } else { 095 value = mapper.selectOneByQueryAs(queryWrapper, filedType); 096 // 循环查询嵌套类 097 if (!fieldQuery.isPrevent()) { 098 queryFields(mapper, Collections.singletonList(value), fieldQueryMap); 099 } 100 } 101 // 属性查询出来的值不为 null 时,为属性设置值 102 if (value != null) { 103 fieldQuery.getFieldWrapper().set(value, entity); 104 } 105 }); 106 } 107 } 108 109 110 @SuppressWarnings({"rawtypes", "unchecked"}) 111 private static Object getCollectionValue(Class<?> fieldType, Collection value) { 112 if (value == null) { 113 if (fieldType == List.class) { 114 return Collections.emptyList(); 115 } else if (fieldType == Set.class) { 116 return Collections.emptySet(); 117 } 118 // avoid NPE 119 return ClassUtil.newInstance(fieldType); 120 } 121 122 if (ClassUtil.canInstance(fieldType.getModifiers())) { 123 Collection collection = (Collection) ClassUtil.newInstance(fieldType); 124 collection.addAll(value); 125 return collection; 126 } 127 128 if (List.class.isAssignableFrom(fieldType)) { 129 return value; 130 } 131 132 if (Set.class.isAssignableFrom(fieldType)) { 133 return new HashSet<>(value); 134 } 135 136 throw FlexExceptions.wrap("Unsupported collection type: " + fieldType); 137 } 138 139 @SuppressWarnings({"rawtypes", "unchecked"}) 140 private static Object getMapValue(Class<?> fieldType, Map value) { 141 if (ClassUtil.canInstance(fieldType.getModifiers())) { 142 Map map = (Map) ClassUtil.newInstance(fieldType); 143 map.putAll(value); 144 return map; 145 } 146 147 return new HashMap<>(value); 148 } 149 150 @SuppressWarnings("unchecked") 151 private static <T> Object getArrayValue(Class<?> componentType, List<T> list) { 152 if (CollectionUtil.isEmpty(list)) { 153 return Array.newInstance(componentType, 0); 154 } 155 156 T[] array = (T[]) Array.newInstance(componentType, list.size()); 157 158 for (int rows = 0; rows < list.size(); rows++) { 159 array[rows] = list.get(rows); 160 } 161 162 return array; 163 } 164 165}