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.relation; 017 018import com.mybatisflex.core.exception.FlexExceptions; 019import com.mybatisflex.core.query.QueryWrapper; 020import com.mybatisflex.core.row.Row; 021import com.mybatisflex.core.util.*; 022 023import java.lang.reflect.Field; 024import java.util.*; 025 026class ToManyRelation<SelfEntity> extends AbstractRelation<SelfEntity> { 027 028 protected String mapKeyField; 029 protected FieldWrapper mapKeyFieldWrapper; 030 protected String orderBy; 031 protected long limit = 0; 032 033 034 public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField, 035 String joinTable, String joinSelfColumn, String joinTargetColumn, 036 String dataSource, Class<SelfEntity> selfEntityClass, Field relationField, 037 String extraCondition, String[] selectColumns) { 038 super(selfField, targetSchema, targetTable, targetField, 039 joinTable, joinSelfColumn, joinTargetColumn, 040 dataSource, selfEntityClass, relationField, 041 extraCondition, selectColumns 042 ); 043 } 044 045 046 @Override 047 public void customizeQueryWrapper(QueryWrapper queryWrapper) { 048 if (StringUtil.isNotBlank(orderBy)) { 049 queryWrapper.orderBy(orderBy); 050 } 051 052 if (limit > 0) { 053 queryWrapper.limit(limit); 054 } 055 } 056 057 @SuppressWarnings("rawtypes") 058 @Override 059 public void join(List<SelfEntity> selfEntities, List<?> targetObjectList, List<Row> mappingRows) { 060 selfEntities.forEach(selfEntity -> { 061 Object selfValue = selfFieldWrapper.get(selfEntity); 062 if (selfValue != null) { 063 selfValue = selfValue.toString(); 064 Set<String> targetMappingValues = new HashSet<>(); 065 if (mappingRows != null) { 066 for (Row mappingRow : mappingRows) { 067 if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) { 068 Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn); 069 if (joinValue != null) { 070 targetMappingValues.add(joinValue.toString()); 071 } 072 } 073 } 074 } else { 075 targetMappingValues.add((String) selfValue); 076 } 077 078 if (targetMappingValues.isEmpty()) { 079 return; 080 } 081 082 Class<?> fieldType = relationFieldWrapper.getFieldType(); 083 //map 084 if (Map.class.isAssignableFrom(fieldType)) { 085 Class<?> wrapType = getMapWrapType(fieldType); 086 Map map = (Map) ClassUtil.newInstance(wrapType); 087 for (Object targetObject : targetObjectList) { 088 Object targetValue = targetFieldWrapper.get(targetObject); 089 if (targetValue != null && targetMappingValues.contains(targetValue.toString())) { 090 Object keyValue = mapKeyFieldWrapper.get(targetObject); 091 Object needKeyValue = ConvertUtil.convert(keyValue, relationFieldWrapper.getKeyType()); 092 map.put(needKeyValue, targetObject); 093 } 094 } 095 relationFieldWrapper.set(map, selfEntity); 096 } 097 //集合 098 else { 099 Class<?> wrapType = MapperUtil.getCollectionWrapType(fieldType); 100 Collection collection = (Collection) ClassUtil.newInstance(wrapType); 101 for (Object targetObject : targetObjectList) { 102 Object targetValue = targetFieldWrapper.get(targetObject); 103 if (targetValue != null && targetMappingValues.contains(targetValue.toString())) { 104 collection.add(targetObject); 105 } 106 } 107 relationFieldWrapper.set(collection, selfEntity); 108 } 109 } 110 }); 111 } 112 113 public void setMapKeyField(String mapKeyField) { 114 this.mapKeyField = mapKeyField; 115 if (StringUtil.isNotBlank(mapKeyField)) { 116 this.mapKeyFieldWrapper = FieldWrapper.of(targetEntityClass, mapKeyField); 117 } else { 118 if (Map.class.isAssignableFrom(relationFieldWrapper.getFieldType())) { 119 throw FlexExceptions.wrap("Please config mapKeyField for map field: " + relationFieldWrapper.getField()); 120 } 121 } 122 } 123 124 public static Class<? extends Map> getMapWrapType(Class<?> type) { 125 if (ClassUtil.canInstance(type.getModifiers())) { 126 return (Class<? extends Map>) type; 127 } 128 129 return HashMap.class; 130 } 131 132}