diff --git a/orm/README.md b/orm/README.md index ae3fed09..c1194564 100644 --- a/orm/README.md +++ b/orm/README.md @@ -26,7 +26,7 @@ var collection = OrmContext.getOrmManager().getCollection(UserEntity.class) #### 2. Indirect use (middle level API) to access data through the collection's simple wrapper IAccessor and IQuery interfaces - IAccessor is a data access interface - - Inserting data into the database uses the return value of the object's id() method as the primary key + - Inserting data into the database uses the field value of the object's field which marked `@Id` as the primary key ``` OrmContext.getAccessor().insert(obj) ``` diff --git a/orm/README_CN.md b/orm/README_CN.md index 2e45dcfc..dad0f0e2 100644 --- a/orm/README_CN.md +++ b/orm/README_CN.md @@ -25,7 +25,7 @@ var collection = OrmContext.getOrmManager().getCollection(UserEntity.class) #### 2. 间接使用(middle level api),通过collection的简易包装类IAccessor和IQuery接口访问数据 - IAccessor接口,为数据访问接口 - - 插入数据到数据库,会以对象的id()方法的返回值作为主键 + - 插入数据到数据库,会以对象class的@Id字段的值作为主键 ``` OrmContext.getAccessor().insert(obj) ``` diff --git a/orm/src/main/java/com/zfoo/orm/convention/ZfooAnnotationConvention.java b/orm/src/main/java/com/zfoo/orm/convention/ZfooAnnotationConvention.java new file mode 100644 index 00000000..569196a2 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/convention/ZfooAnnotationConvention.java @@ -0,0 +1,45 @@ +package com.zfoo.orm.convention; + +import com.zfoo.orm.anno.Id; +import org.bson.BsonType; +import org.bson.codecs.pojo.ClassModelBuilder; +import org.bson.codecs.pojo.Convention; +import org.bson.codecs.pojo.PropertyModelBuilder; +import org.bson.codecs.pojo.annotations.*; + +import java.lang.annotation.Annotation; + +/** + * zfoo注解约定 + * + * @author Sando + * @version 1.0 + * @since 2024/7/30 + */ +public class ZfooAnnotationConvention implements Convention { + public static final ZfooAnnotationConvention INSTANCE = new ZfooAnnotationConvention(); + @Override + public void apply(ClassModelBuilder classModelBuilder) { + for (PropertyModelBuilder propertyModelBuilder : classModelBuilder.getPropertyModelBuilders()) { + processPropertyAnnotations(classModelBuilder, propertyModelBuilder); + } + } + + private void processPropertyAnnotations(final ClassModelBuilder classModelBuilder, + final PropertyModelBuilder propertyModelBuilder) { + for (Annotation annotation : propertyModelBuilder.getReadAnnotations()) { + if (annotation instanceof Id) { + String idPropertyName = classModelBuilder.getIdPropertyName(); + String fieldName = propertyModelBuilder.getName(); + if (idPropertyName != null && !fieldName.equals(idPropertyName)) { + // allow using @Id and @BsonId on same field + String typeName = classModelBuilder.getType().getName(); + throw new IllegalStateException("The class " + + typeName + " has more than one id property. The properties are " + + idPropertyName + " and " + fieldName); + } + classModelBuilder.idPropertyName(fieldName); + } + } + } +} 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 d4788d00..81c7e8c3 100644 --- a/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java +++ b/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java @@ -30,6 +30,7 @@ import com.zfoo.orm.codec.MapCodecProvider; import com.zfoo.orm.config.CacheStrategy; import com.zfoo.orm.config.OrmConfig; import com.zfoo.orm.config.PersisterStrategy; +import com.zfoo.orm.convention.ZfooAnnotationConvention; import com.zfoo.orm.model.EntityDef; import com.zfoo.orm.model.IEntity; import com.zfoo.orm.model.IndexDef; @@ -42,7 +43,6 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistries; import org.bson.codecs.pojo.Conventions; import org.bson.codecs.pojo.PojoCodecProvider; -import org.bson.codecs.pojo.annotations.BsonId; import org.bson.types.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,12 +105,11 @@ public class OrmManager implements IOrmManager { allEntityCachesUsableMap.put(entityClass, false); } - var pojoCodecProvider = PojoCodecProvider.builder() - .conventions(List.of(Conventions.ANNOTATION_CONVENTION)) - .automatic(true) - .register(new MapCodecProvider()) - .build(); - var codecRegistry = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider)); + var pojoCodecProvider = PojoCodecProvider.builder().automatic(true) + .conventions(List.of(Conventions.ANNOTATION_CONVENTION, ZfooAnnotationConvention.INSTANCE)) + .register(new MapCodecProvider()).build(); + var codecRegistry = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), + CodecRegistries.fromProviders(pojoCodecProvider)); var mongoBuilder = MongoClientSettings .builder() @@ -441,7 +440,7 @@ public class OrmManager implements IOrmManager { var getIdMethod = ReflectionUtils.getMethodByNameInPOJOClass(clazz, FieldUtils.fieldToGetMethod(clazz, idField)); var returnTypeOfGetIdMethod = getIdMethod.getReturnType(); AssertionUtils.isTrue(returnTypeOfGetIdMethod.equals(idFieldType), "[{}] getIdMethod:[{}] return type:[{}] must be equal with type id:[{}]" - , clazz.getSimpleName(), getIdMethod.getName(), returnTypeOfGetIdMethod.getName(), idFieldType.getName()); + , clazz.getSimpleName(), getIdMethod.getName(),returnTypeOfGetIdMethod.getName(), idFieldType.getName()); // 随机给id字段赋值,然后调用id()方法,看看两者的返回值是不是一样的,避免出错 var entityInstance = ReflectionUtils.newInstance(clazz); @@ -462,10 +461,6 @@ public class OrmManager implements IOrmManager { throw new RunException("orm id field only supports int long float double String ObjectId"); } - if (!idField.getName().equals("id") && !idField.isAnnotationPresent(BsonId.class)) { - throw new RunException("use @BsonId annotation to @Id filed:[{}] or rename this field with id", idField.getName()); - } - ReflectionUtils.makeAccessible(idField); ReflectionUtils.setField(idField, entityInstance, idFiledValue); var idMethodOptional = Arrays.stream(ReflectionUtils.getAllMethods(clazz)).filter(it -> it.getName().equalsIgnoreCase("id")) diff --git a/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java b/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java index 7e91db53..bb4fed38 100644 --- a/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java +++ b/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java @@ -13,10 +13,10 @@ package com.zfoo.orm.entity; +import com.zfoo.orm.anno.EntityCache; import com.zfoo.orm.anno.Id; import com.zfoo.orm.anno.Index; import com.zfoo.orm.model.IEntity; -import org.bson.codecs.pojo.annotations.BsonId; import java.util.Date; @@ -24,10 +24,10 @@ import java.util.Date; /** * @author godotg */ +@EntityCache public class MailEntity implements IEntity { @Id - @BsonId private String mailId; @Index(ascending = true, unique = false) @@ -37,9 +37,9 @@ public class MailEntity implements IEntity { private Date createDate; - public static MailEntity valueOf(String mailId, String userName, String content, Date createDate) { + public static MailEntity valueOf(String id, String userName, String content, Date createDate) { var entity = new MailEntity(); - entity.mailId = mailId; + entity.mailId = id; entity.userName = userName; entity.content = content; entity.createDate = createDate;