Saturday, September 7, 2013

Generic Dao Pattern Code

 // jdbc.properties - connection

hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class = com.mysql.jdbc.Driver
hibernate.connection.url = jdbc:mysql://localhost:3306/test
hibernate.connection.username = root
hibernate.connection.password = ********
hibernate.show_sql = true
hibernate.connection.pool_size = 1
hibernate.hbm2ddl.auto = create

 // app-context.xml - (Application context - spring configuration)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation=" 
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 
          http://www.springframework.org/schema/aop
          http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-2.5.xsd">

 <context:property-placeholder location="classpath:jdbc.properties" />
 <context:component-scan base-package="com.global" />

 <context:annotation-config />

 <!-- HIBERNATE CONFIGURATION -->      
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="packagesToScan" value="com.global.models"/>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
    <prop key="hibernate.connection.driver_class">${hibernate.connection.driver_class}</prop>
    <prop key="hibernate.connection.url">${hibernate.connection.url}</prop>
    <prop key="hibernate.connection.username">${hibernate.connection.username}</prop>
    <prop key="hibernate.connection.password">${hibernate.connection.password}</prop>
    <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
    <prop key="hibernate.connection.pool_size">${hibernate.connection.pool_size}</prop>
    <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>   
   </props>
  </property>
 </bean>

 <tx:annotation-driven transaction-manager="txManager" />
  
 <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

</beans>

// Log4j.properties
log4j.rootLogger=DEBUG,A1

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c %x - %m%n

// Dao
//AbstractDAO.java
import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public abstract class AbstractDAO <T, ID extends Serializable> implements GenericDAO <T,ID> {
   
    protected HibernateTemplate hibernateTemplate;
    private  Class<T> entityClass;
   
    public AbstractDAO(Class<T> c){entityClass =c;}
   
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate){
        this.hibernateTemplate = hibernateTemplate;
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        hibernateTemplate = new HibernateTemplate(sessionFactory);
    }
   
    @Transactional(propagation = Propagation.SUPPORTS)
    public void save(T entity) {
        hibernateTemplate.saveOrUpdate(entity);
    }
   
    @Transactional(propagation = Propagation.SUPPORTS)
    public void delete (T entity){
        hibernateTemplate.delete(entity);
    }
   
    @Transactional(propagation = Propagation.SUPPORTS)
    public T findByPrimaryKey (ID id){
        return hibernateTemplate.load(entityClass, id);
    }
   
    @SuppressWarnings("unchecked")
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly=true)
    public List<T> load(final Order order, final Criterion... criterion) {
        return (List<T>) hibernateTemplate.execute(new HibernateCallback<Object> () {
            public Object doInHibernate(Session session) {
               
                Criteria criteria = session.createCriteria(entityClass);
               
                if (criterion != null){
           
                    for (Criterion crit : criterion){
                        criteria.add(crit);
                    }
                }
               
                if (order != null){
               
                    criteria.addOrder(order);
                }
               
                return criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
            }
        });
    }
   
    @SuppressWarnings("unchecked")
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly=true)
    public List<T> loadAll() {
        return (List<T>) hibernateTemplate.execute(new HibernateCallback<Object> () {
            public Object doInHibernate(Session session) {
               
                Criteria criteria = session.createCriteria(entityClass);
               
                return criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
            }
        });
    }
   
    @SuppressWarnings("unchecked")
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly=true)   
    public List<T> findByNamedQueryAndNamedParam(String queryName,List paramList, Boolean isEntityClass){
        Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
        if(isEntityClass == true){       
           
            Query query =  session.createSQLQuery(makeSPCall(queryName,paramList)).addEntity(entityClass);;
            List<T> list = query.list();
            return list;   
           
        }else{
           
            Query query = session.createSQLQuery(makeSPCall(queryName,paramList));
            query.executeUpdate();
            query = session.createSQLQuery("select "+extractOutParam(paramList));
            query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
            List data = query.list();
           
            /*Query query = session.createSQLQuery("{ call simpleproc(@a) }");
            query.executeUpdate();
            query = session.createSQLQuery("select @a");
            query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
            List data = query.list();*/

            /* for(Object object : data)
             {
                Map row = (Map)object;
                System.out.print("---------: " + row.get("@a")+"\n");
             }*/
            
             return data;
            //return hibernateTemplate.findByNamedQueryAndNamedParam(queryName, paramNames, values);
        }
           
    }
   
    public void setEntityClass(Class<T> entityClass){
        this.entityClass = entityClass;
    }
   

    private String makeSPCall(String spName,List paramList){
       
        StringBuffer sb = new StringBuffer();
        sb.append("{ call ");
        sb.append(spName);   
        sb.append("( ");
        if(paramList != null){
            for(int i=0;i<paramList.size();i++){
                sb.append(paramList.get(i).toString());
                if(i != paramList.size()-1 ){
                    sb.append(",");
                }
            }
        }
        sb.append(" ) }");
        return sb.toString();
    }

    // out parameters
    private String extractOutParam(List paramList){
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<paramList.size();i++){
            if(paramList.get(i).toString().charAt(0) == '@'){
                sb.append(paramList.get(i).toString());
                sb.append(",");
            }   
        }
        return sb.deleteCharAt(sb.lastIndexOf(",")).toString();
    }
   
   
}

//GenericDao.java
import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;

public interface GenericDAO <T, ID extends Serializable> {

    void save (T entity);
    void delete (T entity);
    T findByPrimaryKey (ID id);
    public List<T> load(final Order order, final Criterion... criterion);
    public List<T> loadAll();
    public void setEntityClass(Class<T> entityClass);
    public List<T> findByNamedQueryAndNamedParam(String queryName, List paramList, Boolean isEntityClass);
}

//DepartmentDAO.java
import com.global.models.Department;

public interface DepartmentDAO extends GenericDAO<Department, Long> {
}

// StaffDAO.java
import com.global.models.Staff;

public interface StaffDAO extends GenericDAO<Staff, Long> {
}

//UserDAO.java
import java.util.List;

import com.global.models.User;

public interface UserDAO extends GenericDAO<User, Long> {

    List<User> findByName(String name);
}

// DAO Implementation
// DepartmentDAOImpl.java
import org.springframework.stereotype.Repository;

import com.global.dao.AbstractDAO;
import com.global.dao.DepartmentDAO;
import com.global.models.Department;

@Repository("departmentDAO")
public class DepartmentDAOImpl extends AbstractDAO <Department, Long> implements DepartmentDAO {
   
    public DepartmentDAOImpl() {
        super(Department.class);
    }
}
//StaffDAOImpl.java
import org.springframework.stereotype.Repository;

import com.global.dao.AbstractDAO;
import com.global.dao.StaffDAO;
import com.global.models.Staff;

@Repository("staffDAO")
public class StaffDAOImpl extends AbstractDAO <Staff, Long> implements StaffDAO {
   
    public StaffDAOImpl() {
        super(Staff.class);
    }
}
//UserDAOImpl.java
import java.util.List;

import org.springframework.stereotype.Repository;

import com.global.dao.AbstractDAO;
import com.global.dao.UserDAO;
import com.global.models.User;

@Repository("userDAO")
public class UserDAOImpl extends AbstractDAO <User, Long> implements UserDAO {
   
    public UserDAOImpl() {
        super(User.class);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<User> findByName(String name) {
        return hibernateTemplate.find("from User where username = ?", name);
    }
}
//Models
//Department.java
import java.io.Serializable;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="Department")
public class Department implements Serializable {

    private static final long serialVersionUID = 536199897485735748L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
   
    private String name;
   
    @OneToMany(mappedBy="department", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Collection<Staff> staff;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public Collection<Staff> getStaff() {
        return staff;
    }

    public void setStaff(Collection<Staff> staff) {
        this.staff = staff;
    }
}
// Staff.java
import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="Staff")
public class Staff implements Serializable {
   
    private static final long serialVersionUID = 6090120733590906021L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
   
    private String firstname;
    private String surname;
   
    @ManyToOne
    private Department department;
   
    public long getId() {
        return id;
    }
   
    public void setId(long id) {
        this.id = id;
    }
   
    public String getFirstname() {
        return firstname;
    }
   
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
   
    public String getSurname() {
        return surname;
    }
   
    public void setSurname(String surname) {
        this.surname = surname;
    }
   
    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Staff [id=" + id + ", firstname=" + firstname + ", surname="
                + surname + ", department=" + department.getId() + "]";
    }
}

//User.java
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.NamedNativeQuery;

//@NamedNativeQuery(name = "callUserStoreProcedure", query = "call t()", resultClass = User.class)
@Entity
@Table(name = "user")
public class User implements Serializable,Comparable {
   
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long user_id;
   
    @Column(name = "username")
    private String username;
   
    @Column(name = "password")
    private String password;
   
   
    public User(){}
   
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
   
    public Long getUser_id() {
        return user_id;
    }
    public void setUser_id(Long user_id) {
        this.user_id = user_id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
   
    @Override
    public int compareTo(Object o) {
        if(!(o instanceof User))
            throw new ClassCastException();
       
        User u = (User) o;
        return password.compareTo(u.getPassword());
    }

    @Override
    public String toString() {
        return "User [user_id=" + user_id + ", username=" + username
                + ", password=" + password + "]";
    }
}

// Services
//GenericService.java
import java.util.List;

import org.hibernate.annotations.NamedNativeQueries;
import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Qualifier;

import com.global.dao.DepartmentDAO;
import com.global.dao.StaffDAO;
import com.global.dao.UserDAO;
import com.global.models.Department;
import com.global.models.Staff;
import com.global.models.User;

@Component("service")
public class GenericService {

    @Autowired
    @Qualifier (value="departmentDAO")
    private DepartmentDAO departmentDao;
   
    @Autowired
    @Qualifier (value="staffDAO")
    private StaffDAO staffDao;
   
    @Autowired
    @Qualifier (value="userDAO")
    private UserDAO userDao;
   
    /**
     * Adds data to DB
     */

    @Transactional
    public void testAddData(){
       
        /*Department dept = new Department();
        dept.setName("IT");
        departmentDao.save(dept);
       
        Staff one = new Staff();
        one.setDepartment(dept);
        one.setFirstname("Ben");
        one.setSurname("Macklin");
        staffDao.save(one);
       
        Staff two = new Staff();
        two.setDepartment(dept);
        two.setFirstname("David");
        two.setSurname("Stonson");
       
        staffDao.save(two);*/
       
        User user = new User("sandeep", "9oo9le");
        userDao.save(user);
    }
   
    /**
     * Loads a member of staff and checks their department
     */

    @Transactional
    public void loadStaff(){
        List<Staff> staffs = staffDao.loadAll();
        Staff loaded = staffDao.findByPrimaryKey(staffs.get(0).getId());
        System.out.println("Accounts "+loaded.getDepartment().getName());
    }
   
    /**
     * Loads a department and checks it has two staff.
     */
   
    @Transactional
    public void loadDepartment(){
        List<Department> depList = departmentDao.loadAll();
       
        Department dep = departmentDao.findByPrimaryKey(depList.get(0).getId());
       
        for (Staff staff: dep.getStaff()){
            System.out.println(staff.getFirstname());
            System.out.println(staff.getSurname());
        }
       
        //assertEquals(2, dep.getStaff().size());
    }
   
    /**
     * Deletes all data after tests have run
     */
   
    @Transactional
    public void reset(){
       
        // Deletes all staff as departments cascadeType set to All.
        List<Department> dep = departmentDao.loadAll();
       
        for (Department department : dep){
        //    departmentDao.delete(department);
            System.out.println(department);
        }
    }
   
    @Transactional
    public List<User> findByName(String name){
        return userDao.findByName(name);
    }
   
    @Transactional   
    public List<User> findByNamedQueryAndNamedParam(String queryName, List paramList, Boolean isEntityClass){
        return userDao.findByNamedQueryAndNamedParam(queryName,paramList,isEntityClass);
    }   
   
    @Transactional   
    public List<Staff> findByNamedQuery(String queryName, List paramList, Boolean isEntityClass){
        return staffDao.findByNamedQueryAndNamedParam(queryName,paramList,isEntityClass);
    }
   
    @Transactional
    public List<User> load(final Order order, final Criterion... criterion){
        return userDao.load(order, criterion);
    }
   
}

// TestGen.java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.global.models.Staff;
import com.global.models.User;
import com.global.services.GenericService;


public class TestGen {
   
    /**
     * @param args
     */
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
         ApplicationContext ctx = new ClassPathXmlApplicationContext("app-context.xml");
         GenericService service = (GenericService)ctx.getBean("service");
        // Add data in DB
        // service.testAddData();

        // not a generic function
        List<User> usrList = service.findByName("sandeep");   
        System.out.println(usrList);
       
        // get list based on criteria
        Criterion criterion = Restrictions.ne("password", "9oo9le");       
        usrList = service.load(Order.desc("user_id"), criterion);
        for (User user : usrList) {
            System.out.println(" Criteria:--------- "+user.toString());
        }
       
        // Call stored procedure for bean
         usrList = (List<User>)service.findByNamedQueryAndNamedParam("t", null, true);
        for (User user : usrList) {
            System.out.println(user.toString());
        }       
       
        @SuppressWarnings("rawtypes")
        List paramList1 = new ArrayList();
        paramList1.add(2);
       
        // Call stored procedure for bean
         List<Staff> usrList1 = (List<Staff>)service.findByNamedQuery("sp2", paramList1, true);
        for (Staff user : usrList1) {
            System.out.println(user.toString());
        }   
       
        @SuppressWarnings("rawtypes")
        List paramList = new ArrayList();
        paramList.add("@a");
        paramList.add("@b");
        paramList.add(2);
       
        // Call Stroed procedure for Out Parameters
        List data = service.findByNamedQueryAndNamedParam("sp1",paramList,false);
               
        for(Object object : data)
        {
           Map row = (Map)object;
           System.out.print("---------: " + row.get("@a")+"\n");
           System.out.print("---------: " + row.get("@b")+"\n");
        }
       
        /*List<User> usrLst = (List<User>)service.findByNamedQueryAndNamedParam("t()", null, null);
        for (User user : usrLst) {
            System.out.println(user.toString());
        }*/
       
        /*@SuppressWarnings("rawtypes")
        List paramList = new ArrayList();
        paramList.add("@a");
        paramList.add("@b");
        paramList.add(2);
       
        TestGen t = new TestGen();
        System.out.println(t.makeSPCall("simpleproc",paramList));
        System.out.println(t.extractOutParam(paramList));*/
       
    }   
}




// jar files
antlr-2.7.6.jar
aopalliance.jar
cglib-nodep-2.2.3.jar
commons-collections-3.1.jar
commons-logging-1.1.1.jar
dom4j-1.6.1.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
hibernate3.jar
javassist-3.12.0.GA.jar
jta-1.1.jar
log4j-1.2.15.jar
mysql-connector-java-5.1.7-bin.jar
org.springframework.aop-3.0.6.RELEASE.jar
org.springframework.asm-3.0.6.RELEASE.jar
org.springframework.beans-3.0.6.RELEASE.jar
org.springframework.context-3.0.6.RELEASE.jar
org.springframework.core-3.0.6.RELEASE.jar
org.springframework.expression-3.0.6.RELEASE.jar
org.springframework.jdbc-3.0.6.RELEASE.jar
org.springframework.orm-3.0.6.RELEASE.jar
org.springframework.transaction-3.0.6.RELEASE.jar
org.springframework.web-3.0.6.RELEASE.jar
slf4j-api-1.6.1.jar
slf4j-nop-1.6.1.jar

No comments:

Post a Comment