我的问题是将MongoDB
文档转换为一种类型:
getCollection
javadoc
说:
/**
* Gets a collection, with a specific default document class.
*
* @param collectionName the name of the collection to return
* @param documentClass the default class to cast any documents returned from the database into.
* @param <TDocument> the type of the class to use instead of {@code Document}.
* @return the collection
*/
<TDocument> MongoCollection<TDocument> getCollection(String collectionName, Class<TDocument> documentClass);
这是我的实施:
public class AccountDAO {
public static FindIterable<AccountDTO> accountPersist(AccountDTO accountDTO){
MongoCollection<AccountDTO> accountDataCollection = Utils.getDbCollection();
accountDataCollection.insertOne(accountDTO);
return accountDataCollection.find();
}
}
和getDbCollection
:
public static MongoCollection<AccountDTO> getDbCollection() {
MongoDatabase db = Utils.getDbConnect();
MongoCollection<AccountDTO> accountDataCollection = null ;
accountDataCollection = db.getCollection(AccountDTO.COLLECTION_NAME,AccountDTO.class);
return accountDataCollection;
}
CodecImplementationProvider:
package utils;
import org.bson.BsonReader;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import org.bson.codecs.configuration.CodecRegistry;
import digester.Account;
import digester.Customer;
import dto.AccountDTO;
// the Codec extends two interfaces: Encoder<T>, Decoder<T>
class MyAccountDTOImpCodec implements Codec<AccountDTO> {
private CodecRegistry codecRegistry;
public MyAccountDTOImpCodec(CodecRegistry codecRegistry) {
this.codecRegistry = codecRegistry;
}
public void encode(BsonWriter writer, AccountDTO doc, EncoderContext encoderContext) {
writer.writeStartDocument();
writer.writeName("IBAN");
writer.writeString(doc.getIBAN());
writer.writeName("customerFirstName");
writer.writeString(doc.getCustomerFirstName());
writer.writeName("customerLastName");
writer.writeString(doc.getCustomerLastName());
writer.writeEndDocument();
}
public Class<AccountDTO> getEncoderClass() {
return AccountDTO.class;
}
public AccountDTO decode(BsonReader reader, DecoderContext decoderContext) {
reader.readStartDocument();
String iBAN = reader.readString("IBAN");
String firstName = reader.readString("customerFirstName");
String lastName = reader.readString("customerLastName");
double balance = reader.readDouble("balance");
String currency = reader.readString("currency");
long customerId = reader.readInt64("customerId");
reader.readEndDocument();
Account account = new Account(iBAN, balance, currency);
Customer customer = new Customer(firstName, lastName, customerId, account);
AccountDTO doc = new AccountDTO(account, customer);
return doc;
}
}
CodecProvider:
package utils;
import org.bson.codecs.Codec;
import org.bson.codecs.configuration.CodecProvider;
import org.bson.codecs.configuration.CodecRegistry;
import dto.AccountDTO;
class MyCodecProvider implements CodecProvider {
public <T> Codec<T> get(Class<T> myClass, CodecRegistry codecRegistry) {
if (myClass== AccountDTO.class) {
return (Codec<T>) new MyAccountDTOImpCodec(codecRegistry);
}
return null;
}
}
使用JUnit
运行测试时,我得到了这个堆栈:
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class dto.AccountDTO.
我认为这是一个糟糕的实现,在Node.js
我会发送我的json
对象,将java
对象发送到MongoDB
似乎很奇怪。
这只是对javadoc
的错误解释还是我的代码缺乏?
答案 0 :(得分:3)
您必须为Java类实现 Codec ,然后MongoDB将能够将BSON值解码为Java对象并将Java对象编码为BSON值。看看这个Mongo Java Driver Doc:http://mongodb.github.io/mongo-java-driver/3.0/bson/codecs/
这将是代表MongoDB集合中文档的POJO类:
class MyDocument {
private String id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "MyDocument [id=" + id + ", name=" + name + "]";
}
}
我们需要创建一个实现 Codec接口的类,此外还扩展了接口:Encoder<T>
和Decoder<T>
。该类将提供将MyDocument Java对象编码和解码为BSON文档的方法。
class MyDocumentImpCodec implements Codec<MyDocument> {
private CodecRegistry codecRegistry;
public MyDocumentImpCodec(CodecRegistry codecRegistry) {
this.codecRegistry = codecRegistry;
}
public void encode(BsonWriter writer, MyDocument doc, EncoderContext encoderContext) {
writer.writeStartDocument();
writer.writeName("_id");
writer.writeString(doc.getId());
writer.writeName("name");
writer.writeString(doc.getName());
writer.writeEndDocument();
}
public MyDocument decode(BsonReader reader, DecoderContext decoderContext) {
reader.readStartDocument();
String id = reader.readString("_id");
String name = reader.readString("name");
reader.readEndDocument();
MyDocument doc = new MyDocument();
doc.setId(id);
doc.setName(name);
return doc;
}
public Class<MyDocument> getEncoderClass() {
return MyDocument.class;
}
}
CodecProvider 是Codec实例的工厂。
class MyCodecProvider implements CodecProvider {
public <T> Codec<T> get(Class<T> myClass, CodecRegistry codecRegistry) {
if (myClass == MyDocument.class) {
return (Codec<T>) new MyDocumentImpCodec(codecRegistry);
}
return null;
}
}
CodecRegistry类包含一组Codec实例,这些实例根据它们编码和解码的Java类进行访问。在我们的示例中,CodecRegistry实例仅获取我们之前定义的MyCodecProvider和default codec registries。
public static MongoCollection<AccountDTO> getDbCollection() {
// ...................................................
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromProviders(new MyCodecProvider()),
MongoClient.getDefaultCodecRegistry());
MongoClientOptions options = MongoClientOptions
.builder()
.codecRegistry(codecRegistry)
.build();
// ...................................................
MongoClient mongoClient = new MongoClient(MONGODB_SERVER_IP, options);
MongoDatabase = db = mongoClient.getDatabase(MONGODB_SERVER_DATABASE_NAME);
MongoCollection<MyDocument> collection = db.getCollection(
MONGODB_SERVER_COLLECTION_NAME,
MyDocument.class);
return collection;
}
实现DAO方法的示例:
public static void getDocument() {
FindIterable<MyDocument> iterator = collection.find();
for (MyDocument doc : iterator) {
System.out.println(doc);
}
}
public static void insertDocument() {
MyDocument doc = new MyDocument();
doc.setId("1001");
doc.setName("myName");
collection.insertOne(doc);
}