A CRUD App with MongoDB Java
October 2, 2020
1. Overview
This is an example Java application with a command-line user interface to perform CRUD operations (Create Read Update Delete) on MongoDB database.
MongoDB is a NoSQL document based database. Data is stored in databases, collections and documents. These are analogous to database, table and row in SQL and tabular database system. The document data is similar to JSON in structure, with fields defined as key value pairs. The data stored in the database is BSON (binary JSON) types. These are an extension to JSON which provide additional data types like date, various numeric types, etc., in addition to the JSON string, boolean, number, array and object types.
The standard way to connect to the MongoDB server is from a client application. mongo
shell, the command-line tool is included with the database, is commonly used to perform administrative and data related tasks. A client can also be an application developed using a programming language like Java, Python or NodeJS platform. The client program connects to the database server via a driver. For Java applications it is the MongoDB Java Driver. In addition to connection, the driver also converts the data from the client format to the BSON stored on the database server, and vice-versa.
This application is command-line program, runs from the OS terminal. It has a menu as shown in the screenshot below. The user can select an option to perform a task - a CRUD operation. The user can enter data interactively and get the result of the database operation.
The application is written using Java SE 8 and MongoDB Java Driver v3.12.2. The app connects to MongoDB Server v4.2.8. The code runs from the terminal or from an IDE like IntelliJ Idea.
The Java source code for the application can be downloaded from the Download section below.
2. The mongo Shell
mongo
shell is an interactive command-line tool included with an installation of the MongoDB. You can connect to the server by typing:
> mongo
This connects to the server and shell interface allows the database operations. By default, the shell connects to MongoDB running on localhost
with port 27017
. You can also specify these options when starting the shell.
Here are some basic commands (Note the shell use JavaScript syntax):
> show dbs
test
blog
> show collections
persons
sales
testColl
> db
test
> use crud
switched to db crud
> var doc = { name: "John", city: "New York" }
> db.names.insertOne(doc);
{
"acknowledged" : true,
"insertedId" : ObjectId("5f6cac04d35a6397ae971f18")
}
> db.names.find()
{ "_id" : ObjectId("5f6cac04d35a6397ae971f18"), "name" : "John", "city" : "New York" }
The above code (or commands) lists all the databases, lists all the collections in the current database, shows what the current database is, makes a database current, creates a JSON document and assigns it to a variable, inserts the JSON into a collection and queries the collection.
In the above code, the crud
database and names
collection are created newly with the insert command. When the first document is inserted into a collection, the database and collection are created, if they do not already exist.
The updateOne
and deleteOne
commands are used to update and delete a document from the collection. The find, update and delete take a filter as an argument to target a specific document. There are variations of these methods to work with multiple documents (e.g., insertMany
).
Note the field _id
from the result of the find query. It is created by the driver and is of type ObjectId
. It is assigned to the newly inserted document. This field acts as a primary key. It is a mandatory field for each document in a collection, has a unique index defined on it and is immutable. You can provide your own _id
field's value, and this can be any BSON type except an array; e.g., timestamp, string.
3. CRUD with Java
The example uses a database named crud
and a collection named names
. Each document in the collection has two fields - name
and city
. Then there is the mandatory _id
field. The app's user will supply the name and city field values and the _id
field is system generated. An example document:
{
"_id" : ObjectId("5f6cac04d35a6397ae971f18"),
"name" : "John",
"city" : "New York"
}
The app's MongoOps.java
class has all the database related operations: create a connection, insert, update, delete a document, query all documents and finally query by the two fields or a single field.
3.1. Database Connection
The following code creates a connection to the database and gets an instance of collection. We will apply CRUD methods on this collection
object.
final String CONNECTION_URL = "mongodb://localhost:27017/";
MongoClient mongoClient = MongoClients.create(CONNECTION_URL);
MongoCollection<Document> collection = mongoClient.getDatabase("crud")
.getCollection("names");
3.2. Insert Document
The app's create function adds a document for a given name
and city
. In case the user doesn't provide any or both the values, the program will pick a random name
and/or city
from an array of few values. The document creation code using the user supplied field values:
Document doc = new Document("name", name).append("city", city);
collection.insertOne(doc);
3.3. Update Document
The update function updates the city
field value for a given name
. The update happens using the user supplied field values. The update method takes a filter to find the document with the matching name
and applies the update on the city
field:
Bson filter = Filters.eq("name", name);
Bson update = Updates.set("city", city);
UpdateResult result = collection.updateOne(filter, update);
3.4. Delete Document
The delete operation lets user specify the name
field and the corresponding document is deleted from the collection.
Bson filter = new Document().append("name", name);
DeleteResult result = collection.deleteOne(filter);
3.5. Query Collection
There are two query functions.
The "query all" gets all the documents from the collection and collects them in a List<Document>
:
return collection.find().into(new ArrayList<Document>());
Here is the screenshot showing the query result. Note the "_id": {"$oid": "5f6ee6ab4bf05b07430c5193"}
is the JSON representation of ObjectId("5f6ee6ab4bf05b07430c5193")
.
Then there is a query by field - name
and/or city
. In this case a filter is applied specifying the condition. The specific name
and/or city
are provided by the user.
Bson filter = Filters.eq("city", city);
Bson filter = Filters.eq("name", name);
Bson filter = Filters.and(Filters.eq("name", name), Filters.eq("city", city));
The query with the filter:
return collection.find(filter).into(new ArrayList<Document>());
3.6. Other Database Operations
Though not included in this app's functionality, here are some database administrative commands:
MongoClient#listDatabases()
MongoDatabase#drop()
MongoDatabase#createCollection()
MongoCollection#countDocuments()
MongoDatabase#runCommand()
The above commands explain themselves. Note that all are instance methods. The runCommand()
allows run the native MongoDB commands from your Java application. For example, database.runCommand(new Document("drop", "testdb"));
, drops the specified database.
4. Notable Features
MongoDB also has these features out of the box: Transactions, Change Streams (access real-time data changes), Replication (data redundancy and high availability using multiple servers) and Sharding (data distribution across multiple servers).
An important feature of MongoDB document structure is its flexible schema. For example, you can include a new field into a document without any new definitions. Consider the code from the mongo
shell:
> db.names.insertOne(
{ name: "Kim", city: "Seoul", favorites: [ "apples", "red", "sailing" ] }
)
This code snippet inserts a new document into the names
collection with the new array field favorites
. Now the collection has documents with different fields. For stricter validation of document structure you can use the Schema Validation feature for insert and update operations.
5. The Example Application
The Main.java
launches the app. This class uses a java.util.Scanner
to accept user input from command-line. The input is validated, processed and the result is shown on the terminal. All the database operations are performed in the MongoOps.java
class.
The MongoDB database access code uses the MongoDB Java driver. By default this driver logs using a logger. This app is a command-line program and the detailed logging interferes with the app's functionality (reading from the terminal and writing to it). So, the logging is suppressed by setting the logging level to LEVEL.SEVERE
from the default INFO
.
The insert, update and delete database operation Java methods may throw a runtime exception, the MongoException
due to an error during an operation. In such a case the application prints an appropriate message and exits. There is also a properties file with the MongoDB connection host and port information. The propreties are loaded from the AppProperties.java
class.
Browse the Java source code:
6. Download
Download the Java source code for the example: mongo-java-crud-app.zip
7. Useful Links
- Get MongoDB
- MongoDB Installation instructions
- MongoDB Java Driver
- The mongo Shell
- MongoDB CRUD Operations