mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-08-20 10:24:19 +00:00
perf[orm]: 校验entity的map属性类型
This commit is contained in:
@@ -347,7 +347,7 @@ public class OrmManager implements IOrmManager {
|
||||
|
||||
// 校验entity格式
|
||||
var entitySubClassMap = new HashMap<Class<?>, Set<Class<?>>>();
|
||||
checkEntity(clazz, entitySubClassMap);
|
||||
checkEntity(clazz);
|
||||
// 对象循环引用检测
|
||||
for (var entry : entitySubClassMap.entrySet()) {
|
||||
var subClass = entry.getKey();
|
||||
@@ -438,19 +438,13 @@ public class OrmManager implements IOrmManager {
|
||||
AssertionUtils.isTrue(gvsReturnValue.equals(vsValue), "实体类Entity[{}]的gvs方法和svs方法定义格式不正确", clazz.getSimpleName());
|
||||
}
|
||||
|
||||
private void checkEntity(Class<?> clazz, HashMap<Class<?>, Set<Class<?>>> entitySubClassMap) {
|
||||
// 不需要检查重复的协议
|
||||
if (entitySubClassMap.containsKey(clazz)) {
|
||||
return;
|
||||
}
|
||||
entitySubClassMap.put(clazz, new HashSet<>());
|
||||
|
||||
// // 是否为一个简单的javabean
|
||||
// ReflectionUtils.assertIsPojoClass(clazz);
|
||||
// // 不能是泛型类
|
||||
// AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}]不能是泛型类", clazz.getCanonicalName());
|
||||
// // 必须要有一个空的构造器
|
||||
// ReflectionUtils.publicEmptyConstructor(clazz);
|
||||
private void checkEntity(Class<?> clazz) {
|
||||
// 是否为一个简单的javabean
|
||||
ReflectionUtils.assertIsPojoClass(clazz);
|
||||
// 不能是泛型类
|
||||
AssertionUtils.isTrue(ArrayUtils.isEmpty(clazz.getTypeParameters()), "[class:{}]不能是泛型类", clazz.getCanonicalName());
|
||||
// 必须要有一个空的构造器
|
||||
ReflectionUtils.publicEmptyConstructor(clazz);
|
||||
|
||||
// 不能使用Storage的Index注解
|
||||
var storageIndexes = ReflectionUtils.getFieldsByAnnoNameInPOJOClass(clazz, "com.zfoo.storage.model.anno.Index");
|
||||
@@ -475,51 +469,71 @@ public class OrmManager implements IOrmManager {
|
||||
} else if (fieldType.isArray()) {
|
||||
// 是一个数组
|
||||
Class<?> arrayClazz = fieldType.getComponentType();
|
||||
checkSubEntity(clazz, arrayClazz, entitySubClassMap);
|
||||
checkSubEntity(clazz, arrayClazz);
|
||||
} else if (Set.class.isAssignableFrom(fieldType)) {
|
||||
AssertionUtils.isTrue(fieldType.equals(Set.class), "ORM[class:{}]类型声明不正确,必须是Set接口类型", clazz.getCanonicalName());
|
||||
|
||||
Type type = field.getGenericType();
|
||||
var type = field.getGenericType();
|
||||
AssertionUtils.isTrue(type instanceof ParameterizedType, "ORM[class:{}]类型声明不正确,不是泛型类[field:{}]", clazz.getCanonicalName(), field.getName());
|
||||
|
||||
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
var types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
AssertionUtils.isTrue(types.length == 1, "ORM[class:{}]中Set类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
|
||||
|
||||
checkSubEntity(clazz, types[0], entitySubClassMap);
|
||||
checkSubEntity(clazz, types[0]);
|
||||
} else if (List.class.isAssignableFrom(fieldType)) {
|
||||
// 是一个List
|
||||
AssertionUtils.isTrue(fieldType.equals(List.class), "ORM[class:{}]类型声明不正确,必须是List接口类型", clazz.getCanonicalName());
|
||||
|
||||
Type type = field.getGenericType();
|
||||
var type = field.getGenericType();
|
||||
AssertionUtils.isTrue(type instanceof ParameterizedType, "ORM[class:{}]类型声明不正确,不是泛型类[field:{}]", clazz.getCanonicalName(), field.getName());
|
||||
|
||||
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
var types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
AssertionUtils.isTrue(types.length == 1, "ORM[class:{}]中List类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
|
||||
|
||||
checkSubEntity(clazz, types[0], entitySubClassMap);
|
||||
}
|
||||
// else if (Map.class.isAssignableFrom(fieldType)) {
|
||||
// throw new RunException("ORM[class:{}]类型声明不正确,不支持Map类型", clazz.getCanonicalName());
|
||||
// }
|
||||
else {
|
||||
entitySubClassMap.get(clazz).add(fieldType);
|
||||
checkEntity(fieldType, entitySubClassMap);
|
||||
checkSubEntity(clazz, types[0]);
|
||||
} else if (Map.class.isAssignableFrom(fieldType)) {
|
||||
if (!fieldType.equals(Map.class)) {
|
||||
throw new RunException("ORM[class:{}]类型声明不正确,必须是Map接口类型", clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
var type = field.getGenericType();
|
||||
|
||||
if (!(type instanceof ParameterizedType)) {
|
||||
throw new RunException("ORM[class:{}]中数组类型声明不正确,[field:{}]不是泛型类", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
var types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
|
||||
if (types.length != 2) {
|
||||
throw new RunException("ORM[class:{}]中数组类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
var keyType = types[0];
|
||||
var valueType = types[1];
|
||||
|
||||
if (!isBaseType((Class<?>) keyType)) {
|
||||
throw new RunException("ORM[class:{}]类型声明不正确,Map的key类型必须为基础类型", clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
checkSubEntity(clazz, valueType);
|
||||
} else {
|
||||
checkEntity(fieldType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkSubEntity(Class<?> currentEntityClass, Type type, HashMap<Class<?>, Set<Class<?>>> entitySubClassMap) {
|
||||
private void checkSubEntity(Class<?> currentEntityClass, Type type) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
// 泛型类
|
||||
Class<?> clazz = (Class<?>) ((ParameterizedType) type).getRawType();
|
||||
if (Set.class.equals(clazz)) {
|
||||
// Set<Set<String>>
|
||||
checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0], entitySubClassMap);
|
||||
checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0]);
|
||||
return;
|
||||
} else if (List.class.equals(clazz)) {
|
||||
// List<List<String>>
|
||||
checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0], entitySubClassMap);
|
||||
checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0]);
|
||||
return;
|
||||
} else if (Map.class.equals(clazz)) {
|
||||
// Map<List<String>, List<String>>
|
||||
@@ -536,8 +550,7 @@ public class OrmManager implements IOrmManager {
|
||||
} else if (clazz.equals(List.class) || clazz.equals(Set.class) || clazz.equals(Map.class)) {
|
||||
throw new RunException("ORM不支持数组和集合联合使用[type:{}]类型", type);
|
||||
} else {
|
||||
entitySubClassMap.get(currentEntityClass).add(clazz);
|
||||
checkEntity(clazz, entitySubClassMap);
|
||||
checkEntity(clazz);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,31 +17,47 @@ import com.zfoo.orm.OrmContext;
|
||||
import com.zfoo.orm.entity.bag.BagItem;
|
||||
import com.zfoo.orm.entity.bag.Item;
|
||||
import com.zfoo.orm.entity.bag.MapEntity;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Ignore
|
||||
public class MapTest {
|
||||
private static final Logger log = LoggerFactory.getLogger(MapTest.class);
|
||||
|
||||
@Test
|
||||
public void insertMapData() {
|
||||
|
||||
var context = new ClassPathXmlApplicationContext("application.xml");
|
||||
MapEntity entity = OrmContext.getAccessor().load(1, MapEntity.class);
|
||||
if (entity == null) {
|
||||
entity = new MapEntity();
|
||||
entity.setId(1);
|
||||
entity.getRoleBag().computeIfAbsent("1", k -> new BagItem())
|
||||
.getMapItem().computeIfAbsent("2", k -> new Item());
|
||||
OrmContext.getAccessor().insert(entity);
|
||||
log.info("数据插入成功 {}", entity);
|
||||
} else {
|
||||
log.info("entity已存在 {}", entity);
|
||||
}
|
||||
|
||||
OrmContext.getAccessor().delete(1, MapEntity.class);
|
||||
|
||||
var entity = new MapEntity();
|
||||
entity.setId(1);
|
||||
|
||||
var bagMap = new HashMap<String, BagItem>();
|
||||
entity.setBagMap(bagMap);
|
||||
|
||||
var itemMap = new HashMap<String, Item>();
|
||||
itemMap.put("1", new Item(1, "item1"));
|
||||
itemMap.put("2", new Item(2, "item1"));
|
||||
itemMap.put("3", new Item(3, "item1"));
|
||||
|
||||
var bagItem1 = new BagItem(1, "desc1", itemMap);
|
||||
var bagItem2 = new BagItem(2, "desc2", itemMap);
|
||||
var bagItem3 = new BagItem(3, "desc3", itemMap);
|
||||
|
||||
bagMap.put("bag1", bagItem1);
|
||||
bagMap.put("bag2", bagItem2);
|
||||
bagMap.put("bag3", bagItem3);
|
||||
|
||||
OrmContext.getAccessor().insert(entity);
|
||||
|
||||
var myEntity = OrmContext.getAccessor().load(1, MapEntity.class);
|
||||
Assert.assertEquals(entity, myEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,22 @@ package com.zfoo.orm.entity.bag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BagItem {
|
||||
|
||||
private int id;
|
||||
private String desc;
|
||||
|
||||
private Map<String, Item> mapItem = new HashMap<>();
|
||||
private Map<String, Item> itemMap = new HashMap<>();
|
||||
|
||||
public BagItem() {
|
||||
this.id = 1;
|
||||
this.desc = "desc";
|
||||
}
|
||||
|
||||
public BagItem(int id, String desc, Map<String, Item> itemMap) {
|
||||
this.id = id;
|
||||
this.desc = desc;
|
||||
this.itemMap = itemMap;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
@@ -43,20 +49,24 @@ public class BagItem {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public Map<String, Item> getMapItem() {
|
||||
return mapItem;
|
||||
public Map<String, Item> getItemMap() {
|
||||
return itemMap;
|
||||
}
|
||||
|
||||
public void setMapItem(Map<String, Item> mapItem) {
|
||||
this.mapItem = mapItem;
|
||||
public void setItemMap(Map<String, Item> itemMap) {
|
||||
this.itemMap = itemMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BagItem{" +
|
||||
"id=" + id +
|
||||
", desc='" + desc + '\'' +
|
||||
", mapItem=" + mapItem +
|
||||
'}';
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BagItem bagItem = (BagItem) o;
|
||||
return id == bagItem.id && Objects.equals(desc, bagItem.desc) && Objects.equals(itemMap, bagItem.itemMap);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, desc, itemMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,19 @@
|
||||
|
||||
package com.zfoo.orm.entity.bag;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Item {
|
||||
|
||||
private int a;
|
||||
private String b;
|
||||
|
||||
public Item() {
|
||||
this.a = 1;
|
||||
this.b = "bbbb";
|
||||
}
|
||||
|
||||
public Item(int a, String b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public int getA() {
|
||||
@@ -38,11 +44,17 @@ public class Item {
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Item{" +
|
||||
"a=" + a +
|
||||
", b='" + b + '\'' +
|
||||
'}';
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Item item = (Item) o;
|
||||
return a == item.a && Objects.equals(b, item.b);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,14 @@ import com.zfoo.orm.model.entity.IEntity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@EntityCache(cacheStrategy = "thousand", persister = @Persister("time30s"))
|
||||
public class MapEntity implements IEntity<Long> {
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
private Map<String, BagItem> roleBag = new HashMap<>();
|
||||
|
||||
public MapEntity() {
|
||||
|
||||
}
|
||||
private Map<String, BagItem> bagMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Long id() {
|
||||
@@ -45,19 +42,25 @@ public class MapEntity implements IEntity<Long> {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Map<String, BagItem> getRoleBag() {
|
||||
return roleBag;
|
||||
public Map<String, BagItem> getBagMap() {
|
||||
return bagMap;
|
||||
}
|
||||
|
||||
public void setRoleBag(Map<String, BagItem> roleBag) {
|
||||
this.roleBag = roleBag;
|
||||
public void setBagMap(Map<String, BagItem> bagMap) {
|
||||
this.bagMap = bagMap;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MapEntity mapEntity = (MapEntity) o;
|
||||
return id == mapEntity.id && Objects.equals(bagMap, mapEntity.bagMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MapEntity{" +
|
||||
"id=" + id +
|
||||
", roleBag=" + roleBag +
|
||||
'}';
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, bagMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user