锁定老帖子 主题:DAO设计问题
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-08-18
public interface Dao { public abstract List getList(int first,int max) throws Exception; public abstract int getTotal()throws Exception; } public abstract class AbsDao extends HibernateDaoSupport implements Dao { /** *@return List 以集合形式返回符合HQL语句中实体 *@param int max 最大记录数 *@param int first 第一条记录的位置 */ public List getList(final int first,final int max)throws Exception{ return super.getHibernateTemplate().executeFind( new HibernateCallback(){ public Object doInHibernate(Session session) throws HibernateException,SQLException{ try{ return session.createQuery("from "+getTableName()).setFirstResult(first).setMaxResults(max).list(); } catch(Exception e){ throw new HibernateException(e); } } } ); } /** * @return int count 返回HQL查询的记录数 * @param String HQL 统计的HQL语句 */ public int getTotal() throws Exception { return ((Integer)super.getSession().createQuery("select count(*) from "+getTableName()).uniqueResult()).intValue(); } /** * @return String TableName * */ private String getTableName()throws Exception{ return this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".")+1, this.getClass().getName().length()-3); } } ///这个是工具生成的修改了继承,使得为分页作准备。 public class UserinfoDAO extends AbsDao {} //这个是伪泛型的DAO public class DaoImpl extends AbsDao{ /** *@return List 以集合形式返回符合HQL语句中实体 *@param String HQL 要执行的HQL语句 */ public List getList(String HQL)throws Exception{ return super.getHibernateTemplate().find(HQL); } /** *将Object写入数据库 *@param Object o 要保存的对象 */ public void save(Object o)throws Exception{ super.getHibernateTemplate().save(o); } /** *将List(Object)写入数据库 *@param List list(Object) 要保存的对象数组列表 */ public void saveAll(List list)throws Exception{ super.getHibernateTemplate().save(list); } /** *将Object更新 *@param Object o 要跟新的对象 */ public void update(Object o)throws Exception{ super.getHibernateTemplate().update(o); } /** *将Object更新 *@param List list(Object) 要更新的对象数组列表 */ public void updateAll(List list)throws Exception{ super.getHibernateTemplate().update(list); } /**通过SQL语句直接操作数据库 * @param String HQL; */ public void excuteSQL(String HQL) throws Exception { super.getHibernateTemplate().find(HQL); } } 服务层 public interface PageService{ public abstract int getPageSize()throws Exception; public abstract void setPageSize(int pageSize)throws Exception; public abstract int getTotal() throws Exception; public abstract int getPageCount()throws Exception; public abstract List getFirstPage() throws Exception; public abstract List getLastPage() throws Exception; public abstract List getPreviousPage(int currentPage)throws Exception; public abstract List getNextPage(int currentPage)throws Exception; public abstract List getPointPage(int pointPage)throws Exception; } public abstract class AbsPageService implements PageService { /** * @return int 数据库中记录总数 * */ public int getTotal() throws Exception { return getDao().getTotal(); } /** *@return int totalpage 返回分页数 *@param int PageSize 页面的记录数 */ public int getPageCount(int PageSize) throws Exception { return ((getTotal()+PageSize)-1)/PageSize; } /** *@return List 返回指定页面的记录 注意这个方法提供给接口方法 *@param int PointPage 指定的页面 *@param int PageSize 页面的记录数 */ public List getPointPage(int PointPage, int PageSize) throws Exception { if(PointPage>=0&&PointPage<=getPageCount(PageSize)){ return getDao().getList((PointPage-1)*PageSize, PageSize); } else{ return null; } } //以下是接口方法 /** *@return List 返回第一页的记录 **/ public List getFirstPage() throws Exception{ return this.getPointPage(1, PageSize); } /** * @return List 返回最后一页 * */ public List getLastPage() throws Exception{ return this.getPointPage(this.getPageCount(PageSize), PageSize); } /** * @return List 返回前一页的数据 * @param int currentPage 当前页 * */ public List getPreviousPage(int currentPage)throws Exception{ if(currentPage>1&&this.getTotal()>currentPage){ return this.getPointPage(currentPage-1, PageSize); } else{ return null; } } /** * @return List 返回后一页的数据 * @param int currentPage 当前页 * */ public List getNextPage(int currentPage)throws Exception{ if(this.getTotal()>=(currentPage+1)&&(currentPage+1)>0){ return this.getPointPage(currentPage+1, PageSize); } else{ return null; } } /** * @return List 返回当前页的数据 * @param int currentPage 当前页 * */ public List getPointPage(int pointPage)throws Exception{ if(this.getTotal()>=(pointPage)&&(pointPage)>0){ return this.getPointPage(pointPage, PageSize); } else{ return null; } } /** * @return int 总页面数 * */ public int getPageCount() throws Exception { return this.getPageCount(this.getPageSize()); } //注入方法 public int getPageSize() { return PageSize; } public void setPageSize(int pageSize) { PageSize = pageSize; } public Dao getDao() { return dao; } public void setDao(Dao dao) { this.dao = dao; } private int PageSize=10; private Dao dao; } public interface UserinfoService { public abstract void regist(Userinfo ui)throws Exception; public abstract void delete(Integer userinfoid)throws Exception; public abstract void update(Userinfo ui)throws Exception; public abstract Map manager(String pointPage,String operator)throws Exception; public abstract Userinfo find(Integer userinfoid)throws Exception; } public class UserinfoServiceImpl extends AbsPageService implements PageService,UserinfoService{ /** * 用户的删除方法 * @param Integer userinfoid * */ public void delete(Integer userinfoid) throws Exception { ((UserinfoDAO)super.getDao()).delete(((UserinfoDAO)super.getDao()).findById(userinfoid)); } /** * 用户的查找方法 * @return Userinfo * @param Integer userinfoid * */ public Userinfo find(Integer userinfoid) throws Exception { return ((UserinfoDAO)super.getDao()).findById(userinfoid); } /** * 用户的管理方法 * @param String pointPage 当前页 * @param String operator 操作 * */ public Map manager(String pointPage,String operator) throws Exception { this.setAph(new PageHold()); this.getAph().setPs(this); return this.getAph().getUpsPage(pointPage, operator); } /** * 用户的注册方法 * @param Userinfo userinfo * */ public void regist(Userinfo ui) throws Exception { ((UserinfoDAO)super.getDao()).save(ui); } /** * 用户的更新方法 * @param Userinfo userinfo * */ public void update(Userinfo ui) throws Exception { ((UserinfoDAO)super.getDao()).merge(ui); } public AbsPageHold getAph() { return aph; } public void setAph(AbsPageHold aph) { this.aph = aph; } private AbsPageHold aph; } 工具类 public abstract class AbsPageHold { /** * 获取页面的逻辑 * @return Map map * @param String pointPage 当前页 * @param String operator 操作符 * */ public Map getUpsPage(String pointPage,String operator)throws Exception{ Map map=null; try{ if(operator==null){ map=this.getFirstPage(); } else if(operator.equals("first")){ map=this.getFirstPage(); } else if(operator.equals("previous")){ map=this.getPreviousPage(pointPage); } else if(operator.equals("next")){ map=this.getNextPage(pointPage); } else if(operator.equals("jump")){ map=this.getJumpPage(pointPage); } else if(operator.equals("last")){ map=this.getLastPage(); } else{ map=this.getFirstPage(); } } catch(Exception e){ System.out.println(e); } return map; } /** * 分页所需要的帮助类 * */ public Map getMap()throws Exception{ Map map=new HashMap(); map.put("totalCount",new Integer(this.getPs().getTotal())); map.put("totalPage", new Integer(this.getPs().getPageCount())); return map; } //模板方法 public abstract Map getFirstPage()throws Exception; public abstract Map getLastPage()throws Exception; public abstract Map getNextPage(String pointPage)throws Exception; public abstract Map getPreviousPage(String pointPage)throws Exception; public abstract Map getJumpPage(String pointPage)throws Exception; //注入 public PageService getPs() { return ps; } public void setPs(PageService ps) { this.ps = ps; } private PageService ps; } public class PageHold extends AbsPageHold{ public Map getFirstPage() throws Exception { Map map=super.getMap(); map.put("pointPage", "1"); map.put("list", this.getPs().getFirstPage()); return map; } public Map getJumpPage(String pointPage) throws Exception { Map map=super.getMap(); int i=Integer.parseInt(pointPage); List list=this.getPs().getPointPage(i); if(list!=null){ map.put("pointPage", ""+(i)); map.put("list", list); } else{ map.put("pointPage", "1"); map.put("list", this.getPs().getFirstPage()); } return map; } public Map getLastPage() throws Exception { Map map=super.getMap(); map.put("pointPage",((Integer)map.get("totalPage")).toString()); map.put("list",this.getPs().getLastPage()); return map; } public Map getNextPage(String pointPage) throws Exception { Map map=super.getMap(); int i=Integer.parseInt(pointPage); List list=this.getPs().getNextPage(i); if(list!=null){ map.put("pointPage", ""+(i+1)); map.put("list", list); } else{ map.put("pointPage", ""+this.getPs().getPageCount()); map.put("list", this.getPs().getLastPage()); } return map; } public Map getPreviousPage(String pointPage) throws Exception { Map map=super.getMap(); int i=Integer.parseInt(pointPage); List list=this.getPs().getPreviousPage(i); if(list!=null){ map.put("pointPage", ""+(i-1)); map.put("list", list); } else{ map.put("pointPage", "1"); map.put("list",this.getPs().getFirstPage()); } return map; } } 。 现在问题是。我没有办法写一个通用的DAO接口实现CURD。 用伪泛型DAO无法解决注入问题。还有伪泛型DAO怎么处理SQL语句?放在Service层么? 似乎不怎么合适。 还有就是分页的时候PAGEHOLD(分页)和Userinfo相互交叉。 DTO传输应该放在什么地方? 等诸如此类的问题。请指点一下。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-08-18
把 DAO 和 Service 合并更符合 Don't repeat your self. 的原则。
|
|
返回顶楼 | |
发表时间:2008-08-18
citysir 写道 把 DAO 和 Service 合并更符合 Don't repeat your self. 的原则。
能否解释下?不很明白。 |
|
返回顶楼 | |
发表时间:2008-08-19
无非多传一个参数 Table...
|
|
返回顶楼 | |
发表时间:2008-08-19
laiseeme 写道 无非多传一个参数 Table...
真的合适吗?我不很明白你意思,多传Table ? 最重要的 不会每个表都建立一个接口继承DAO 接口 然后再写DAOimpl 最后用模式管理? 还有就是 ServiceImpl里面 根PageHold 交叉。是否意味着 设计不当? |
|
返回顶楼 | |
发表时间:2008-08-19
建议在dao层 不要写死sql 除非是经常用到的sql 例如 from Table ,实现 Don't repeat
servive层才是你要书写sql 的合理地方,因为service是业务层 ,因为业务是不断变化的,而dao仅仅实现一个与数据库交互的一个接口 |
|
返回顶楼 | |
发表时间:2008-08-20
litianyi520 写道 建议在dao层 不要写死sql 除非是经常用到的sql 例如 from Table ,实现 Don't repeat
servive层才是你要书写sql 的合理地方,因为service是业务层 ,因为业务是不断变化的,而dao仅仅实现一个与数据库交互的一个接口 我理解你意思了,可是如果 这么做的话会造成Hibernate入侵Service。不便于解耦, 我曾考虑利用面向接口的思想 把SQL注入到一个DAO的辅助类,该类有个MAP 储存各种SQL。运行时根据注入来调整SQL。不过造成的问题是。一个DAO要有个辅助的类,过于臃肿。SQL数量多的话不便于管理。 如果按照Service层持有SQL的话,只需要一个DAO,矛盾主要集中在SQL语句上。 |
|
返回顶楼 | |
发表时间:2008-08-20
结构如下
public interface Dao { public List getList(String HQL) throws Exception; public List getList(String TableName,int first,int max) throws Exception; public void saveupdate(String HQL) throws Exception; public void save(Object o) throws Exception; public void saveAll(List list) throws Exception; public void update(Object o) throws Exception; public void updateAll(List list) throws Exception; public int getTotal(String HQL)throws Exception; } public abstract class AbsDao implements Dao { /** *@return Object 以Object形式返回符合HQL语句的实体 *@param Class K 要查找的类 *@param Integer id 查找的实体ID */ public Object getObject(Class k,Integer id)throws Exception{ Session session=null; Transaction tx=null; Object o; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); o=session.get(k,id); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } return o; } } public class DaoImpl extends AbsDao implements Dao { /** *@return List 以集合形式返回符合HQL语句中实体 *@param String HQL 要执行的HQL语句 */ public List getList(String HQL)throws Exception{ Session session=null; Transaction tx=null; List list; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); list=session.createQuery(HQL).list(); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } return list; } /** *将Object写入数据库 *@param Object o 要保存的对象 */ public void save(Object o)throws Exception{ Session session=null; Transaction tx=null; List list; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); session.save(o); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } } /** *将List(Object)写入数据库 *@param List list(Object) 要保存的对象数组列表 */ public void saveAll(List list)throws Exception{ Session session=null; Transaction tx=null; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); Iterator it=list.iterator(); while(it.hasNext()){ session.save(it.next()); } session.flush(); session.clear(); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } } /** *将Object更新 *@param Object o 要跟新的对象 */ public void update(Object o)throws Exception{ Session session=null; Transaction tx=null; List list; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); session.update(o); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } } /** *将Object更新 *@param List list(Object) 要更新的对象数组列表 */ public void updateAll(List list)throws Exception{ Session session=null; Transaction tx=null; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); Iterator it=list.iterator(); while(it.hasNext()){ session.update(it.next()); } session.flush(); session.clear(); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } } /** *@return List 以集合形式返回符合HQL语句中实体 *@param String HQL 要执行的HQL语句 *@param int first 第一条记录的位置 */ public List getList(String HQL,int first,int max)throws Exception{ Session session=null; Transaction tx=null; List list; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); list=session.createQuery(HQL).setFirstResult(first).setMaxResults(max).list(); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } return list; } /** *@return int 返回统计符合SQL语句的条数 *@param String HQL 执行的统计语句 */ public int getCount(String HQL)throws Exception{ Session session=null; Transaction tx=null; Integer i=new Integer(0); try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); i=(Integer)session.createQuery(HQL).uniqueResult(); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } return i.intValue(); } /**通过SQL语句直接操作数据库 * @param String HQL; * */ public void saveupdate(String HQL) throws Exception { Session session=null; Transaction tx=null; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); session.createQuery(HQL); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } } /** * @return int count 返回HQL查询的记录数 * @param String HQL 统计的HQL语句 * */ public int getTotal(String HQL)throws Exception{ Session session=null; Transaction tx=null; int i; try{ session=HibernateSessionFactory.getSession(); tx=session.beginTransaction(); i=((Integer)session.createQuery(HQL).uniqueResult()).intValue(); tx.commit(); } catch(Exception ex){ if(tx!=null){ tx.rollback(); tx=null; } throw new Exception("出错了 "+ex); } finally{ try{ if(session!=null){ session.close(); } } catch(Exception e){ System.out.println("出错了e "+e); } } return i; } } 然后利用注入如(Spring)管理SQL? 一个Service持有多个SQL时候SQL混乱~ 似乎感觉还不如封装的方便。 当然多表多条件的情况除外。 我是不是走入误区了? |
|
返回顶楼 | |
发表时间:2008-08-31
提个建议,分页器那段,分页器里多个法在多次调用getTotal()方法,而getTotal()需要读取数据库,建议加个属性保存下total的值,就不用多次读数据库。
|
|
返回顶楼 | |
发表时间:2008-08-31
ll.jpg
|
|
返回顶楼 | |