此文爲轉載: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.
對天乙社區bbscs8實現的詳細分析四
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.