@@ -13,17 +13,218 @@ Document Data Format: POJOs
13
13
Overview
14
14
--------
15
15
16
- - Description; convert between BSON and POJOs
17
- - Summary of contents of this doc
16
+ This guide explains how you can store and retrieve MongoDB data using plain
17
+ old Java objects (`POJOs <https://en.wikipedia.org/wiki/Plain_old_Java_object>`__).
18
+ POJOs are often used for data encapsulation, separating business logic from
19
+ data representation.
18
20
19
- CodecRegistry
20
- -------------
21
+ In the following sections we show:
21
22
22
- - Brief introduction, link to data-formats/codecs for more info
23
- - Example demonstrating the following:
24
- - specifying how to create a CodecRegistry that uses PojoCodecProvider
25
- - example POJO class with getters/setters
26
- - include user-defined classes and lists
27
- - Sample input/output of aforementioned example
23
+ - a POJO example
24
+ - how to configure the driver to serialize and deserialize the POJO
25
+ - sample code to read and write documents to MongoDB using the POJO
28
26
29
- - Link to data-formats/pojo-customization for more information
27
+ .. _fundamentals-example-pojo:
28
+
29
+ Example POJO
30
+ ------------
31
+
32
+ To follow the steps in this guide, you can create your own class or use the
33
+ following sample POJO class which describes characteristics of a flower:
34
+
35
+ .. code-block:: java
36
+
37
+ public class Flower {
38
+
39
+ private ObjectId id;
40
+ private String name;
41
+ private List<String> colors;
42
+ private Boolean isBlooming;
43
+ private Float height;
44
+
45
+ // public empty constructor needed for retrieving the POJO
46
+ public Flower() {}
47
+
48
+ public Flower(String name, Boolean isBlooming, Float height, List<String> colors) {
49
+ this.name = name;
50
+ this.isBlooming = isBlooming;
51
+ this.height = height;
52
+ this.colors = colors;
53
+ }
54
+
55
+ public ObjectId getId() {
56
+ return id;
57
+ }
58
+
59
+ public void setId(ObjectId id) {
60
+ this.id = id;
61
+ }
62
+
63
+ public String getName() {
64
+ return name;
65
+ }
66
+
67
+ public void setName(String name) {
68
+ this.name = name;
69
+ }
70
+
71
+ public Boolean getIsBlooming() {
72
+ return isBlooming;
73
+ }
74
+
75
+ public void setIsBlooming(Boolean isBlooming) {
76
+ this.isBlooming = isBlooming;
77
+ }
78
+
79
+ public Float getHeight() {
80
+ return height;
81
+ }
82
+
83
+ public void setHeight(Float height) {
84
+ this.height = height;
85
+ }
86
+
87
+ public List<String> getColors() {
88
+ return colors;
89
+ }
90
+
91
+ public void setColors(List<String> colors) {
92
+ this.colors = colors;
93
+ }
94
+
95
+ @Override
96
+ public String toString() {
97
+ return "Flower [id=" + id + ", name=" + name + ", colors=" + colors + ", isBlooming=" + isBlooming + ", height=" + height + "]";
98
+ }
99
+ }
100
+
101
+ If you are creating your own POJO for storing and retrieving data in MongoDB,
102
+ make sure to follow the following guidelines:
103
+
104
+ - The POJO class should not implement interfaces or extend classes from a
105
+ framework.
106
+ - Include all the fields for which you want to store and retrieve data;
107
+ make sure they are not ``static`` or ``transient``.
108
+ - If you include public getter or setter methods using the
109
+ `JavaBean naming conventions <https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html>`__
110
+ in your POJO, the driver calls them when serializing or deserializing data.
111
+ If you omit the getter or setter methods for a public property field, the
112
+ driver accesses or assigns them directly.
113
+
114
+ Configure the Driver for POJOs
115
+ ------------------------------
116
+
117
+ To set up the driver to store and retrieve POJOs, we need to specify:
118
+
119
+ - The ``PojoCodecProvider``, a codec provider that includes
120
+ :doc:`Codecs </fundamentals/data-formats/codecs>` that define how to
121
+ encode/decode the data between the POJO and MongoDB document, and which
122
+ POJO classes or packages that the Codecs should apply to.
123
+ - A :java-docs:`CodecRegistry <apidocs/bson/org/bson/codecs/configuration/CodecRegistry.html>`
124
+ instance that contains the codec provider and other related information.
125
+ - A ``MongoClient``, ``MongoDatabase``, or ``MongoCollection`` instance
126
+ configured to use the ``CodecRegistry``.
127
+ - A ``MongoCollection`` instance created with the POJO document class
128
+ bound to the :java-docs:`TDocument </apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html>`__
129
+ generic type.
130
+
131
+ Follow the steps below to see how to perform each of the configuration
132
+ requirements:
133
+
134
+
135
+ 1. Configure the :java-docs:`PojoCodecProvider <apidocs/bson/org/bson/codecs/pojo/PojoCodecProvider.html>`,
136
+ a codec provider that provides the Codecs that define how to encode the data
137
+ and on which classes to apply the Codecs. In this example, we use the
138
+ :java-docs:`automatic(true) <apidocs/bson/org/bson/codecs/pojo/PojoCodecProvider.Builder.html#automatic(boolean)>`
139
+ setting of the :java-docs:`PojoCodecProvider.Builder <apidocs/bson/org/bson/codecs/pojo/PojoCodecProvider.Builder.html>`
140
+ to apply the Codecs to any class and its properties.
141
+
142
+ .. code-block:: java
143
+
144
+ CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
145
+
146
+ .. note::
147
+
148
+ Codec providers also contain other objects such as ``ClassModel`` and
149
+ ``Convention`` instances that further define serialization behavior.
150
+ For more information on codec providers and customization, see our guide
151
+ on :doc:`POJO Customization </fundamentals/data-formats/pojo-customization>`.
152
+
153
+
154
+ #. Add the ``PojoCodecProvider`` instance to a ``CodecRegistry``. The
155
+ ``CodecRegistry`` allows you to specify one or more codec providers to
156
+ encode the POJO data. In this example, we call the following methods:
157
+
158
+ - :java-docs:`fromRegistries() <apidocs/bson/org/bson/codecs/configuration/CodecRegistries.html#fromRegistries(org.bson.codecs.configuration.CodecRegistry...)>`
159
+ to combine multiple ``CodecRegistry`` instances into a single one
160
+ - :java-docs:`getDefaultCodecRegistry() <apidocs/mongodb-driver-core/com/mongodb/MongoClientSettings.html?is-external=true#getDefaultCodecRegistry()>`
161
+ to retrieve a ``CodecRegistry`` instance from a list of codec providers
162
+ - :java-docs:`fromProviders() <apidocs/bson/org/bson/codecs/configuration/CodecRegistries.html#fromProviders(org.bson.codecs.configuration.CodecProvider...)>`
163
+ to create a ``CodecRegistry`` instance from the ``PojoCodecProvider``
164
+
165
+ See the code below to see how to instantiate the ``CodecRegistry``:
166
+
167
+ .. code-block:: java
168
+
169
+ // ensure you use the following static imports above your class definition
170
+ import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry;
171
+ import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
172
+ import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
173
+
174
+ // ...
175
+
176
+ CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
177
+
178
+ #. Configure our ``MongoClient``, ``MongoDatabase``, or ``MongoCollection``
179
+ instance to use the Codecs in the ``CodecRegistry``. You only need to
180
+ configure one of these. In this example, we set the ``CodecRegistry`` on a
181
+ ``MongoDatabase`` called ``sample_pojos`` using the ``withCodecRegistry()``
182
+ method.
183
+
184
+ .. code-block:: java
185
+
186
+ try (MongoClient mongoClient = MongoClients.create(uri)) {
187
+ MongoDatabase database = mongoClient.getDatabase("sample_pojos").withCodecRegistry(pojoCodecRegistry);
188
+ // ...
189
+ }
190
+
191
+ #. Pass your POJO class to your call to ``getCollection()`` as the
192
+ document class parameter and specify it as the type argument of your
193
+ ``MongoCollection`` instance as follows:
194
+
195
+ .. code-block:: java
196
+
197
+ MongoCollection<Flower> collection = database.getCollection("flowers", Flower.class);
198
+
199
+ Once you have configured the ``MongoCollection`` instance above, you can:
200
+
201
+ - save an instance of the POJO to the collection
202
+ - retrieve instances of the POJO from a query on the collection
203
+
204
+ The code below shows you how you can insert an instance of ``Flower`` into
205
+ the collection and then retrieve it as a ``List`` of your POJO class objects:
206
+
207
+ .. code-block:: java
208
+
209
+ Flower flower = new Flower("rose", false, 25.4f, Arrays.asList(new String[] {"red", "green"}));
210
+
211
+ // insert the instance
212
+ collection.insertOne(flower);
213
+
214
+ // return all documents in the collection
215
+ List<Flower> flowers = new ArrayList<>();
216
+ collection.find().into(flowers);
217
+ System.out.println(flowers);
218
+
219
+ When you run this code, your output should resemble the following:
220
+
221
+ .. code-block:: none
222
+ :copyable: false
223
+
224
+ [Flower [id=5f7f87659ed5b07cf3480a06, name=rose, colors=[green, red], isBlooming=false, height=25.4]]
225
+
226
+ .. note::
227
+
228
+ By default, the ``PojoCodecProvider`` omits fields in your POJO that are
229
+ set to ``null``. For more information on how to specify this behavior, see
230
+ our guide on :doc:`POJO Customization </fundamentals/data-formats/pojo-customization>`.
0 commit comments