February 3, 2011

Part 9: Creating the DAO Layer

Now that both our Java Data Model and our Database Model are connected through a MyBatis mapper file, we will add a Data Access Object class so we can abstract the calling of SQL statements, and keep our servlet clean of database related code.

I know it's not a 'pure' implementation of the DAO pattern however it serves the main purpose of decoupling servlet code from database related code.

If you want to see a better way to integrate MyBatis and basic DAO classes, check out my other blog post MyBatis DAO Example Code Tutorial

ModelingAgencyDAO.java

ModelingAgencyDAO is going to be a Java class which encapsulates all the 'logical' database functionality we need, such as getting a list of all clients, models and bookings in our database. It will accomplish this by using the MyBatis framework.

For now, create the file ModelingAgencyDAO.java under the com.modelingagency.db package, with the following content:


package com.modelingagency.db;

import java.util.ArrayList;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

import com.modelingagency.objects.Booking;
import com.modelingagency.objects.Client;
import com.modelingagency.objects.Model;

public class ModelingAgencyDAO {

 private SqlSessionFactory sf;
 
 //constructor will receive a myBatis sessionFactory object
 public ModelingAgencyDAO(SqlSessionFactory containerSessionFactory) {
  if(containerSessionFactory==null)
   System.err.println("Error: could not load myBatis sessionFactory");  
  sf = containerSessionFactory;
 }
   
 public ArrayList<Client> getClients() throws PersistenceException{
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList<Client> clients = (ArrayList<Client>)session.selectList("com.modelingagency.objects.SimpleMappers.allClients");    
   return clients;  
  }
  finally
  {
   session.close();
  }
  
 }
  
 public ArrayList<Model> getModels() throws PersistenceException{
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList<Model> models = (ArrayList<Model>)session.selectList("com.modelingagency.objects.SimpleMappers.allModels");    
   return models;
  }
  finally
  {
   session.close();
  }
  
 }
 
 @Test
 public ArrayList<Booking> getBookings() throws PersistenceException{
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList<Booking> bookings = (ArrayList<Booking>)session.selectList("com.modelingagency.objects.SimpleMappers.allBookings");    
   return bookings;   
  }
  finally
  {
   session.close();
  }
  
 }
 
}

You will notice the methods in this DAO class are very similar to the ones we defined in the MyBatisTest class in Part 8. It's a good idea to have a test case setup for your DAO classes.

Now in order to use the DAO from a servlet, all you have to do is create a new object and pass in a MyBatis SqlSessionFactory through the constructor.

Let's modify our TestServlet so we can make use of our DAO class to retreive a list of all clients, a list of all models, and a list of all bookings. Your TestServlet.java class should now look like this:


package com.modelingagency.servlets;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.modelingagency.db.ModelingAgencyDAO;
import com.modelingagency.objects.*;

public class TestServlet  extends HttpServlet{
 
 private static Logger log = LoggerFactory.getLogger(TestServlet.class);
 
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
 {
  HttpSession session = request.getSession();   
  ServletContext sc = getServletContext();
  
  SqlSessionFactory sf = (SqlSessionFactory)getServletContext().getAttribute("sqlSessionFactory");
  ModelingAgencyDAO dao = new ModelingAgencyDAO(sf);
  
  try
  {
   ArrayList<Client> clients = dao.getClients();    
   ArrayList<Model> models = dao.getModels();    
   ArrayList<Booking> bookings = dao.getBookings();    
   
   request.setAttribute("all_clients", clients); 
   request.setAttribute("all_models", models);
   request.setAttribute("all_bookings", bookings);
       
  }
  catch(PersistenceException p)
  {
   p.printStackTrace();  
  }
  finally
  {
   request.setAttribute("message","Welcome to the modeling agency MyBatis tutorial");
   log.info("The message attribute has been set");
  } 
                
  RequestDispatcher view = request.getRequestDispatcher("index.jsp");
  view.forward(request, response);
 }
 
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request,response);
 }
 
}

But before you can run the web application, you'll need to make sure that MyBatis has been initalized and available to the ModelingAgency app.

Part 10: Initializing MyBatis on application startup