新闻发布系统设计思路(Dao与service)

        接上篇的新闻发布系统设计思路(域模型)之后,我把相关dao的设计和逻辑层的相关设计思路发上来,请大家一起看看还有什么需要改进的地方.
       dao作为域模型的一部分,被与单独的domain分开成单独的数据访问对象,并分别对应域模型的四个数据模型对象.分别为articleDao,categoryDao,articleTopTypeDao,和userDao.其中articleDao和categoryDao为主要的dao,其他的还等待扩展或者只是一个简单的占位点.
#-------------------------------------

articleDao(文章数据访问对象)

java 代码
  1. public interface IArticleDAO {   
  2.     /** 通过一个主键得到一篇文章   
  3.      * @param s 文章主键   
  4.      **/  
  5.     public Article get(Serializable s);   
  6.        
  7.     /** 通过主键来删除一篇文章,传递整个文章对象  
  8.      *@param s 整个文章对象,此对象至少含有主键id值  
  9.      */  
  10.     public void delete(Article s);   
  11.        
  12.     /** 更新这个文章  
  13.      * @param article 需要更新的文章对象,此对象是在原有的文章对象基础之上改变相应值再更新其.  
  14.      * 必须保证此对象是持久化的,如果未持久化,则作相应的插入操作.  
  15.      */  
  16.     public void update(Article article);   
  17.        
  18.     /** 保存这个对象  
  19.      * @param article 要保存的文章对象,此对象要求是未持久化的,即id值是未被赋值的,反之如果数据  
  20.      * 库中有此对象,则作相应的更新操作.  
  21.      */  
  22.     public void save(Article article);   
  23.        
  24.     /**  
  25.      * 通过文章路径信息和其页面数值来得到一个唯一的article对象  
  26.      */    
  27.     public Article getArticleByPathMarkAndPageCurrentIndex(String pathMark, int pageCurrentIndex);   
  28.        
  29.     /**  
  30.      * 通过文章路径信息得到一篇文章的页面列表,因为文章可能有多页.  
  31.      */  
  32.     public List<Article> getArticleListByPathMark(String pathMark);   
  33.        
  34.     /**   
  35.      * 通过一个动态查询条件查询所有的文章对象  
  36.      */    
  37.     public List<Article> getArticleListByCriteria(DetachedCriteria criteria);   
  38.        
  39.     /**  
  40.      * 通过一个动态查询条件和个分页对象相关的文章对象,此次查询只查询相关分页内的文章对象  
  41.      */    
  42.     public List<Article> getArticleListByCriteria(DetachedCriteria criteria, Page page);   
  43. }   

此接口中都是一些常用的操作,包括文章的查询和上下页的翻页等操作.其中getArticleListByPathMark(String pathMark)操作为得到某一篇文章的所有单页文章,因为如果对某一篇文章进行相应更改(如文章页数的改变等),需要对这一篇文章进行相关数据项的删除与添加.而其它操作,如动态查询,目录下文章查询等操作,都委托给getArticleListByCriteria(criteria)和getArticleListByCriteria(cirteria,page)来完成因为一个查询的条件多,如考虑删除条件,目录条件,置顶条件等.

#--------------------
categoryDao(目录数据访问对象)

java 代码
  1. public interface ICategoryDAO {   
  2.        
  3.     /** 通过主键来得到类别对象 **/  
  4.     public Category get(Serializable s);   
  5.        
  6.     /** 删除类别对象 **/  
  7.     public void delete(Category s);   
  8.        
  9.     /** 更新类别对象 **/  
  10.     public void update(Category category);   
  11.        
  12.     /** 保存类别对象 **/  
  13.     public void save(Category category);   
  14.        
  15.     /** 得到一个类别的下级类别列表 **/  
  16.     public List<Category> getCategoryListBySuperCategory(Category category);   
  17.        
  18.     /** 判断一个类别是否和其同级别类别有重复的名字 **/  
  19.     public boolean hasCategory(Category category);   
  20. }  

目录操作相对简单些,除了基本操作,增加getCategoryListBySuperCategory(category)操作,由一目录来得到它的子目录(此处category我只传递了category的主键信息,当然在openSessionInView环境中,可由category.getCategoryList()方法来直接得到子目录,不要这要多发送一条上级目录的查询操作).hasCategory(category)方法,用来处理目录的同名问题,在同一目录下,不允许两个同名的目录存在(当然跨目录是可以的).

其它dao都很简单,就不要再细说了.四个数据访问对象都只对基本的数据操作作了定义,相对来说,更说的操作放在逻辑层(servie)来作.service处理的事也不多,也是把相应操作委托给dao来操作,加上一些自己的逻辑操作.相关接口定义如下(整个系统我只设计了一个servie,此service将所有dao操作聚合在一起)

java 代码
  1. public interface IService {   
  2.     /** 保存一页文章,而不是一篇,因为一篇文章可能有多页 **/  
  3.     public void saveArticle(Article article);   
  4.        
  5.     /** 得到一页文章,此方法通过主键来得到一篇文章中的其中一页 **/  
  6.     public Article getArticle(Serializable s);   
  7.        
  8.     /** 通过文章的路径标记和当前页面的页面下标数(第几页)来得到实际的页面文章对象 **/  
  9.     public Article getArticleByPathMarkAndPageCurrentIndex(String pathMark, int pageCurrentIndex);   
  10.        
  11.     /** 通过文章路径来得到一篇文章,一篇文章可能有多页,故返回一个文章列表 **/  
  12.     public List<Article> getArticleListByArticlePathMark(String pathMark);   
  13.        
  14.     /** 更新一篇文章中的一页文章 **/  
  15.     public void updateArticle(Article article);   
  16.        
  17.     /** 为一篇文章添加或者删除置顶标记,一篇文章并不是指一页文章,而是指包含几个页面的一篇文章 **/  
  18.     public void updateArticleByArticleTopType(Article article, ArticleTopType articleTopType);   
  19.        
  20.     /** 为一篇文章添加或者删除审核标记 **/  
  21.     public void updateArticleByAudit(Article article, boolean auditFlag);   
  22.        
  23.     /** 为一个列表文章添加或者删除置顶标记 **/  
  24.     public void updateArticleListByTop(List<Article> articleList, ArticleTopType articleTopType);   
  25.        
  26.     /** 为一个列表文章添加或者删除审核标记 **/  
  27.     public void updateArticleListByAudit(List<Article> articleList, boolean auditFlag);   
  28.        
  29.     /** 删除一篇文章,在实际操作中,这个方法并不使用,因为实际没有从数据库中删除记录的操作 **/  
  30.     public void deleteArticle(Article article);   
  31.        
  32.     /** 第一次删除一篇文章,此操作为文章作删除标记 **/  
  33.     public void deleteFirstArticle(Article article);   
  34.        
  35.     /** 最终删除一篇文章,此操作将使文章最终不可被检索,仅存在于数据库中作为备份 **/  
  36.     public void deleteShiftArticle(Article article);   
  37.        
  38.     /** 保存一个类别 **/  
  39.     public void saveCategory(Category category);   
  40.        
  41.     /** 取得一个类别  **/  
  42.     public Category getCategory(Serializable s);   
  43.        
  44.     /** 更新类别 **/  
  45.     public void updateCategory(Category category);   
  46.        
  47.     /** 删除一个类别 **/  
  48.     public void deleteCategory(Category category);   
  49.        
  50.     /** 保存一个文章置顶对象,并返回这个对象的id值 **/  
  51.     public Serializable saveArticleTopType(ArticleTopType articleTopType);   
  52.        
  53.     /** 根据动态查询条件和分页组件,查询相关的文章列表 **/  
  54.     public List<Article> queryArticleListByCriteria(DetachedCriteria criterion, Page page);   
  55.        
  56.     /** 查询现在时间段内有次的文章置顶对象 **/  
  57.     public List<ArticleTopType> getArticleTopTypeListNowValid();   
  58.        
  59.     /** 根据动态查询条件,查询相关的文章列表,查询满足条件的所有对象 **/  
  60.     public List<Article> queryArticleListByCriteria(DetachedCriteria criteria);   
  61.        
  62.     /** 恢复一篇文章,这是由于先前的删除文章所作操作的逆向操作 **/  
  63.     public void updateArticleByRecover(Article article);   
  64.        
  65.     /** 取得一个用户 **/  
  66.     public User getUser(Serializable s);   
  67.        
  68.     /** 判断是否有一个重复的类别 **/  
  69.     public boolean hasCategory(Category category);   
  70.        
  71.     /** 通过上级类别来得到其下级类别列表 **/  
  72.     public List<Category> getCategoryListBySuperCategory(Category category);   
  73.        
  74.     /** 改变文章的类别 **/  
  75.     public void updateArticleByCategory(Article article, Category category);   
  76.        
  77.     /** 改变一个列表文章的类别,这些文章都是同一个类别 **/  
  78.     public void updateArticleListByCategory(List<Article> articleList, Category category);   
  79. }  

service将各种操作以更形象的方式提供给action层,并在其中封装数据对象的操作过程,避免action与dao的直接交互.

在service和dao中都出现了一个page对象,这个对象用于页面分页使用.将分页操作放在特定的对象中.分页操作主要涉及到三个方面,每页文章数,当前页数,以及总文章数,其他都可以这三个参数来得到.相应分页对象代码如下:

java 代码
  1. public class Page {   
  2.   
  3.     public Page() {   
  4.     }   
  5.        
  6.     /** 当前页数,默认为第一页 **/  
  7.     private int currentPage = 1;   
  8.        
  9.     /** 每页显示的记录数 默认为 20条记录 **/  
  10.     private int pageSize = 20;   
  11.        
  12.     /** 总记录数 **/  
  13.     private int totalCount;   
  14.   
  15.     public int getCurrentPage() {   
  16.         return currentPage;   
  17.     }   
  18.   
  19.     public void setCurrentPage(int currentPage) {   
  20.         if(currentPage <= 0)   
  21.             return;   
  22.         this.currentPage = currentPage;   
  23.     }   
  24.        
  25.     public int getPageSize() {   
  26.         return pageSize;   
  27.     }   
  28.   
  29.     public void setPageSize(int pageSize) {   
  30.         if(pageSize <= 0)   
  31.             return;   
  32.         this.pageSize = pageSize;   
  33.     }   
  34.   
  35.     public int getTotalCount() {   
  36.         return totalCount;   
  37.     }   
  38.   
  39.     public void setTotalCount(int totalCount) {   
  40.         this.totalCount = totalCount;   
  41.     }   
  42.        
  43.     /** 得到起始记录,此记录是当前显示数据的第一条记录的前一条记录,即前一页记录页的最后一条记录  
  44.      * 因为setCurrentPage方法的存在,使得不可能出现计算得出起始记录为负数的情况,此结果返回的  
  45.      * 最小起始记录为 0  
  46.      */  
  47.     public int getStartIndex() {   
  48.         return (this.currentPage - 1) * this.pageSize;   
  49.     }   
  50.        
  51.     /** 得到总的记录页面数,此结果页每页显示的记录数与总记录数之间的关系计算得出 **/  
  52.     public int getTotalPage() {   
  53.         int i = this.totalCount / this.pageSize;   
  54.         int j = this.totalCount % this.pageSize;   
  55.         return i + (j == 0 ? 0 : 1);   
  56.     }   
  57.        
  58.     /** 是否有上一页 **/  
  59.     public boolean hasPreviousPage() {   
  60.         return this.currentPage > 1;   
  61.     }   
  62.        
  63.     /** 是否有下一页 **/  
  64.     public boolean hasNexPage() {   
  65.         return this.currentPage < this.getTotalCount();   
  66.     }   
  67.   
  68. }  

相应操作都是很简单,我也是简单地进行了些操作.由于需求的简单, 使得相应的代码都不是太长,当然逻辑操作也不是太多.在很多的小型系统的开发场合,常常把service这层去掉,而直接以dao层跟action的直接交互.这也未必不是一种方式.(这里我也有想把service层去掉,因为工作确实不多).

dao层代码和service代码放在附件中,请有意思地交流一下.看有什么可以补充的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值