ZK With MongoDB Part 1 - Using MongoDB Java Driver

From Documentation
DocumentationSmall Talks2012JanuaryZK With MongoDB Part 1 - Using MongoDB Java Driver
ZK With MongoDB Part 1 - Using MongoDB Java Driver

Author
Ashish Dasnurkar
Date
Jan 18, 2012
Version
ZK 5

WarningTriangle-32x32.png This page is under construction, so we cannot guarantee the accuracy of the content!

Introduction

ZK is primarily an UI framework and it doesn't make any assumptions about application's persistence layer or database. Application developers are free to use any database (relational or non-relational) and any data access layer solutions that work with those databases. Typically, for relational databases developers either use plain JDBC or some sophisticated object-relational mapping library like Hibernate. In this small talk series I will show how developers can develop non-relational database driven ZK application.

I will describe a simple TODO list application that uses mongoDB which is a popular non-relational database. In this series I will show three approaches to work with mongoDB. In Part 1 I will use mongoDB Java driver APIs for TODO tasks CRUD operations which is similar to using JDBC driver for relational databases. In Part 2, I will use morphia , a lightweight type-safe library for mapping Java objects to/from mongoDB, which is similar to using Hibernate for relational databases. Finally for developers who are familiar with Spring framework, in Part 3 I will show how to leverage Spring Data mongoDB support to work with mongoDB database.

mongoDB Overview

mongoDB is a document oriented database that manages collections of BSON documents. Each BSON document is a set of fields. Each field is a key-value pair where key is a string and value can be other basic types, a BSON document or array of values. Below is a sample of tasks collection

{ "_id" : ObjectId("4e97d8b7dfa2925b0844a3c9"), "id" : "c011a1df-22ab-4607-a358-ea2f2873b51e", "name" : "Write article", "priority" : 1, "date" : ISODate("2011-10-06T16:00:00Z") }
{ "_id" : ObjectId("4e97d8e5dfa2925b0844a3ca"), "id" : "ce4a059f-1825-4410-bf95-4c30e11aca14", "name" : "Conference call", "priority" : 2, "date" : ISODate("2011-10-13T16:00:00Z") }
{ "_id" : ObjectId("4e97d8f0dfa2925b0844a3cb"), "id" : "0b0db7ac-b5db-40a6-9c8e-2c86581a3e89", "name" : "Release 5", "priority" : 1, "date" : ISODate("2011-10-27T16:00:00Z")}

In this example, each Task document has 5 fields. _id is auto-generated by mongoDB whenever a document is added to the collection. Remaining four fields - id,name,prority and date contains Task data. Note that mongoDB is schema free so you do not have to pre-define this Task document structure. It will be automatically created when first Task document is saved in the database. For this article all you need is an installed instance of mongoDB. You can follow mongoDB quick-start guide to setup and get the mongoDB running.

TODO application Overview

I will use same TODO application for each part. The application itself is a simple ZUML page showing list of tasks to do in a listbox and couple input components to enter and/or edit task details. Users can add, update and delete tasks by clicking the related buttons.

It is based on ZK's MVC pattern. Below is the View part todo.zul page

View

 

<window title="Simple Todo application with mongoDB Java driver" width="640px" border="normal" apply="org.zkoss.mongodb.controller.SimpleTodoController">
	<listbox id="tasks" multiple="true" rows="10">
		<listhead>
			<listheader label="Item" />
			<listheader label="Priority" width="50px" />
			<listheader label="Date" width="90px" />
		</listhead>
	</listbox>
	<groupbox>
		<caption label="Event" />
		Item: <textbox id="name" constraint="no empty" cols="25" />
		Priority: <intbox id="priority" cols="1" constraint="no empty"/>
		Date: <datebox id="date" cols="8" constraint="no empty"/>
		<button id="add" label="Add" />
		<button id="update" label="Update" />
		<button id="delete" label="Delete" />
	</groupbox>
</window>

mongoDB Java driver

First, either manually download mongoDB java driver from here and place it in your application classpath (WEB-INF/lib) or if you are using Maven, include the following dependency in your project pom.xml file

 

<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>2.6.5</version>
		</dependency>

Model

Data for tasks listbox is ListModel model, a list of Task Javabean objects retrieved from mongoDB database. Below is Task Javabean definition

Task.java code

public class Task {
	private String id;
	private String name;
	private int priority;
	private Date executionDate;

	public Task(){ }

	public Task(String id,String name,int priority,Date date){
		this.id = id;
		this.name = name;
		this.priority = priority;
		this.setExecutionDate(date);
	}
	// setters and getter for all fields
}


Next I define a mongoDB connection manager singlton class that holds an instance of Mongo that represents a pool of database connections with internal pooling. I use this Mongo instance to connect with "simpletasks" database using getDB(String) API.

 

public class MongoDBManager {

	private static Mongo mongo = null;
	private MongoDBManager() {};

	public static synchronized DB getDB(String dbName) throws Exception {
		if(mongo == null) {
			mongo = new Mongo();
		}
		return mongo.getDB(dbName);
	}
}
  • Note that database doesn't have to pre-exist. If it isn't created yet, mongoDB will create it for you.

  • Next I create a TaskDAO for performing CRUD operations on "Tasks" collection within our "simpletasks" mongoDB database. Lets first see how to get list of all tasks in database.

     
    public List<Task> findAll(){
    		List<Task> tasks = new ArrayList<Task>();
    		try {
    			DB db = MongoDBManager.getDB("simpletasks");
    			DBCollection coll = db.getCollection("Tasks");
    			DBCursor cursor = coll.find();
    
    			while (cursor.hasNext()) {
    				DBObject dbobj = cursor.next();
    				Task task = new Task((String) dbobj.get("id"),
    						(String) dbobj.get("name"),
    						(Integer) dbobj.get("priority"),
    						(Date) dbobj.get("date"));
    				tasks.add(task);
    			}
    
    		} catch (Exception e) {}
    		return tasks;
    	}
    


    First I get a single connection with "simpletasks" database and use it to get "Tasks" collection instance. DBCollection#find() returns a cursor that can be used to iterate over set of documents in that collections. DBCursor#next() returns one DBObject instance that represents one document inside the collection. DBObject is a Map like representation of document stored in mongoDB. I manually retrieve each field from this DBObject instance and create a Task Javabean instance and add it to my tasks ArrayList. DBCollection has all the necessary APIs to insert, remove and update documents. Below is the method that inserts new Task document in "Tasks" collection using DBCollection#insert(DBObject) API