java - 带有 MongoDB Java 集合的动态 POJO 类型
问题描述
当我们知道我们正在使用的特定类型时,我了解如何使用 MongoDB Java 驱动程序来读取和存储 POJO 。在我正在处理的项目中,编解码器提供程序(以及编解码器注册表)是由通过属性传入的类名构建的(有一些硬编码值)。这支持例如仅在进行测试(JUnit)时注销某些消息。
问题是我无法确定如何使用 MongoCollection 使用这种类型。下面是一个基于实际问题的玩具问题(我们有一个通用的“消息”接口,我们希望记录的所有 POJO 都实现该接口。日志记录函数接受该“消息”接口的对象并需要将其插入集合)。
首先我们有我们的界面:
public interface MyInterface {
int getX();
}
和简单的实现:
public class ImplA implements MyInterface {
public int getX(){return 1;}
}
然后使用它们的代码:
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.pojo.ClassModel;
import org.bson.codecs.pojo.PojoCodecProvider;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
public class Main {
public static void main(String[] args){
new Main().run();
}
public void run(){
MongoClient client = MongoClients.create("mongodb://localhost:27018");
MongoDatabase db = client.getDatabase("db1").withCodecRegistry(fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().register(
ClassModel.builder(MyInterface.class).enableDiscriminator(true).build(),
ClassModel.builder(ImplA.class).enableDiscriminator(true).build()
).build())
));
MyInterface obj1 = new ImplA();
db.getCollection("ImplA",ImplA.class).insertOne((ImplA) obj1);
db.getCollection("ImplA",obj1.getClass()).insertOne(obj1);
db.getCollection("ImplA",Object.class).insertOne(obj1);
}
}
在第一个插入编译时,第二个插入失败并出现以下错误:
错误:错误:行(42)java:不兼容的类型:Main.MyInterface 无法转换为 capture#1 of ?扩展 Main.MyInterface
在我看来,这个功能应该是可能的,因为 MongoCollection 肯定有关于类型的信息。传入的对象具有某种类型,我想要该类型的集合并插入它。如果第二个 insertOne 被注释掉,则代码编译。驱动程序抛出一个异常,说 Object 没有编解码器;因此,它肯定是从给定的内容中确定要使用的编解码器来获取集合。
更新:我曾尝试使用 getClass.cast 进行各种转换,各种泛型组合,但这里有一个可行的选项:
MyInterface obj1 = new ImplA();
Class<MyInterface> myC = (Class<MyInterface>) Class.forName(obj1.getClass().getName());
db.getCollection("ImplA",myC).insertOne(obj1);
这可能会引发类未找到异常,并且看起来不必要地复杂。
解决方案
尝试使用: db.getCollection("ImplA").withDocumentClass(obj1.getClass()).insertOne(obj1)
推荐阅读
- java - Docker PostgreSQL 中的连接被拒绝
- oracle - 如何在oracle中转换数字中的指数值
- python - 根据列的平均值更改列索引
- vba - 在第 1 行下方添加行,用 docvariable 和增量填充第一个单元格
- c# - 使用 Prism EventAggregator 实现弹出窗口(新窗口)
- vue.js - Vuex 分析:如何知道一个 vuex 状态或内存中的组件大小
- excel - 如何使用宏删除excel中的特定行和升档单元格?
- reactjs - 组件渲染已触发,但 DOM 未更新
- c++ - 在 windows x64 上设置 openssl 时找不到 libeay32.lib 和 ssleay32.lib 文件
- sql - 为分隔字符串重新迭代字符串提取