optimize relation annotations

This commit is contained in:
开源海哥 2023-07-07 11:24:30 +08:00
parent 41c30e9cfc
commit 849686ab44
8 changed files with 62 additions and 42 deletions

View File

@ -22,8 +22,8 @@ import java.lang.annotation.*;
@Target({ElementType.FIELD})
public @interface RelationManyToOne {
String selfField() default "";
String selfField();
String targetField();
String targetField() default "";
}

View File

@ -38,8 +38,8 @@ class ManyToMany<SelfEntity> extends Relation<SelfEntity> {
private String orderBy;
public ManyToMany(RelationManyToMany annotation, Class<SelfEntity> entityClass, Field relationField) {
super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""),
getDefaultPrimaryProperty(annotation.targetField(), entityClass, "@RelationOneToMany.targetField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""),
super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationManyToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""),
getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField), "@RelationManyToMany.targetField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""),
entityClass, relationField);
this.joinTable = annotation.joinTable();

View File

@ -28,8 +28,9 @@ import static com.mybatisflex.core.query.QueryMethods.column;
class ManyToOne<SelfEntity> extends Relation<SelfEntity> {
public ManyToOne(RelationManyToOne annotation, Class<SelfEntity> entityClass, Field relationField) {
super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""),
annotation.targetField(), entityClass, relationField);
super(annotation.selfField(),
getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField), "@RelationManyToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"")
, entityClass, relationField);
}
@Override

View File

@ -24,13 +24,12 @@ import com.mybatisflex.core.table.TableInfoFactory;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.core.util.FieldWrapper;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.reflection.Reflector;
import org.apache.ibatis.reflection.TypeParameterResolver;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
abstract class Relation<SelfEntity> {
@ -55,19 +54,7 @@ abstract class Relation<SelfEntity> {
this.selfFieldWrapper = FieldWrapper.of(entityClass, selfField);
Reflector reflector = new Reflector(entityClass);
Class<?> targetClass = reflector.getGetterType(relationField.getName());
if (Collection.class.isAssignableFrom(targetClass)) {
Type genericType = TypeParameterResolver.resolveFieldType(relationField, entityClass);
if (genericType instanceof ParameterizedType) {
this.targetEntityClass = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
}
} else if (targetClass.isArray()) {
this.targetEntityClass = targetClass.getComponentType();
} else {
this.targetEntityClass = targetClass;
}
this.targetEntityClass = relationFieldWrapper.getMappingType();
this.targetField = ClassUtil.getFirstField(targetEntityClass, field -> field.getName().equals(targetField));
this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField);
@ -172,14 +159,18 @@ abstract class Relation<SelfEntity> {
}
protected static String getDefaultPrimaryProperty(String key,Class<?> entityClass,String message){
if (StringUtil.isNotBlank(key)){
protected static Class<?> getTargetEntityClass(Class<?> entityClass, Field relationField) {
return FieldWrapper.of(entityClass, relationField.getName()).getMappingType();
}
protected static String getDefaultPrimaryProperty(String key, Class<?> entityClass, String message) {
if (StringUtil.isNotBlank(key)) {
return key;
}
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
List<IdInfo> primaryKeyList = tableInfo.getPrimaryKeyList();
if (primaryKeyList == null || primaryKeyList.size() != 1){
if (primaryKeyList == null || primaryKeyList.size() != 1) {
throw FlexExceptions.wrap(message);
}

View File

@ -22,6 +22,7 @@ import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.Reflectors;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.io.ResolverUtil;
import org.apache.ibatis.reflection.Reflector;
@ -131,7 +132,7 @@ public class TableInfoFactory {
TableInfo tableInfo = new TableInfo();
tableInfo.setEntityClass(entityClass);
Reflector reflector = new Reflector(entityClass);
Reflector reflector = Reflectors.of(entityClass);
tableInfo.setReflector(reflector);
//初始化表名

View File

@ -15,6 +15,8 @@
*/
package com.mybatisflex.core.util;
import org.apache.ibatis.reflection.Reflector;
import java.lang.reflect.*;
import java.util.Collection;
import java.util.Map;
@ -62,7 +64,7 @@ public class FieldWrapper {
fieldWrapper = new FieldWrapper();
fieldWrapper.fieldType = findField.getType();
fieldWrapper.mappingType = parseMappingType(findField);
fieldWrapper.mappingType = parseMappingType(clazz, findField);
fieldWrapper.setterMethod = setter;
String[] getterNames = new String[]{"get" + StringUtil.firstCharToUpperCase(fieldName), "is" + StringUtil.firstCharToUpperCase(fieldName)};
@ -78,8 +80,10 @@ public class FieldWrapper {
return fieldWrapper;
}
private static Class<?> parseMappingType(Field field) {
Class<?> fieldType = field.getType();
private static Class<?> parseMappingType(Class<?> clazz, Field field) {
Reflector reflector = Reflectors.of(clazz);
Class<?> fieldType = reflector.getGetterType(field.getName());
if (Collection.class.isAssignableFrom(fieldType)) {
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
@ -88,10 +92,6 @@ public class FieldWrapper {
}
}
if (fieldType.isArray()) {
return field.getType().getComponentType();
}
return fieldType;
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core.util;
import org.apache.ibatis.reflection.Reflector;
import org.apache.ibatis.util.MapUtil;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class Reflectors {
private final static ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<>();
public static Reflector of(Class<?> type){
return MapUtil.computeIfAbsent(reflectorMap, type, Reflector::new);
}
}

View File

@ -15,13 +15,11 @@
*/
package com.mybatisflex.core.util;
import com.mybatisflex.core.update.ModifyAttrsRecordProxyFactory;
import com.mybatisflex.core.table.IdInfo;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import com.mybatisflex.core.update.ModifyAttrsRecordProxyFactory;
import org.apache.ibatis.reflection.Reflector;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.invoker.Invoker;
import java.lang.reflect.Array;
@ -31,8 +29,6 @@ public class UpdateEntity {
private UpdateEntity() {}
private static final ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
public static <T> T of(Class<T> clazz) {
return ModifyAttrsRecordProxyFactory.getInstance().get(clazz);
@ -43,7 +39,7 @@ public class UpdateEntity {
T newEntity = ModifyAttrsRecordProxyFactory.getInstance().get(clazz);
TableInfo tableInfo = TableInfoFactory.ofEntityClass(clazz);
List<IdInfo> primaryKeyList = tableInfo.getPrimaryKeyList();
Reflector reflector = reflectorFactory.findForClass(clazz);
Reflector reflector = Reflectors.of(clazz);
if (primaryKeyList != null && !primaryKeyList.isEmpty()) {
for (int i = 0; i < primaryKeyList.size(); i++) {
@ -82,7 +78,7 @@ public class UpdateEntity {
T newEntity = (T) of(usefulClass);
Reflector reflector = reflectorFactory.findForClass(usefulClass);
Reflector reflector = Reflectors.of(usefulClass);
String[] propertyNames = reflector.getGetablePropertyNames();
for (String propertyName : propertyNames) {