Currently I am using struts2 Framework for my work's project, and while designing my DAO classes I have a question in my mind to improve on the design patterns.
On my search function, I have 3 kinds of search
My question is, what is the best way to do the DAO method?
in my struts2 method, I'm having
public String execute() {
//assuming these are passed in from JSP
if ("searchByAnId".equals(paramSearch))
{
List<DTO> datalist = this.someDao.implementList(theIdParam);
} else if("searchByAnOtherParam".equals(paramSearch))
{
List<DTO> datalist = this.someDao.implementAnotherList(param1, param2, param3, param4)
// more params
} else
{
List<DTO> datalist = this.someDao.implementListAll();
}
return "success";
}
I was reading on Design Patterns such as Factory methods, Decorator methods, Observer method, but I wasn't sure which one is the most appropriate ones (or anything else without 3rd party plugin) that suits this?
DTO stands for Data Transfer Object, which is a design pattern. It is one of the EPA patterns which we call when we need to use such objects that encapsulate and aggregate data for transfer. A DTO is similar to a data structure, but like a data structure, it doesn't contain any business logic.
DAO is a class that usually has the CRUD operations like save, update, delete. DTO is just an object that holds data. It is JavaBean with instance variables and setter and getters. The DTO is used to expose several values in a bean like fashion.
DTOs are not an anti-pattern. When you're sending some data across the wire (say, to an web page in an Ajax call), you want to be sure that you conserve bandwidth by only sending data that the destination will use.
DTOs or Data Transfer Objects are objects that carry data between processes in order to reduce the number of methods calls.
I usually tend to create a basic dao interface with the definitions of methods common to all my domain entities, such as:
// marker interface
public interface DomainEntity extends Serializable { }
// common dao methods
public interface DAO<T extends DomainEntity> {
public T findById(Long id);
public List<T> findAll();
public T save(T entity);
public boolean update(T entity);
public boolean delete(T entity);
}
And then provide one or more implementations based on my requirements:
// implementation of common dao methods using JPA
public class JpaDAO<T> implements DAO<T> {
private EntityManager em;
public JpaDao(EntityManager em) { this.em = em; }
// Default implementations using JPA...
}
// implementation of common dao methods using JDBC
public class JdbcDAO<T> implements DAO<T> {
private Connection conn;
public JdbcDao(Connection conn) { this.conn = conn; }
// Default implementations using JDBC
}
Now, assuming i have the following person class:
public class Person implements DomainEntity {
private Long id;
private String firstName;
private String lastName;
// getters/setters...
}
I first define a generic PersonDAO interface like so:
public interface PersonDAO implements DAO<Person> {
public List<Person> findByFirstName(String name);
public List<Person> findByLastName(String name);
}
Note that in my specific entity dao interface above, i have included only the extra methods which are specific to my domain entity. Common methods are inherited by the super interface and are parameterised to my domain entity using generics.
Now the last remaining thing is to define different implementations of my entity specific methods, like so:
package mypackage.daos.jpa;
public class PersonDAOImpl extends JpaDAO<Person> implements PersonDAO {
// here i implement only the entity specific dao methods
// defined in the last interface.
}
If i also need to provide an alternative DAO implementation (say based on jdbc instead of JPA), its as easy as creating a second class (preferably in a separate package):
package mypackage.daos.jdbc;
public class PersonDAOImpl extends JdbcDAO<Person> implements PersonDAO {
// again i only implement the entity specific DAO methods since
// defaults have been implemented in the super class...
}
The nice thing about this is that you can switch implementations without the calling code to get affected by that:
// a service class that uses my dao
public class PersonService {
private PersonDAO dao;
public PersonService(PersonDAO dao) { this.dao = dao }
public void doSomethingUseful() {
// use the dao here...
}
}
Typically, the proper dao implementation (jdbc or jpa) would be injected via the constructor during service creation. Of course you can have only one implementation if you like (i.e. jpa).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With