gpt4 book ai didi

java - 使用反射将 Mongo DBObject 转换为实体 POJO

转载 作者:行者123 更新时间:2023-12-02 05:03:39 24 4
gpt4 key购买 nike

首先我想说的是,我知道有像 Morphia 和 Spring Data for MongoDB 这样的 ORM。我并不是想重新发明威尔——只是为了学习。因此,我的 AbstractRepository 背后的基本思想是封装所有存储库之间共享的逻辑。子类(特定实体的存储库)将实体类传递给 .

使用 Reflection 将实体 bean (POJO) 转换为 DBObject 非常简单。将 DBObject 转换为实体 bean 会出现问题。原因?我需要将 DBObject 中的任何字段类型转换为实体 bean 属性类型。这就是我被困住的地方。我无法在 AbstractRepository 方法中获取实体 bean 类 T getEntityFromDBObject(DBObject object)

我可以将实体类传递给此方法,但这会破坏多态性的目的。另一种方法是声明私有(private) T 类型属性,然后使用 Field 读取类型。定义附加属性只是为了让我可以阅读,这听起来不太正确。

所以问题是 - 如何使用反射使用尽可能少的参数将 DBObject 映射到 POJO。这又是这个想法:

public  abstract class AbstractRepository<T> {
T getEntityFromDBObject(DBObject object) {
....
}
}

具体的存储库将如下所示:

public class EntityRepository extends AbstractRepository<T> {
}

谢谢!

注意:忽略复杂的关系和引用。假设它不需要支持对另一个 DBObject 或 POJO 的引用。

最佳答案

您需要构建类型 T 的实例并用“DBObject”中的数据填充它:

public abstract class AbstractRepository<T> {

protected final Class<T> entityClass;

protected AbstractRepository() {
// Don't remember if this reflection stuff throws any exception
// If it does, try-catch and throw RuntimeException
// (or assign null to entityClass)
// Anyways, it's impossible that such exception occurs here
Type t = this.getClass().getGenericSuperclass();
this.entityClass = ((Class<T>)((ParameterizedType)t).getActualTypeArguments()[0]);
}

T getEntityFromDBObject(DBObject object) {
// Use reflection to create an entity instance
// Let's suppose all entities have a public no-args constructor (they should!)
T entity = (T) this.entityClass.getConstructor().newInstance();

// Now fill entity with DBObject's data
// This is the place to fill common fields only, i.e. an ID
// So maybe T could extend some abstract BaseEntity that provides setters for these common fields
// Again, all this reflection stuff needs to be done within a try-catch block because of checked exceptions
// Wrap the original exception in a RuntimeException and throw this one instead
// (or maybe your own specific runtime exception for this case)

// Now let specialized repositories fill specific fields
this.fillSpecificFields(entity, object);

return entity;
}

protected abstract void fillSpecificFields(T entity, DBObject object);

}

如果您不想在每个实体的存储库中实现方法.fillSpecificFields(),那么您需要使用反射来设置每个字段(包括常见的字段,例如ID,所以不要手动设置它们)。

如果是这种情况,则您已经将实体类作为 protected 属性,因此它可用于每个实体的存储库。您需要迭代它的所有字段,包括在父类(super class)中声明的字段(我相信您必须使用方法 .getFields() 而不是 .getDeclaredFields() )并通过反射设置值。

顺便说一句,我真的不知道该 DBObject 实例中包含哪些数据以及采用什么格式,因此请告诉我从中提取字段值是否会导致非结果微不足道。

关于java - 使用反射将 Mongo DBObject 转换为实体 POJO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28005541/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com