【问题标题】:POJO to org.bson.Document and Vice VersaPOJO 到 org.bson.Document 和反之亦然
【发布时间】:2016-09-04 19:43:40
【问题描述】:

有没有简单的方法可以将 Simple POJO 转换为 org.bson.Document?

我知道有很多方法可以做到这一点:

Document doc = new Document();
doc.append("name", person.getName()):

但是它有一个更简单且打字更少的方法吗?

【问题讨论】:

    标签: java mongodb-java


    【解决方案1】:

    目前 Mongo Java Driver 3.9.1 提供开箱即用的 POJO 支持
    http://mongodb.github.io/mongo-java-driver/3.9/driver/getting-started/quick-start-pojo/
    假设您有一个包含一个嵌套对象的示例集合

    db.createCollection("product", {
    validator: {
        $jsonSchema: {
            bsonType: "object",
            required: ["name", "description", "thumb"],
            properties: {
                name: {
                    bsonType: "string",
                    description: "product - name - string"
                },
                description: {
                    bsonType: "string",
                    description: "product - description - string"
                },
                thumb: {
                    bsonType: "object",
                    required: ["width", "height", "url"],
                    properties: {
                        width: {
                            bsonType: "int",
                            description: "product - thumb - width"
                        },
                        height: {
                            bsonType: "int",
                            description: "product - thumb - height"
                        },
                        url: {
                            bsonType: "string",
                            description: "product - thumb - url"
                        }
                    }
                }
    
            }
        }
    }});
    

    1.为 MongoDatabase bean 提供适当的 CodecRegistry

    @Bean
    public MongoClient mongoClient() {
        ConnectionString connectionString = new ConnectionString("mongodb://username:password@127.0.0.1:27017/dbname");
    
        ConnectionPoolSettings connectionPoolSettings = ConnectionPoolSettings.builder()
                .minSize(2)
                .maxSize(20)
                .maxWaitQueueSize(100)
                .maxConnectionIdleTime(60, TimeUnit.SECONDS)
                .maxConnectionLifeTime(300, TimeUnit.SECONDS)
                .build();
    
        SocketSettings socketSettings = SocketSettings.builder()
                .connectTimeout(5, TimeUnit.SECONDS)
                .readTimeout(5, TimeUnit.SECONDS)
                .build();
    
        MongoClientSettings clientSettings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .applyToConnectionPoolSettings(builder -> builder.applySettings(connectionPoolSettings))
                .applyToSocketSettings(builder -> builder.applySettings(socketSettings))
                .build();
    
        return MongoClients.create(clientSettings);
    }
    
    @Bean 
    public MongoDatabase mongoDatabase(MongoClient mongoClient) {
        CodecRegistry defaultCodecRegistry = MongoClientSettings.getDefaultCodecRegistry();
        CodecRegistry fromProvider = CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build());
        CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(defaultCodecRegistry, fromProvider);
        return mongoClient.getDatabase("dbname").withCodecRegistry(pojoCodecRegistry);
    }
    

    2。注释您的 POJOS

    public class ProductEntity {
    
        @BsonProperty("name") public final String name;
        @BsonProperty("description") public final String description;
        @BsonProperty("thumb") public final ThumbEntity thumbEntity;
    
        @BsonCreator
        public ProductEntity(
                @BsonProperty("name") String name,
                @BsonProperty("description") String description,
                @BsonProperty("thumb") ThumbEntity thumbEntity) {
            this.name = name;
            this.description = description;
            this.thumbEntity = thumbEntity;
        }
    }
    
    public class ThumbEntity {
    
        @BsonProperty("width") public final Integer width;
        @BsonProperty("height") public final Integer height;
        @BsonProperty("url") public final String url;
    
        @BsonCreator
        public ThumbEntity(
                @BsonProperty("width") Integer width,
                @BsonProperty("height") Integer height,
                @BsonProperty("url") String url) {
            this.width = width;
            this.height = height;
            this.url = url;
        }
    }
    

    3.查询mongoDB获取POJOS

    MongoCollection<Document> collection = mongoDatabase.getCollection("product");
    Document query = new Document();
    List<ProductEntity> products = collection.find(query, ProductEntity.class).into(new ArrayList<>());
    


    就是这样!您可以轻松获得您的 POJOS 无需繁琐的手动映射 并且不会失去运行本机 mongo 查询的能力

    【讨论】:

    • 它们不是必需的,请看一下:mongodb.github.io/mongo-java-driver/3.6/bson/pojos 但是,在我看来,注释真的很棒,因为: - 你可以使 POJO 对象不可变,这总是一个好习惯 - 不可变对象代码不易出错,并且您摆脱了所有这些 getter 和 setter - 当 mongo 中的字段名称更改时,您可以轻松更改其注释,而无需触摸 POJO 对象中的字段名称
    • 无论如何我们可以将它与非嵌套类一起使用,但是那些具有对不同类的对象引用的类?我已经使用 @Field 注释将它们映射到我的数据库。
    • 这是否适用于抽象类和继承?
    【解决方案2】:

    您可以使用GsonDocument.parse(String json) 将POJO 转换为Document。这适用于 3.4.2 版本的 java 驱动程序。

    类似这样的:

    package com.jacobcs;
    
    import org.bson.Document;
    
    import com.google.gson.Gson;
    import com.mongodb.MongoClient;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    
    public class MongoLabs {
    
        public static void main(String[] args) {
            // create client and connect to db
            MongoClient mongoClient = new MongoClient("localhost", 27017);
            MongoDatabase database = mongoClient.getDatabase("my_db_name");
    
            // populate pojo
            MyPOJO myPOJO = new MyPOJO();
            myPOJO.setName("MyName");
            myPOJO.setAge("26");
    
            // convert pojo to json using Gson and parse using Document.parse()
            Gson gson = new Gson();
            MongoCollection<Document> collection = database.getCollection("my_collection_name");
            Document document = Document.parse(gson.toJson(myPOJO));
            collection.insertOne(document);
        }
    
    }
    

    【讨论】:

    • 如果使用 Long 怎么样,Gson 不会像 bson 期望的那样处理 Long。示例:a = int, b = long 应该以 { "a" : 12, "b" : { "$numberLong" : "14" } } 结尾,但看起来所有值都添加为 'a'。
    【解决方案3】:

    重点是,您不需要将手放在 org.bson.Document 上。

    Morphia 会在幕后为你做这一切。

    import com.mongodb.MongoClient;
    import org.mongodb.morphia.Datastore;
    import org.mongodb.morphia.DatastoreImpl;
    import org.mongodb.morphia.Morphia;
    import java.net.UnknownHostException;
    
    .....
        private Datastore createDataStore() throws UnknownHostException {
            MongoClient client = new MongoClient("localhost", 27017);
            // create morphia and map classes
            Morphia morphia = new Morphia();
            morphia.map(FooBar.class);
            return new DatastoreImpl(morphia, client, "testmongo");
        }
    
    ......
    
        //with the Datastore from above you can save any mapped class to mongo
        Datastore datastore;
        final FooBar fb = new FooBar("hello", "world");
        datastore.save(fb);
    

    这里有几个例子:https://mongodb.github.io/morphia/

    【讨论】:

      【解决方案4】:

      我不知道您的 MongoDB 版本。但是现在,没有必要将 Document 转换为 POJO,反之亦然。您只需要根据您想要使用的文档或 POJO 创建您的集合,如下所示。

      //If you want to use Document
      MongoCollection<Document> myCollection = db.getCollection("mongoCollection");
      Document doc=new Document();
      doc.put("name","ABC");
      myCollection.insertOne(doc);
      
      
      //If you want to use POJO
      MongoCollection<Pojo> myCollection = db.getCollection("mongoCollection",Pojo.class);
      Pojo obj= new Pojo();
      obj.setName("ABC");
      myCollection.insertOne(obj);
      

      如果您想使用 POJO,请确保您的 Mongo DB 配置了正确的编解码器注册表。

      MongoClient mongoClient = new MongoClient();
      //This registry is required for your Mongo document to POJO conversion
      CodecRegistry codecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
              fromProviders(PojoCodecProvider.builder().automatic(true).build()));
      MongoDatabase db = mongoClient.getDatabase("mydb").withCodecRegistry(codecRegistry);
      

      【讨论】:

        【解决方案5】:

        如果您使用的是 Morphia,则可以使用这段代码将 POJO 转换为文档。

        Document document = Document.parse( morphia.toDBObject( Entity ).toString() )
        

        如果您不使用 Morphia,那么您可以通过编写自定义映射并将 POJO 转换为 DBObject 并进一步将 DBObject 转换为字符串然后解析它来执行相同的操作。

        【讨论】:

          【解决方案6】:

          如果你将 Spring Data MongoDB 与 springboot 一起使用,MongoTemplate 有一个方法可以很好地做到这一点。

          Spring Data MongoDB API

          这是一个示例。

          1.首先在spring boot项目中自动装配mongoTemplate。

          @Autowired
          MongoTemplate mongoTemplate;
          

          2.在你的服务中使用 mongoTemplate

          Document doc = new Document();
          mongoTemplate.getConverter().write(person, doc);
          

          为了做到这一点,你需要配置你的 pom 文件和 yml 来注入 mongotemplate

          pom.xml

          <dependency>
              <groupId>org.springframework.data</groupId>
              <artifactId>spring-data-mongodb</artifactId>
              <version>2.1.10.RELEASE</version>
          </dependency>
          

          application.yml

          # mongodb config
          spring:
            data:
              mongodb:
                uri: mongodb://your-mongodb-url
          

          【讨论】:

          • 请添加一些解释给你回答。
          【解决方案7】:

          不,我认为它对 bulkInsert 很有用。我认为 bulkInsert 不能与 pojo 一起使用(如果我没记错的话)。 如果有人知道如何使用 bulkInsert

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-28
          • 2015-11-18
          • 2012-03-24
          • 1970-01-01
          • 1970-01-01
          • 2012-12-10
          • 2014-11-08
          相关资源
          最近更新 更多