Image 1. UML diagram for a generic DAO.
The solution proposed in this article is based on Spring Framework 2.5 and Hibernate 3.2.x. Let's begin with a business model class called Person, its objects (instances) are going to be used and obtained from a database like Oracle, MSSQL, or whatever JDBC compliant database
.
Listing 1. Java Implementation of the business model class.
public class Person {
private Long id;
private String name;
private int age;
public Person() {
}
public void setAge(final int age) {
this.age = age;
}
public void setId(final Long id) {
this.id = id;
}
public void setName(final String name) {
this.name = name;
}
public int getAge() {
return age;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
Listing 2. Hibernate XML Mapping.
<?xml version="1.0" encoding="ISO-8859-1"?> DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping default-access="field" default-cascade="save-update"> <class name="Person" table="Person"> <id column="ID" name="id"> <generator class="native"/> </id>
<property name="name"/> <property name="age"/> </class>
</hibernate-mapping>
Next, we have to define the GenericDao interface where we are going to declare CRUD (Create, Retrieve, Update and Delete) operations. This interface is declared with one Generic Type, that is a template for the Business Model class (for example a Person class).
Listing 3. Generic DAO Interface.
public interface GenericDao {
public void save(T entity);
public void delete(T entity);
public void update(T entity);
public T findById(Serializable id);
public List findAll();
public void deleteById(Serializable id);
public int count();
public List findByExample(T exampleObject);
}
After doing this, you will need to implement this GenericDao interface in order to bring the specific HibernateGenericDAO implementation of the CRUD methods. We extend HibernateDaoSupport because it provides some useful functions such as a exception translation hierarchy, and we declare HibernateGenericDAO as abstract because we are not interested in creating instances of this class (we are interested in creating specific business model classes DAO instances).
public abstract class HibernateGenericDAO extends HibernateDaoSupport implements GenericDao {
protected Class persistentClass = getDomainClass();
protected abstract Class getDomainClass();
public void save(final T entity) {
getHibernateTemplate().save(entity);
}
public void delete(final T entity) {
getHibernateTemplate().delete(entity);
}
public void update(final T entity) {
getHibernateTemplate().update(entity);
}
@SuppressWarnings("unchecked")
public T findById(final Serializable id) {
return (T) getHibernateTemplate().get(this.persistentClass, id);
}
@SuppressWarnings("unchecked")
public List findAll() {
return getHibernateTemplate().find("from " + this.persistentClass.getName() + " o");
}
public void deleteById(final Serializable id) {
T obj = this.findById(id);
getHibernateTemplate().delete(obj);
}
@SuppressWarnings("unchecked")
public int count() {
List list = getHibernateTemplate().find("select count(*) from " + persistentClass.getName() + " o");
Long count = list.get(0);
return count.intValue();
}
@SuppressWarnings("unchecked")
public List findByExample(final T exampleObject) {
return getHibernateTemplate().findByExample(exampleObject);
}
}
After creating the last class the only thing that you will need is to create the specific business model DAO class, in our case PersonDAO. You can realize that it is a very short class, this is the advantage of using the GenericDAO. Every single DAO class for a specifi business model class is going to be as short as this one.
public class PersonDAO extends HibernateGenericDAO implements GenericDao {
@Override
protected Class getDomainClass() {
return Person.class;
}
}
Well, we already have the foundation needed to integrate with spring framework. Spring will be responsible to bind all the dependencies of the beans (glue it all together) and to handle the instances.
Listing 6. Spring framework DAO Configuration<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>classpath*:META-INF/jdbc.propertiesvalue><value>classpath*:META-INF/hibernate.propertiesvalue></list></property><bean><bean id="internal.theDataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.db.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /><property name="maxActive" value="100"/><property name="maxWait" value="1000"/><property name="poolPreparedStatements" value="true"/><property name="defaultAutoCommit" value="true"/></bean><bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" lazy-init="true"><property name="targetDataSource" ref="internal.theDataSource" /></bean><bean id="persistence.sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="true"><property name="dataSource" ref="dataSource" /><property name="mappingLocations"><list><value>classpath*:mappings/*.hbm.xmlvalue></list><property><property name="hibernateProperties"><props><prop key="hibernate.show_sql">${hibernate.show_sql}</prop><prop key="hibernate.dialect">${hibernate.dialect}</prop><prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop><prop key="connection.pool_size">${hibernate.connection.pool_size}</prop><prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop><prop key="hibernate.transaction.flush_before_completion">${hibernate.transaction.flush_before_completion}</prop></props></property></bean><bean id="persistence.personDAO" class="com.hexacta.persistence.dao.PersonDAO" lazy-init="default" autowire="default" dependency-check="default"><property name="sessionFactory"><ref bean="persistence.sessionFactory"/></property></bean></beans>
No comments:
Post a Comment