论坛首页 Java企业应用论坛

有了hibernate是否还需要Dao?

浏览 28680 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-23  
tczengjin 写道
抛出异常的爱 写道
管理方便 ,找文件不用debug
仅此而已吗?能稍微详细点吗?另外看过你在javaeye上的回帖,一般回的第一帖精简的很,如果不是我继续看你以后的回帖,恐怕偶目前还理解不了其中的深意 另外我这样dao每个方法打开session进行一次crud操作后关闭,那Session的缓存基本上利用不上了是不???

你又高看我了,
crud这里面cud三个是非常重复的劳动
由session.save(o)
就可以完成的东西不应该写在每个DAO中如果想要写也要写到公共的DAO中以减少代码重复
根据ID找实例的过程也被合谐了(就是sql:seclect XXX from x_table where id = ?)
所以dao里只要放一些非常不一般的查询语句,
并给这些查询方法定义一个好贴切好理解的名子就可以了.
或在注释中把这个东西用在某处的场景写好
到要改时不用从action -> service ->dao 这样找过去
只要简简单单的用全文搜索找到这样的注释
或新加dao 或 修改dao全看对这个方法的引用来决定了.

以上是工作方法中的方便之处.
可以提高工作效率300%左右

PS:看robbin以前的贴子,对查询的优化缓存,不以session开关为终点.好像是cache机制,不过我还没有感受过

tczengjin 写道
xuejianshan 写道
偶也正在学习之中,如果你在看看spring我想你会恍然大悟的。
但是当你学习这方面的东西时,头脑里必须有一个概念---面象接口编程。
具体它为什么这样分,当然会有它的道理,如果你还是不明白的话,那只能说你对它的思想还不够深入,我建议多读代码,和别人讨论一下。
我其实还是懂一点spring的,能够理解面向接口编程。如果说Dao接口可以不让降低我们对数据库访问接口的依赖,Service接口主要可以降低我们对于什么的依赖呢?如果大家略举一例,不胜感激!!!另外我目前写的程序与Hibernate耦合并没有关系,在这样的情况下,大家认为省去Dao是不是一个更好的选择,我一开始就不介意与Hibernate偶和,故均没有写Service接口和Dao接口,但写了Service 和 Dao的一个具体的实现(出于自己一想简化开发省了接口,又惯性使然写了这两个层),请问在这样的情况,大家能否给个建议,Service和Dao的取舍问题,谢谢!

对事务的范围的依赖.
如果你所有的业务都是简单的crud一个表,
那 么service就是摆设
但只要你的service包含多个表的操作
那么就要以service的每个方法作为事务的边界
让spring可以以这个为边界来自动补充事务.

再PS:这些在以前有过很详细的讨论. 还谈到了充血模型的问题.搜一下
0 请登录后投票
   发表时间:2007-12-23  
个人感觉分清楚各个层还是很有必要的
目前公司的项目中:也和楼主的情形差不多,实际上每一层都只是对下层的方法的简单封装
也就是上面的Service.add(User)-->DAO.add(user) -包含-> Hibernate.save(User)
感觉很冗余,不过我也发现了,随着应用规模的扩展,在很多地方出现了重复的代码
对于分层封装来说如果前期没有规划好,会带来不必要的麻烦的
目前公司打算明年整合产品呢,底层开发尽然使用相同的接口来实现(公司的产品现在存在多个,但是他们底层所要操作的数据基本上都是一致的,目前出现了每个产品都需要实现一次它自己的底层操作,实际上那些操作在明年打算完全由一个组来提供一个接口来整合)

个人愚见:
1。根据规模,和将来来判断分层架构,至于方法的冗余实现,那是业务没有划分好导致的,未区分业务方法和持久化方法
2。至于说的数据库使用了ORM依然可以使用JDBC的,Hibernate还是提供了JDBC 原生SQL的阿,还有实在不行还可以获取Connection吖——这是jdbc的开始^-^ 有了Connection就可以做任何事情了
0 请登录后投票
   发表时间:2007-12-23  

[quote="qmy"]先谢谢tczengjin的回复 :)

我再想了想之前用JDBC时的DAO所做的工作,只是封装了SQL语句。
比如DAO有个insert(User)的方法,封装的是insert into t_user values(?,?,?.....)的操作,Service只要调用DAO的这个insert方法就好了。

可是Hibernate提供了save(user)这样的方法,已经封装了SQL语句,也就是说它已经实现了DAO的功能,没必要再写DAO了。如果为了解耦合,只有写一个Hibernate提供的这些api的抽象,然后如果想切换到JDBC,就另外写一个譬如JDBC的DAO实现。

还是我的菜菜的理解……望指点[/quote]
楼上其它人的回复也就是这个意思,另外抛出异常的爱的回复的确是经验之谈,结合以前看了点的spirngside关于EntityDao和HibernateEntityDao HibernateGenericDao这三个类的封装目的完全和抛出异常的爱说的一致,而在springside2 bookstore例子中省略了dao,service继承HibernateEntityDao<T>,如果需要复杂的查询的话,正如楼上所说,此时可以在写Dao继承HibernateEntityDao<T>封装查询操作,然后供service继承。在bookstore例子中没有Dao这一层,可见一般情况下可以省略Dao了。如果你需要使用其它orm解决方案可以可以继承springside 比如IbatisEntityDao<T> 它们均实现了EntityDao接口,这也正是接口的作用。这里把springside关于Hibernate的封装帖出来,供你参考吧,呵呵,今天算开窍了。

java 代码
  1. package org.springside.core.dao;   
  2.   
  3. import java.io.Serializable;   
  4. import java.util.List;   
  5.   
  6. import org.hibernate.Criteria;   
  7. import org.hibernate.criterion.Criterion;   
  8. import org.springside.core.utils.GenericsUtils;   
  9.   
  10. /**  
  11.  * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类.  
  12.  * <p/>  
  13.  * 子类只要在类定义时指定所管理Entity的Class, 即拥有对单个Entity对象的CRUD操作.  
  14.  * <pre>  
  15.  * public class UserManager extends HibernateEntityDao<User> {  
  16.  * }  
  17.  * </pre>  
  18.  *  
  19.  * @author calvin  
  20.  * @see HibernateGenericDao  
  21.  */  
  22. @SuppressWarnings("unchecked")   
  23. public class HibernateEntityDao<T> extends HibernateGenericDao implements EntityDao<T> {   
  24.   
  25.     protected Class<T> entityClass;// DAO所管理的Entity类型.   
  26.   
  27.     /**  
  28.      * 在构造函数中将泛型T.class赋给entityClass.  
  29.      */  
  30.     public HibernateEntityDao() {   
  31.         entityClass = GenericsUtils.getSuperClassGenricType(getClass());   
  32.     }   
  33.   
  34.     /**  
  35.      * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。  
  36.      */  
  37.     protected Class<T> getEntityClass() {   
  38.         return entityClass;   
  39.     }   
  40.   
  41.     /**  
  42.      * 根据ID获取对象.  
  43.      *  
  44.      * @see HibernateGenericDao#getId(Class,Object)  
  45.      */  
  46.     public T get(Serializable id) {   
  47.         return get(getEntityClass(), id);   
  48.     }   
  49.   
  50.     /**  
  51.      * 获取全部对象  
  52.      *  
  53.      * @see HibernateGenericDao#getAll(Class)  
  54.      */  
  55.     public List<T> getAll() {   
  56.         return getAll(getEntityClass());   
  57.     }   
  58.   
  59.     /**  
  60.      * 获取全部对象,带排序参数.  
  61.      *  
  62.      * @see HibernateGenericDao#getAll(Class,String,boolean)  
  63.      */  
  64.     public List<T> getAll(String orderBy, boolean isAsc) {   
  65.         return getAll(getEntityClass(), orderBy, isAsc);   
  66.     }   
  67.   
  68.     /**  
  69.      * 根据ID移除对象.  
  70.      *  
  71.      * @see HibernateGenericDao#removeById(Class,Serializable)  
  72.      */  
  73.     public void removeById(Serializable id) {   
  74.         removeById(getEntityClass(), id);   
  75.     }   
  76.   
  77.     /**  
  78.      * 取得Entity的Criteria.  
  79.      *  
  80.      * @see HibernateGenericDao#createCriteria(Class,Criterion[])  
  81.      */  
  82.     public Criteria createCriteria(Criterion... criterions) {   
  83.         return createCriteria(getEntityClass(), criterions);   
  84.     }   
  85.   
  86.     /**  
  87.      * 取得Entity的Criteria,带排序参数.  
  88.      *  
  89.      * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])  
  90.      */  
  91.     public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions) {   
  92.         return createCriteria(getEntityClass(), orderBy, isAsc, criterions);   
  93.     }   
  94.   
  95.     /**  
  96.      * 根据属性名和属性值查询对象.  
  97.      *  
  98.      * @return 符合条件的对象列表  
  99.      * @see HibernateGenericDao#findBy(Class,String,Object)  
  100.      */  
  101.     public List<T> findBy(String propertyName, Object value) {   
  102.         return findBy(getEntityClass(), propertyName, value);   
  103.     }   
  104.   
  105.     /**  
  106.      * 根据属性名和属性值查询对象,带排序参数.  
  107.      *  
  108.      * @return 符合条件的对象列表  
  109.      * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)  
  110.      */  
  111.     public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc) {   
  112.         return findBy(getEntityClass(), propertyName, value, orderBy, isAsc);   
  113.     }   
  114.   
  115.     /**  
  116.      * 根据属性名和属性值查询单个对象.  
  117.      *  
  118.      * @return 符合条件的唯一对象 or null  
  119.      * @see HibernateGenericDao#findUniqueBy(Class,String,Object)  
  120.      */  
  121.     public T findUniqueBy(String propertyName, Object value) {   
  122.         return findUniqueBy(getEntityClass(), propertyName, value);   
  123.     }   
  124.   
  125.     /**  
  126.      * 判断对象某些属性的值在数据库中唯一.  
  127.      *  
  128.      * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"  
  129.      * @see HibernateGenericDao#isUnique(Class,Object,String)  
  130.      */  
  131.     public boolean isUnique(Object entity, String uniquePropertyNames) {   
  132.         return isUnique(getEntityClass(), entity, uniquePropertyNames);   
  133.     }   
  134.        
  135.     /**  
  136.      * 消除与 Hibernate Session 的关联  
  137.      * @param entity  
  138.      */  
  139.     public void evit(Object entity){   
  140.         getHibernateTemplate().evict(entity);   
  141.     }   
  142. }  

java 代码
  1. package org.springside.core.dao;   
  2.   
  3. import java.io.Serializable;   
  4. import java.util.List;   
  5.   
  6. /**  
  7.  * 针对单个Entity对象的操作定义.不依赖于具体ORM实现方案.  
  8.  *  
  9.  * @author calvin  
  10.  */  
  11. public interface EntityDao<T> {   
  12.   
  13.     T get(Serializable id);   
  14.   
  15.     List<T> getAll();   
  16.   
  17.     void save(Object o);   
  18.   
  19.     void remove(Object o);   
  20.   
  21.     void removeById(Serializable id);   
  22.   
  23.     /**  
  24.      * 获取Entity对象的主键名.  
  25.      */  
  26.     String getIdName(Class clazz);   
  27. }  
java 代码
  1. package org.springside.core.dao;   
  2.   
  3. import java.io.Serializable;   
  4. import java.lang.reflect.InvocationTargetException;   
  5. import java.util.ArrayList;   
  6. import java.util.List;   
  7. import java.util.regex.Matcher;   
  8. import java.util.regex.Pattern;   
  9.   
  10. import org.apache.commons.beanutils.PropertyUtils;   
  11. import org.hibernate.Criteria;   
  12. import org.hibernate.Query;   
  13. import org.hibernate.criterion.CriteriaSpecification;   
  14. import org.hibernate.criterion.Criterion;   
  15. import org.hibernate.criterion.DetachedCriteria;   
  16. import org.hibernate.criterion.Order;   
  17. import org.hibernate.criterion.Projection;   
  18. import org.hibernate.criterion.Projections;   
  19. import org.hibernate.criterion.Restrictions;   
  20. import org.hibernate.impl.CriteriaImpl;   
  21. import org.hibernate.metadata.ClassMetadata;   
  22. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;   
  23. import org.springframework.util.Assert;   
  24. import org.springframework.util.ReflectionUtils;   
  25. import org.springside.core.dao.support.Page;   
  26. import org.springside.core.utils.BeanUtils;   
  27.   
  28. /**  
  29.  * Hibernate Dao的泛型基类.  
  30.  * <p/>  
  31.  * 继承于Spring的<code>HibernateDaoSupport</code>,提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.  
  32.  *  
  33.  * @author calvin  
  34.  * @author tin  
  35.  * @see HibernateDaoSupport  
  36.  * @see HibernateEntityDao  
  37.  */  
  38. @SuppressWarnings("unchecked")   
  39. public class HibernateGenericDao extends HibernateDaoSupport {   
  40.     /**  
  41.      * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.  
  42.      */  
  43.     public <T> T get(Class<T> entityClass, Serializable id) {   
  44.         return (T) getHibernateTemplate().load(entityClass, id);   
  45.     }   
  46.   
  47.     /**  
  48.      * 获取全部对象.  
  49.      */  
  50.     public <T> List<T> getAll(Class<T> entityClass) {   
  51.         return getHibernateTemplate().loadAll(entityClass);   
  52.     }   
  53.   
  54.     /**  
  55.      * 获取全部对象,带排序字段与升降序参数.  
  56.      */  
  57.     public <T> List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) {   
  58.         Assert.hasText(orderBy);   
  59.         if (isAsc)   
  60.             return getHibernateTemplate().findByCriteria(   
  61.                     DetachedCriteria.forClass(entityClass).addOrder(Order.asc(orderBy)));   
  62.         else  
  63.             return getHibernateTemplate().findByCriteria(   
  64.                     DetachedCriteria.forClass(entityClass).addOrder(Order.desc(orderBy)));   
  65.     }   
  66.   
  67.     /**  
  68.      * 保存对象.  
  69.      */  
  70.     public void save(Object o) {   
  71.         getHibernateTemplate().saveOrUpdate(o);   
  72.     }   
  73.   
  74.     /**  
  75.      * 删除对象.  
  76.      */  
  77.     public void remove(Object o) {   
  78.         getHibernateTemplate().delete(o);   
  79.     }   
  80.   
  81.     /**  
  82.      * 根据ID删除对象.  
  83.      */  
  84.     public <T> void removeById(Class<T> entityClass, Serializable id) {   
  85.         remove(get(entityClass, id));   
  86.     }   
  87.   
  88.     public void flush() {   
  89.         getHibernateTemplate().flush();   
  90.     }   
  91.   
  92.     public void clear() {   
  93.         getHibernateTemplate().clear();   
  94.     }   
  95.   
  96.     /**  
  97.      * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.  
  98.      * 留意可以连续设置,如下:  
  99.      * <pre>  
  100.      * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();  
  101.      * </pre>  
  102.      * 调用方式如下:  
  103.      * <pre>  
  104.      *        dao.createQuery(hql)  
  105.      *        dao.createQuery(hql,arg0);  
  106.      *        dao.createQuery(hql,arg0,arg1);  
  107.      *        dao.createQuery(hql,new Object[arg0,arg1,arg2])  
  108.      * </pre>  
  109.      *  
  110.      * @param values 可变参数.  
  111.      */  
  112.     public Query createQuery(String hql, Object... values) {   
  113.         Assert.hasText(hql);   
  114.         Query query = getSession().createQuery(hql);   
  115.         for (int i = 0; i < values.length; i++) {   
  116.             query.setParameter(i, values[i]);   
  117.         }   
  118.         return query;   
  119.     }   
  120.   
  121.     /**  
  122.      * 创建Criteria对象.  
  123.      *  
  124.      * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}  
  125.      */  
  126.     public <T> Criteria createCriteria(Class<T> entityClass, Criterion... criterions) {   
  127.         Criteria criteria = getSession().createCriteria(entityClass);   
  128.         for (Criterion c : criterions) {   
  129.             criteria.add(c);   
  130.         }   
  131.         return criteria;   
  132.     }   
  133.   
  134.     /**  
  135.      * 创建Criteria对象,带排序字段与升降序字段.  
  136.      *  
  137.      * @see #createCriteria(Class,Criterion[])  
  138.      */  
  139.     public <T> Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions) {   
  140.         Assert.hasText(orderBy);   
  141.   
  142.         Criteria criteria = createCriteria(entityClass, criterions);   
  143.   
  144.         if (isAsc)   
  145.             criteria.addOrder(Order.asc(orderBy));   
  146.         else  
  147.             criteria.addOrder(Order.desc(orderBy));   
  148.   
  149.         return criteria;   
  150.     }   
  151.   
  152.     /**  
  153.      * 根据hql查询,直接使用HibernateTemplate的find函数.  
  154.      *  
  155.      * @param values 可变参数,见{@link #createQuery(String,Object...)}  
  156.      */  
  157.     public List find(String hql, Object... values) {   
  158.         Assert.hasText(hql);   
  159.         return getHibernateTemplate().find(hql, values);   
  160.     }   
  161.   
  162.     /**  
  163.      * 根据属性名和属性值查询对象.  
  164.      *  
  165.      * @return 符合条件的对象列表  
  166.      */  
  167.     public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value) {   
  168.         Assert.hasText(propertyName);   
  169.         return createCriteria(entityClass, Restrictions.eq(propertyName, value)).list();   
  170.     }   
  171.   
  172.     /**  
  173.      * 根据属性名和属性值查询对象,带排序参数.  
  174.      */  
  175.     public <T> List<T> findBy(Class<T> entityClass, String propertyName, Object value, String orderBy, boolean isAsc) {   
  176.         Assert.hasText(propertyName);   
  177.         Assert.hasText(orderBy);   
  178.         return createCriteria(entityClass, orderBy, isAsc, Restrictions.eq(propertyName, value)).list();   
  179.     }   
  180.   
  181.     /**  
  182.      * 根据属性名和属性值查询唯一对象.  
  183.      *  
  184.      * @return 符合条件的唯一对象 or null if not found.  
  185.      */  
  186.     public <T> T findUniqueBy(Class<T> entityClass, String propertyName, Object value) {   
  187.         Assert.hasText(propertyName);   
  188.         return (T) createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult();   
  189.     }   
  190.   
  191.     /**  
  192.      * 分页查询函数,使用hql.  
  193.      *  
  194.      * @param pageNo 页号,从1开始.  
  195.      */  
  196.     public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values) {   
  197.         Assert.hasText(hql);   
  198.         Assert.isTrue(pageNo >= 1"pageNo should start from 1");   
  199.         // Count查询   
  200.         String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));   
  201.         List countlist = getHibernateTemplate().find(countQueryString, values);   
  202.         long totalCount = (Long) countlist.get(0);   
  203.   
  204.         if (totalCount < 1)   
  205.             return new Page();   
  206.         // 实际查询返回分页对象   
  207.         int startIndex = Page.getStartOfPage(pageNo, pageSize);   
  208.         Query query = createQuery(hql, values);   
  209.         List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();   
  210.   
  211.         return new Page(startIndex, totalCount, pageSize, list);   
  212.     }   
  213.   
  214.     /**  
  215.      * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.  
  216.      *  
  217.      * @param pageNo 页号,从1开始.  
  218.      * @return 含总记录数和当前页数据的Page对象.  
  219.      */  
  220.     public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {   
  221.         Assert.notNull(criteria);   
  222.         Assert.isTrue(pageNo >= 1"pageNo should start from 1");   
  223.         CriteriaImpl impl = (CriteriaImpl) criteria;   
  224.   
  225.         // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作   
  226.         Projection projection = impl.getProjection();   
  227.         List<CriteriaImpl.OrderEntry> orderEntries;   
  228.         try {   
  229.             orderEntries = (List) BeanUtils.forceGetProperty(impl, "orderEntries");   
  230.             BeanUtils.forceSetProperty(impl, "orderEntries"new ArrayList());   
  231.         } catch (Exception e) {   
  232.             throw new InternalError(" Runtime Exception impossibility throw ");   
  233.         }   
  234.   
  235.         // 执行查询   
  236.         int totalCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();   
  237.   
  238.         // 将之前的Projection和OrderBy条件重新设回去   
  239.         criteria.setProjection(projection);   
  240.         if (projection == null) {   
  241.             criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);   
  242.         }   
  243.   
  244.         try {   
  245.             BeanUtils.forceSetProperty(impl, "orderEntries", orderEntries);   
  246.         } catch (Exception e) {   
  247.             throw new InternalError(" Runtime Exception impossibility throw ");   
  248.         }   
  249.   
  250.         // 返回分页对象   
  251.         if (totalCount < 1)   
  252.             return new Page();   
  253.   
  254.         int startIndex = Page.getStartOfPage(pageNo, pageSize);   
  255.         List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();   
  256.         return new Page(startIndex, totalCount, pageSize, list);   
  257.     }   
  258.   
  259.     /**  
  260.      * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.  
  261.      *  
  262.      * @param pageNo 页号,从1开始.  
  263.      * @return 含总记录数和当前页数据的Page对象.  
  264.      */  
  265.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions) {   
  266.         Criteria criteria = createCriteria(entityClass, criterions);   
  267.         return pagedQuery(criteria, pageNo, pageSize);   
  268.     }   
  269.   
  270.     /**  
  271.      * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.  
  272.      *  
  273.      * @param pageNo 页号,从1开始.  
  274.      * @return 含总记录数和当前页数据的Page对象.  
  275.      */  
  276.     public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc,   
  277.                            Criterion... criterions) {   
  278.         Criteria criteria = createCriteria(entityClass, orderBy, isAsc, criterions);   
  279.         return pagedQuery(criteria, pageNo, pageSize);   
  280.     }   
  281.   
  282.     /**  
  283.      * 判断对象某些属性的值在数据库中是否唯一.  
  284.      *  
  285.  &n
0 请登录后投票
   发表时间:2007-12-23  

没有Dao 一个BookService的实现,即简化开发,又降低了耦合,感觉在简化和降低耦合上所做的平衡做的实在很好。

java 代码
  1. package org.springside.bookstore.service.sysmgr;   
  2.   
  3. import java.util.HashMap;   
  4. import java.util.List;   
  5. import java.util.Map;   
  6.   
  7. import org.apache.commons.lang.StringUtils;   
  8. import org.hibernate.Criteria;   
  9. import org.hibernate.criterion.Restrictions;   
  10. import org.springside.bookstore.components.xfire.server.simple.BookService;   
  11. import org.springside.bookstore.model.Book;   
  12. import org.springside.bookstore.model.Category;   
  13. import org.springside.bookstore.model.Product;   
  14. import org.springside.core.dao.extend.HibernateEntityExtendDao;   
  15. import org.springside.core.dao.support.Page;   
  16. import org.springside.core.exception.BusinessException;   
  17.   
  18. /**  
  19.  * 图书管理业务类.  
  20.  * 继承于HibernateEntityDao,拥有默认的对Book对象的CRUD函数.  
  21.  * 因为Category实体过于简单,没有独立的Manager,因此BookManager同时充当了CategoryDao的角色.  
  22.  *  
  23.  * @author calvin  
  24.  * @see HibernateEntityExtendDao  
  25.  * @see org.springside.core.dao.HibernateGenericDao  
  26.  */  
  27. @SuppressWarnings("unchecked")   
  28. public class BookManager extends HibernateEntityExtendDao<book> implements BookService {   
  29.   
  30.     @Override  
  31.     protected void onValid(Book entity) {   
  32.         if (!isUnique(entity, "name")) {   
  33.             throw new BusinessException("书名" + entity.getName() + "重复");   
  34.         }   
  35.     }   
  36.   
  37.     /**  
  38.      * 分页获取最新图书.  
  39.      */  
  40.     public Page getNewBooks(Integer pageNo, Integer pageSize) {   
  41. 这正是我所需要的。感谢大家的回复。

0 请登录后投票
   发表时间:2007-12-23  
二楼说的很对,我认为:分层的目的就是为了解耦合,为了尽可能的使各个层次之间的耦合度降低,这样当我们的数据层或者业务层或者表示层发生了一些变化, 可以在最大限度的情况下减少其他层面的代码的变动,在我们使用hibernate的时候,hibernate负责为我们进行数据库的连接操作,而我们写DAO,也是在他的数据库操作的基础上再进行一次封装,这样当我们想更换数据库连接操作方式的时候,只需要改DAO及其以下的部分就可以了,而service层,从字面上翻译,就是服务,它是通过DAO给它的服务,给表示层的Action进行服务的,所有的业务操作应该都是写在service层上的,表示层只是需要调用service层给它提供的接口就行了,这样就好比我们使用手机一样,当我们给手机充电的时候,我们不需要对它的内部结构有多了解,只要我们能正确的使用它提供给我们的充电接口就对了,这就是各司其职吧,不管你内部结构怎么变化,只要你提供给我的是那个接口就不影响我的使用了。但是有些时候,根据项目的不同,耦合度的松紧是靠个人掌握的,并不一定是一定要严格做到松耦合,因为有些时候,想做到松耦合,的确很麻烦,会比紧耦合的情况下要多写很多代码,多考虑很多情况,有些时候这是不必要的。
以上仅是个人拙见,有什么不对的地方,请指点
0 请登录后投票
   发表时间:2007-12-24  
除非持久层决定永远用hibernate了
不然去除了dao 对于以后可能发生的修改会引起很大的开销 比如出现了更好的持久层框架需要更换
dao只是一套接口 用来消除service层和持久层的耦合 应该是这么回事~^_^
过于扁平耦合在一起的系统的路走不长
0 请登录后投票
   发表时间:2007-12-24  
pitt_xu 写道
除非持久层决定永远用hibernate了
不然去除了dao 对于以后可能发生的修改会引起很大的开销 比如出现了更好的持久层框架需要更换
dao只是一套接口 用来消除service层和持久层的耦合 应该是这么回事~^_^
过于扁平耦合在一起的系统的路走不长
我曾把hibernate的DAO从ejb中剥出来
用spring来代替.
0 请登录后投票
   发表时间:2007-12-24  
我也是一个初学者。
我做个一个小项目分层:
1,servlet 专放servlet
2, entity 实体包
3 dao 数据库操作
4 util 帮助
我也是一样用的hibernate,但是我脱离了hibernate,是一样的`我只需要去修改dao里面的类。servlet里面基本上是一些输出xml的地方(用的AJAX)
0 请登录后投票
   发表时间:2007-12-25  
就个人而言,我不喜欢DAO。
DAO不是万能药,解耦并不是加个DAO就能解决的问题。
对于大多的简单操作,Hibernate封得已经够完善了,大多时候加个DAO费力不讨好。
如果操作复杂,Service层过于混乱,这时候再抽取出个DAO也没什么不可以。
说到使用DAO解耦,大家最喜欢举的例子就是换实现。以前是说换数据库,现在Hiberate对数据库封得差不多了。于是说法改成将hibernate换成其他的实现,如jdbc等。
但真实项目中有谁有事没事的去换这些东西。
耦是有了才需要解的,如果凭空想出很多不实在的需求,无非是给自己自找麻烦。
0 请登录后投票
   发表时间:2007-12-25  
zbird 写道
就个人而言,我不喜欢DAO。
DAO不是万能药,解耦并不是加个DAO就能解决的问题。
对于大多的简单操作,Hibernate封得已经够完善了,大多时候加个DAO费力不讨好。
如果操作复杂,Service层过于混乱,这时候再抽取出个DAO也没什么不可以。
说到使用DAO解耦,大家最喜欢举的例子就是换实现。以前是说换数据库,现在Hiberate对数据库封得差不多了。于是说法改成将hibernate换成其他的实现,如jdbc等。
但真实项目中有谁有事没事的去换这些东西。
耦是有了才需要解的,如果凭空想出很多不实在的需求,无非是给自己自找麻烦。
我一直在说....
不是为了移植
而是为了管理方便

当然你可以把业务逻辑
与数据库逻辑写在一起
当只有一二个表时
并没什么不好解理
当一个操作关系到:
日志表,
权限表,
业务级联表,
操作记录表,

用人类的智力要从这么多的代码中找到逻辑.....还是差点意思
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics