05 3月 2007

Gerneric Sample

善用Generic可以減少相當多的程式碼,基本上一定會用的是在DAO及Service中 BaseDao
public interface BaseDao<T, ID extends Serializable> {
 public T get(ID id);
 
 public void save(T entity);

 public void delete(T entity);

 public List findAll(String[] ascProperties, String[] descProperties);
 
 public List findByExample(T entity, String[] ascProperties, String[] descProperties);
 
 public int countByExample(T entity);
}
HibernateBaseDao
public abstract class HibernatetBaseDao<T, ID extends Serializable> extends
  HibernateDaoSupport {

 private Class domainClass;

 public HibernatetBaseDao() {
  this.domainClass = (Class) ((ParameterizedType) getClass()
    .getGenericSuperclass()).getActualTypeArguments()[0];
 }

 public void delete(T entity) {
  this.getHibernateTemplate().delete(entity);
 }

 @SuppressWarnings("unchecked")
 public List findAll(String[] ascProperties, String[] descProperties) {
  Criteria criteria = this.getSession().createCriteria(this.domainClass);
  this.addOrderToCriteria(criteria, ascProperties, descProperties);
  return criteria.list();
 }

 @SuppressWarnings("unchecked")
 public List findByExample(T entity, String[] ascProperties,
   String[] descProperties) {
  Criteria criteria = this.getSession().createCriteria(this.domainClass);
  Example example = Example.create(entity);
  criteria.add(example);
  this.addOrderToCriteria(criteria, ascProperties, descProperties);
  return criteria.list();
 }

 @SuppressWarnings("unchecked")
 public T get(ID id) {
  return (T) this.getHibernateTemplate().get(this.domainClass, id);
 }

 public void save(T entity) {
  this.getHibernateTemplate().saveOrUpdate(entity);
 }

 public int countByExample(T entity) {
  Criteria criteria = this.getSession().createCriteria(this.domainClass);
  if (null != entity) {
   Example example = Example.create(entity);
   criteria.add(example);
  }
  return ((Integer) criteria.setProjection(Projections.rowCount()).list()
    .iterator().next()).intValue();
 }

 protected void addOrderToCriteria(Criteria criteria,
   String[] ascProperties, String[] descProperties) {
  if (null != ascProperties && 0 < ascProperties.length) {
   for (String property : ascProperties) {
    criteria.addOrder(Order.asc(property));
   }
  }
  if (null != descProperties && 0 < descProperties.length) {
   for (String property : descProperties) {
    criteria.addOrder(Order.desc(property));
   }
  }
 }

 public Class getDomainClass() {
  return domainClass;
 }

 public void setDomainClass(Class domainClass) {
  this.domainClass = domainClass;
 } 
}
BaseManager
public interface BaseManager<T, ID extends Serializable> {
 public T get(ID id);
 public void save(T entity);
 public void delete(T entity);
 public void delete(ID id);
 public List findAll();
 public List findAll(String[] ascProperties, String[] descProperties);
 public List findByExample(T entity);
 public List findByExample(T entity, String[] ascProperties, String[] descProperties);
 public int count();
 public int countByExample(T entity);
}
AbstractBaseManager
public abstract class AbstractBaseManager<T, ID extends Serializable, DAO extends BaseDao<T, ID>> {
 private DAO baseDao;

 public T get(ID id) {
  return baseDao.get(id);
 }

 public void save(T entity) {
  this.baseDao.save(entity);
 }

 public void delete(T entity) {
  this.baseDao.delete(entity);
 }

 public void delete(ID id) {
  this.baseDao.delete(this.get(id));
 }

 public List findAll() {
  return this.findAll(new String[0], new String[0]);
 }

 public List findAll(String[] ascProperties, String[] descProperties) {
  return this.baseDao.findAll(ascProperties, descProperties);
 }

 public List findByExample(T entity) {
  return this.findByExample(entity, new String[0], new String[0]);
 }

 public List findByExample(T entity, String[] ascProperties,
   String[] descProperties) {
  return this.findByExample(entity, ascProperties, descProperties);
 }

 public int count() {
  return this.countByExample(null);
 }

 public int countByExample(T entity) {
  return this.baseDao.countByExample(entity);
 }

 public DAO getBaseDao() {
  return baseDao;
 }

 public void setBaseDao(DAO baseDao) {
  this.baseDao = baseDao;
 }

}
這樣每新增一個Domain Class要做基本的CRUD時,僅需要這樣宣告
public interface MasterDao extends BaseDao<Master, String> {

}
public class MasterDaoImpl extends HibernatetBaseDao<Master, String> implements MasterDao {
 public MasterDaoImpl() {
  super();
 }
}
public interface MasterManager extends BaseManager<Master, String> {

}
public class MasterManagerImpl extends AbstractBaseManager<Master, String, MasterDao> implements
  MasterManager {

}
雖然Service與DAO間Method重覆性太高,但是維持了架構的一致性,雖然不是很滿意,還好目前使用Generic減少了重覆的Code,還算是可以接受.

沒有留言: