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 */ 016package com.mybatisflex.core.util; 017 018import com.mybatisflex.core.BaseMapper; 019import com.mybatisflex.core.field.FieldQuery; 020import com.mybatisflex.core.field.FieldQueryBuilder; 021import com.mybatisflex.core.query.QueryWrapper; 022import org.apache.ibatis.exceptions.TooManyResultsException; 023import org.apache.ibatis.session.defaults.DefaultSqlSession; 024 025import java.util.*; 026import java.util.function.Consumer; 027 028public class MapperUtil { 029 030 private MapperUtil() { 031 } 032 033 034 public static <R> void queryFields(BaseMapper<?> mapper, List<R> list, Consumer<FieldQueryBuilder<R>>[] consumers) { 035 if (CollectionUtil.isEmpty(list) || ArrayUtil.isEmpty(consumers) || consumers[0] == null) { 036 return; 037 } 038 list.forEach(entity -> { 039 for (Consumer<FieldQueryBuilder<R>> consumer : consumers) { 040 FieldQueryBuilder<R> fieldQueryBuilder = new FieldQueryBuilder<>(entity); 041 consumer.accept(fieldQueryBuilder); 042 FieldQuery fieldQuery = fieldQueryBuilder.build(); 043 QueryWrapper childQuery = fieldQuery.getQueryWrapper(); 044 045 FieldWrapper fieldWrapper = FieldWrapper.of(entity.getClass(), fieldQuery.getField()); 046 047 Class<?> fieldType = fieldWrapper.getFieldType(); 048 Class<?> mappingType = fieldWrapper.getMappingType(); 049 050 Object value; 051 if (Collection.class.isAssignableFrom(fieldType)) { 052 value = mapper.selectListByQueryAs(childQuery, mappingType); 053 if (!fieldType.isAssignableFrom(value.getClass())) { 054 fieldType = getWrapType(fieldType); 055 Collection newValue = (Collection) ClassUtil.newInstance(fieldType); 056 newValue.addAll((Collection) value); 057 value = newValue; 058 } 059 } else if (fieldType.isArray()) { 060 value = mapper.selectListByQueryAs(childQuery, mappingType); 061 value = ((List<?>) value).toArray(); 062 } else { 063 value = mapper.selectOneByQueryAs(childQuery, mappingType); 064 } 065 fieldWrapper.set(value, entity); 066 } 067 }); 068 } 069 070 071 private static Class<?> getWrapType(Class<?> type) { 072 if (List.class.isAssignableFrom(type)) { 073 return ArrayList.class; 074 } 075 076 if (Set.class.isAssignableFrom(type)) { 077 return HashSet.class; 078 } 079 080 throw new IllegalStateException("Field query can not support type: " + type.getName()); 081 } 082 083 084 /** 085 * 搬运加改造 {@link DefaultSqlSession#selectOne(String, Object)} 086 */ 087 public static <T> T getSelectOneResult(List<T> list) { 088 if (list == null || list.isEmpty()) { 089 return null; 090 } 091 int size = list.size(); 092 if (size == 1) { 093 return list.get(0); 094 } 095 throw new TooManyResultsException( 096 "Expected one result (or null) to be returned by selectOne(), but found: " + size); 097 } 098}