对天乙社区bbscs8实现的详细分析四

此文为转载:http://www.diybl.com/course/1_web/webjs/2007113/82989.html


接下来,看下BookMarkFactory接口,是个工厂接口.它只有一个一个公有方法, public BookMark getInstance(String userId);其实现为BookMarkFactoryImp,它产生一个BookMark bean,不过是同步的! public synchronized BookMark getInstance(String userId) {
    return new BookMark();//返回的是com.laoer.bbscs.bean.BookMark
}
另有一个实现:BookMarksFactoryImp:(有个私有属性:int modNum及其get/set方法)
public synchronized BookMark getInstance(String userId) {
    try {
      return (BookMark) Class.forName(BBSCSUtil.getClassName("BookMark", userId, this.getModNum())).
          newInstance();
    }
    catch (ClassNotFoundException ex) {
      logger.error(ex);
      return null;
    }
    catch (IllegalAccessException ex) {
      logger.error(ex);
      return null;
    }
    catch (InstantiationException ex) {
      logger.error(ex);
      return null;
    }

}
这里用到了com.laoer.bbscs.common包中的工具类:BBSCSUtil.java
public static String getClassName(String className, String userID) {
int num = Math.abs(userID.hashCode());
className = Constant.BEANPERFIX + className + (num % 10);//public static String BEANPERFIX = "com.laoer.bbscs.bean.";
return className;
}

public static String getClassName(String className, String userID, int modnum) {
int num = Math.abs(userID.hashCode());
className = Constant.BEANPERFIX + className + (num % modnum);
return className; //应该返回是就是com.laoer.bbscs.bean.BookMark0~~~9之间的class了
}

public static String getClassName(String className, long bid, int modnum) {
className = Constant.BEANPERFIX + className + (bid % modnum);
return className;
}

而BookMarkService则完全负责这个业务!先看BEAN:
private String id;
private String userID;
private String bookMarkName;
private String url;
private String alt;
private int isShare;
private Date createTime;

 
 

  
  
    
   
   
      
    
    
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   //timestamp类型!

  
  

 
 
看service接口中的方法:
public BookMark findBookMarkByIDUserID(String id, String userID);
public BookMark saveBookMark(BookMark bm) throws BbscsException;
public long getBookMarkNumByUserID(String userID);
public PageList findBookMarks(String userID, Pages pages);
public PageList findBookMarksByUserIDShare(String userID, int isShare, Pages pages);
public void removeBookMark(BookMark bm) throws BbscsException;
public void removeBookMarkByIDUserID(String id, String userID) throws BbscsException;
我们看实现层:先注入BookMarkDAO对象.特别的是:
public PageList findBookMarks(String userID, Pages pages) {
    PageList pl = new PageList();
    if (pages.getTotalNum() == -1) {
      pages.setTotalNum(this.getBookMarkDAO().getBookMarkNumByUserID(userID));
    }
    pages.executeCount();

    List l = this.getBookMarkDAO().findBookMarks(userID, pages.getSpage(), pages.getPerPageNum()); //DAO层方法,Service层没有
    pl.setObjectList(l);
    pl.setPages(pages);
    return pl;
}
和
public PageList findBookMarksByUserIDShare(String userID, int isShare, Pages pages) {
    PageList pl = new PageList();
    if (pages.getTotalNum() == -1) {
      pages.setTotalNum(this.getBookMarkDAO().getBookMarkNumByUserIDShare(userID, isShare));
    }
    pages.executeCount();

    List l = this.getBookMarkDAO().findBookMarksByUserIDShare(userID, isShare, pages.getSpage(),
        pages.getPerPageNum());//DAO层方法,Service层没有
    pl.setObjectList(l);
    pl.setPages(pages);
    return pl;
}
这里用到了2个分页功能的类:它们都在com.laoer.bbscs.service.web包中,一个Page一个PageList;
两个都是javaBEAN,不过可以带少量的业务逻辑处理功能.先看Pages:
int page=1;//页号
long totalNum=-1;//记录总数
int perPageNum=1;//每页显示记录数
int allPage=1;//总页数
int cpage=1;//当前页
int spage=1;//开始记录数
String fileName="";
boolean useUrlRewirte=false;
public Pages(int page, long totalNum, int perPageNum) {
this.page = page;
this.totalNum = totalNum;
this.perPageNum = perPageNum;
this.executeCount();
}

public void executeCount() {
this.allPage = (int) Math.ceil((this.totalNum + this.perPageNum - 1) / this.perPageNum);
int intPage = this.page;
if (intPage > this.allPage) { // pages == 0
   this.cpage = 1;
} else {
   this.cpage = intPage;
}
this.spage = (this.cpage - 1) * this.perPageNum;
}
而PageList包括一个pages和List类型的objectList 及其set/get方法

public PageList() {
}
我们回到findBookMarks,先得到totalNum,再执行executeCount(),设置其值后,用this.getBookMarkDAO().findBookMark(userID,pages.getspage,pages.getPerPageNum())得到后赋给PageList的objectList和page对象.这样,就可以给web层用List去遍历了,当然也要配合page.
我们直接进入DAO接口层:(其实它完全为service层服务,整体上差不多不过有些方法却不一样)
public BookMark saveBookMark(BookMark bm);
public BookMark findBookMarkByIDUserID(String id,String userID);
public long getBookMarkNumByUserID(String userID);
public List findBookMark(final String userID,final int firstResult,final int maxResults);
public long getBookMarkNumByUserIDShare(String userID, int isShare);
public List findBookMarksByUserIDShare(final String userID, final int isShare, final int firstResult,final int maxResults);//final int类型,方法体里不可改变
public void removeBookMark(BookMark bm);
public void removeBookMarkByIDUserID(String id, String userID);
看它的实现BookMarkHibernateDAO.java:(private static final String类型)
private static final String LOAD_BY_ID_USERID = "from BookMark where id = ? and userID = ?";
private static final String GET_NUM_BY_USERID = "select count(*) from BookMark where userID = ?";
private static final String LOADS_BY_USERID =
      "from BookMark where userID = ? order by createTime desc";
private static final String REMOVE_BY_ID_USERID =
      "delete from BookMark where id = ? and userID = ?";
private static final String GET_NUM_BY_USERID_ISSHARE =
      "select count(*) from BookMark where userID = ? and isShare = ?";
private static final String LOADS_BY_USERID_ISSHARE =
      "from BookMark where userID = ? and isShare = ? order by createTime desc";
我们看其中的一些方法(根据UserID取得BookMark数量)
public long getBookMarkNumByUserID(String userID) {
    List l = this.getHibernateTemplate().find(GET_NUM_BY_USERID, userID);
    if (l == null || l.isEmpty()) {
      return 0;
    }
    else {
      return ( (Long) l.get(0)).longValue();
    }
}
另外一个方法:(根据UserID和isShare取得BookMark列表)
public List findBookMarksByUserIDShare(final String userID, final int isShare,
                                         final int firstResult,
                                         final int maxResults) {
    return getHibernateTemplate().executeFind(new HibernateCallback() {
      public Object doInHibernate(Session s) throws HibernateException, SQLException {
        Query query = s.createQuery(LOADS_BY_USERID_ISSHARE);
        query.setString(0, userID);
        query.setInteger(1, isShare);
        query.setFirstResult(firstResult);
        query.setMaxResults(maxResults);

        List list = query.list();
        return list;
      }
    });
}

我们看下CommendService:(推荐)

 
 

  
  
   
   
   

  
  

  
  
   
   
   

  
  

  
  
   
   
   

  
  

  
  
   
   
   

  
  

 
 
先看bean:
private String id;
private long boardID;//版区ID
private String boardName;
private String postID;
private String postMainID;
private String userID;
private String userName;
private long commendBoardID;//推荐顶层版区ID
private int commendTop;//是否推荐到首页
private String title;//帖子标题
private long createTime;//创建时间

 
 

  
  
    
   
   
      
    
    
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   
    
   
   

  
  

 
 
CommendServie接口中有以下主要方法:
public Commend saveCommend(Commend commend) throws BbscsException;
public int getCommendNumByCommendBoardID(long commendBoardID);
public PageList findCommendsByCommendBoardID(long commendBoardID, Pages pages);
public int getCommendNumByCommendTop(int commendTop);
public void removeCommend(long commendBoardID, List ids) throws BbscsException;
public void createCommendTopFile(int num) throws BbscsException;
public List findCommendsByCommendTopCache(int commendTop, int num);
而其实现层大多方法给DAO去实现之.下面为其中的几个方法:
public PageList findCommendsByCommendBoardID(long commendBoardID, Pages pages) {
PageList pl = new PageList();
if (pages.getTotalNum() == -1) {
   pages.setTotalNum(this.getCommendDAO().getCommendNumByCommendBoardID(commendBoardID));//DAO实现
}
pages.executeCount();
List l = this.getCommendDAO().findCommendsByCommendBoardID(commendBoardID, pages.getSpage(),
    pages.getPerPageNum());
pl.setObjectList(l);
pl.setPages(pages);
return pl;
}
下面是从顶层版区删除推荐....
public void removeCommend(long commendBoardID, List ids) throws BbscsException {
List l = this.getCommendDAO().findCommendsInIds(ids);
try {
   for (int i = 0; i < l.size(); i++) {
    Commend c = (Commend) l.get(i);//取出
    Forum f = this.getForumDAO().findForumByID(c.getPostID(), c.getBoardID());
    f.setCommend(0);//修改是否推荐标志
    this.getForumDAO().saveOrUpdateForum(f);
    this.getCommendDAO().removeCommend(c);
   }
   List commendList = this.getCommendDAO().findCommendsByCommendBoardID(commendBoardID, 0, 10);
   this.getCommendFileIO().saveCommendInReadPageFile(commendBoardID, commendList);//写入推荐文件中!!!!
} catch (Exception ex) {
   logger.error(ex);
   throw new BbscsException(ex);
}
}
public void createCommendTopFile(int num) throws BbscsException {
List l = this.getCommendDAO().findCommendsByCommendTop(0, 0, num);
try {
   this.getCommendFileIO().saveCommendInReadPageFile(0, l);
} catch (IOException ex) {
   logger.error(ex);
   throw new BbscsException(ex);
}
}
而findCommendByCommendTopCache为从SysListObjCache中获得10条推荐信息!
public List findCommendsByCommendTopCache(int commendTop, int num) {
List l = (List) this.getSysListObjCache().get(Constant.COMMEND_CACHE_NAME);//public static final String COMMEND_CACHE_NAME = "CommendSceipt";
if (l == null) {
   l = this.getCommendDAO().findCommendsByCommendTop(commendTop, 0, num);
   this.getSysListObjCache().add(Constant.COMMEND_CACHE_NAME, l);
}
return l;
}
我们来分析下commendFileIO:

 
 
由于service实现层用的是fio接口层,实际注入的却是fil.imp里面的东西:
public interface CommendFileIO {
public void saveCommendInReadPageFile(long commendid, List commendList) throws IOException;//只有一个方法
}
看其实现,里面用了BBSCSUtilTextUtils工具类,它其实写了2个文件!!!前一个在贴子显示时用到,后一个可见www.laoer.com斑主推荐部分!
public void saveCommendInReadPageFile(long commendid, List commendList) throws IOException {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < commendList.size(); i++) {
      Commend commend = (Commend) commendList.get(i);
      sb.append("·");
      sb.append("");
      sb.append(TextUtils.htmlEncode(commend.getTitle()));
      sb.append("
"); } File commendFile = new File(BBSCSUtil.getIncludePath() + "Commend_" + commendid + ".html"); FileUtils.writeStringToFile(commendFile, sb.toString(), Constant.CHARSET); commendFile = null; sb = null; sb = new StringBuffer(); //int counter = 0; for (int i = 0; i < commendList.size(); i++) { Commend c = (Commend) commendList.get(i); sb.append(""); sb.append(""); sb.append(""); sb.append(c.getTitle()); sb.append(""); sb.append("["); sb.append(c.getBoardName()); sb.append("]"); sb.append(""); sb.append(""); } commendFile = new File(BBSCSUtil.getIncludePath() + "ForumCover_Commend_" + commendid + ".html"); FileUtils.writeStringToFile(commendFile, sb.toString(), Constant.CHARSET); } BBSCSUtil中的方法:(前面的一些的分析) getUserWebFilePath()返回一个本地的用户资料文件路径,绝对的(加了ROOTPATH) getUserWebPath()相对的... getWebRealPath()返回URL(一级) getUpFilePath和getUpFileWebPath类似与上getUserWebFilePath getIncludePath()返回本地的路径/include/ 对于BBSCSUtil.getActionMappingURLWithoutPrefix("forum?action=index&bid=" + c.getBoardID()),用了工具类封装了真实的网页后缀! public static String getActionMappingURLWithoutPrefix(String action) { //action="forum?action=index&bid=" + c.getBoardID() StringBuffer value = new StringBuffer(); // Use our servlet mapping, if one is specified String servletMapping = Constant.SERVLET_MAPPING;//*.bbscs if (servletMapping != null) { String queryString = null; int question = action.indexOf("?");//6 if (question >= 0) { queryString = action.substring(question);//"action=index&bid="+c.getBoardID() } String actionMapping = getActionMappingNameWithoutPrefix(action);//forum if (servletMapping.startsWith("*.")) { value.append(actionMapping);//forum value.append(servletMapping.substring(1));//forum.bbscs } else if (servletMapping.endsWith("/*")) { value.append(servletMapping.substring(0, servletMapping.length() - 2)); value.append(actionMapping); } else if (servletMapping.equals("/")) { value.append(actionMapping); } if (queryString != null) { value.append(queryString);//value="forum.bbscs?action=index&bid="+c.getBoardID() } } return (value.toString()); } public static String getActionMappingNameWithoutPrefix(String action) { String value = action;action="forum?action=index&bid=" + c.getBoardID() int question = action.indexOf("?");//6 if (question >= 0) { value = value.substring(0, question);//value="forum" } int slash = value.lastIndexOf("/");//slash=0;如果是main/forum.bbscs的话slash=4 int period = value.lastIndexOf(".");//period=0;.....................period=9 if ((period >= 0) && (period > slash)) { value = value.substring(0, period);//value=0....perod main/forum } return (value); //forum } 接下来,我们看CommendDAO,这个接口中提供了如下方法: public Commend saveCommend(Commend commend); public Commend findCommendByID(String id); public Commend findCommendByPostID(String postID); public int getCommendNumByCommendBoardID(long commendBoardID); public List findCommendsByCommendBoardID(long commendBoardID, final int firstResult, final int maxResults); public int getCommendNumByCommendTop(int commendTop); public List findCommendsByCommendTop(int commendTop, final int firstResult, final int maxResults); public List findCommendsInIds(List ids); public void removeCommend(Commend commend); public void removeCommend(String postID); 看实现: private static final String LOADS_IN_IDS = "from Commend where id in (:ids)"; public List findCommendsInIds(final List ids) { return getHibernateTemplate().executeFind(new HibernateCallback() { public Object doInHibernate(Session s) throws HibernateException, SQLException { Query query = s.createQuery(LOADS_IN_IDS); query.setParameterList("ids", ids);//List!!!final List ids List list = query.list(); return list; } }); } ConfigService用于配置服务:(它有两个属性:id,confContext其hbm.xml 有public Config updateConfig(Config config) throws BbscsException; public Config findConfigByID(String id); public List findConfigs(); public void updateAllConfigs(HashMap configs) throws BbscsException; 其实现: public void updateAllConfigs(HashMap configs) throws BbscsException { Iterator it = configs.values().iterator(); try { while (it.hasNext()) { Config config = (Config) it.next(); this.getConfigDAO().updateConfig(config); } } catch (Exception ex) { logger.error(ex); throw new BbscsException(ex); } } 由于比较简单,直接PASS: public List findConfigs() { return this.getHibernateTemplate().find(LOAD_ALL); } 看EliteService,其对应的BEAN有以下属性: private Long id; private long boardID;//版区ID private long parentID; //父ID private List parentIDs;//你级ID列表,用","分开 private String eliteName;//精华目录名称 private String createUser;//创建者 private long eliteTime;//创建时间 private int orders;//序 //自动增长 //自定义类型 进行方法中: public Elite createElite(Elite elite) throws BbscsException; public Elite saveElite(Elite elite) throws BbscsException; public Elite findEliteByID(long id); public List findElitesByPidBid(long pid, long bid); public void removeElite(Elite elite) throws BbscsException; public List findElitesInIds(List ids); 它首先注入了DAO:eliteDAO和forumDAO;需要注意的是: public Elite createElite(Elite elite) throws BbscsException { Elite pElite = this.getEliteDAO().findEliteByID(elite.getParentID()); if (pElite != null) { List pElites = new ArrayList(); pElites.addAll(pElite.getParentIDs()); pElites.add(pElite.getId()); elite.setParentIDs(pElites);//构造一下其ParentIDs } try { return this.getEliteDAO().saveElite(elite); } catch (Exception ex) { logger.error(ex); throw new BbscsException(ex); } } public void removeElite(Elite elite) throws BbscsException { try { List l = this.getForumDAO().findForumsElite(elite.getBoardID(), elite.getBoardID(), elite.getId().longValue()); for (int i = 0; i < l.size(); i++) { Forum forum = (Forum) l.get(i); forum.setEliteID(elite.getParentID());//改变之 this.getForumDAO().saveOrUpdateForum(forum); } this.getEliteDAO().removeElite(elite); } catch (Exception ex) { logger.error(ex); throw new BbscsException(ex); } } 我们直接看DAO: public Elite saveElite(Elite elite); public Elite findEliteByID(long id); public List findElitesByPidBid(long pid, long bid); public void removeElite(Elite elite); public List findElitesInIds(List ids); 对于具体地实现我们PASS.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值