From ae6ac9ec5e91fc1936e318fcd21d1b58fb1c36ba Mon Sep 17 00:00:00 2001 From: jaysunxiao Date: Tue, 22 Feb 2022 15:19:29 +0800 Subject: [PATCH] =?UTF-8?q?perf[orm]:=20=E6=A0=A1=E9=AA=8Centity=E7=9A=84m?= =?UTF-8?q?ap=E5=B1=9E=E6=80=A7=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/zfoo/orm/manager/OrmManager.java | 79 +++++++++++-------- .../java/com/zfoo/orm/accessor/MapTest.java | 42 +++++++--- .../java/com/zfoo/orm/entity/bag/BagItem.java | 38 +++++---- .../java/com/zfoo/orm/entity/bag/Item.java | 28 +++++-- .../com/zfoo/orm/entity/bag/MapEntity.java | 33 ++++---- 5 files changed, 137 insertions(+), 83 deletions(-) diff --git a/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java b/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java index 30d0d9fa..1bc31fb5 100644 --- a/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java +++ b/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java @@ -347,7 +347,7 @@ public class OrmManager implements IOrmManager { // 校验entity格式 var entitySubClassMap = new HashMap, Set>>(); - 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, Set>> 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, Set>> entitySubClassMap) { + private void checkSubEntity(Class currentEntityClass, Type type) { if (type instanceof ParameterizedType) { // 泛型类 Class clazz = (Class) ((ParameterizedType) type).getRawType(); if (Set.class.equals(clazz)) { // Set> - checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0], entitySubClassMap); + checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0]); return; } else if (List.class.equals(clazz)) { // List> - checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0], entitySubClassMap); + checkSubEntity(currentEntityClass, ((ParameterizedType) type).getActualTypeArguments()[0]); return; } else if (Map.class.equals(clazz)) { // Map, List> @@ -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; } } diff --git a/orm/src/test/java/com/zfoo/orm/accessor/MapTest.java b/orm/src/test/java/com/zfoo/orm/accessor/MapTest.java index b6b1508a..29feff1b 100644 --- a/orm/src/test/java/com/zfoo/orm/accessor/MapTest.java +++ b/orm/src/test/java/com/zfoo/orm/accessor/MapTest.java @@ -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(); + entity.setBagMap(bagMap); + + var itemMap = new HashMap(); + 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); } -} \ No newline at end of file +} diff --git a/orm/src/test/java/com/zfoo/orm/entity/bag/BagItem.java b/orm/src/test/java/com/zfoo/orm/entity/bag/BagItem.java index 5ec26552..0b5ae63e 100644 --- a/orm/src/test/java/com/zfoo/orm/entity/bag/BagItem.java +++ b/orm/src/test/java/com/zfoo/orm/entity/bag/BagItem.java @@ -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 mapItem = new HashMap<>(); + private Map itemMap = new HashMap<>(); public BagItem() { - this.id = 1; - this.desc = "desc"; + } + + public BagItem(int id, String desc, Map 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 getMapItem() { - return mapItem; + public Map getItemMap() { + return itemMap; } - public void setMapItem(Map mapItem) { - this.mapItem = mapItem; + public void setItemMap(Map 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); } -} \ No newline at end of file + + @Override + public int hashCode() { + return Objects.hash(id, desc, itemMap); + } +} diff --git a/orm/src/test/java/com/zfoo/orm/entity/bag/Item.java b/orm/src/test/java/com/zfoo/orm/entity/bag/Item.java index d71dba8a..ac5ece20 100644 --- a/orm/src/test/java/com/zfoo/orm/entity/bag/Item.java +++ b/orm/src/test/java/com/zfoo/orm/entity/bag/Item.java @@ -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); } -} \ No newline at end of file + + @Override + public int hashCode() { + return Objects.hash(a, b); + } +} diff --git a/orm/src/test/java/com/zfoo/orm/entity/bag/MapEntity.java b/orm/src/test/java/com/zfoo/orm/entity/bag/MapEntity.java index f3a793f3..44db31fc 100644 --- a/orm/src/test/java/com/zfoo/orm/entity/bag/MapEntity.java +++ b/orm/src/test/java/com/zfoo/orm/entity/bag/MapEntity.java @@ -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 { @Id private long id; - private Map roleBag = new HashMap<>(); - - public MapEntity() { - - } + private Map bagMap = new HashMap<>(); @Override public Long id() { @@ -45,19 +42,25 @@ public class MapEntity implements IEntity { this.id = id; } - public Map getRoleBag() { - return roleBag; + public Map getBagMap() { + return bagMap; } - public void setRoleBag(Map roleBag) { - this.roleBag = roleBag; + public void setBagMap(Map 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); } -} \ No newline at end of file +}