對天乙社區bbscs8實現的詳細分析八

此文爲轉載:http://www.diybl.com/course/1_web/webjs/2007113/82989.html


接下來是FriendFactory,是有個方法public Friend getInstance(String userId);用於實例化Friend對象用!進入Friend Bean:(注意其實現了可序列化接口implements Serializable與BookMark一樣,其實後面的Note,Subscibe都一樣,bean包下還有Friend0~9個與Friend內容一樣的BEAN,它們主要是爲了拆表準備的,普通版本用不到)
private String id;
private String userID;
private String userName;
private String friendID;
private String friendName;
private String friendComment;//介紹
private int isBlack;//是否加入黑名單
我們看其Friend.hbm.xml:
//length=2000?--->對應表中的`FriendComment` text, //說明
    //`IsBlack` tinyint(1) default ?'

看服務層的方法:
public Friend saveFriend(Friend f) throws BbscsException;
public Friend findFriendByID(String id, String ownId);
public Friend findFriendByName(String fname, String ownId);//根據朋友名、自己的ID取得
public long getFriendNum(String ownId, int isBlack);
public List findFriends(String ownId, int isBlack);
public void removeFriend(Friend f) throws BbscsException;
public void removeFriend(String id, String ownId) throws BbscsException;
public void friendIDsToFile(String ownId);//好友列表ID保存至文件
public List fileToFriendIDs(String ownId);
public List findFriendIds(String ownId, int isBlack);
進入service.imp層,首先是
public class FriendFactoryImp
    implements FriendFactory {
public FriendFactoryImp() {
}
   public synchronized Friend getInstance(String userId) {
    return new Friend();//同步方法!!實例化Friend對象
}
}
而另外的FriendsFactoryImp實現,需要注意的是它也實現了FriendFactory接口:
public synchronized Friend getInstance(String userId) {
    try {
      return (Friend) Class.forName(BBSCSUtil.getClassName("Friend", userId)).newInstance();
    }
/**
public static String getClassName(String className, String userID) {
int num = Math.abs(userID.hashCode());
className = Constant.BEANPERFIX + className + (num % 10);
return className; //Friend0~~~~9
}
public static String getClassName(String className, String userID, int modnum) {
int num = Math.abs(userID.hashCode());
className = Constant.BEANPERFIX + className + (num % modnum);
return className;
}//modnum由setModnum具體得到
*/
    catch (ClassNotFoundException ex) {
      logger.error(ex);
      return null;
    }
    catch (IllegalAccessException ex) {
      logger.error(ex);
      return null;
    }
    catch (InstantiationException ex) {
      logger.error(ex);
      return null;
    }
}
我們看其主要的實現方法:
/**
* 好友列表ID保存至文件
*/
public void friendIDsToFile(String ownId) {
    List l = this.getFriendDAO().findFriends(ownId, 0);
    StringBuffer sb = new StringBuffer();
    Friend f;
    for (int i = 0; i < l.size(); i++) {
      f = (Friend) l.get(i);
      sb.append(f.getFriendID());
      sb.append(",");
    }
    File toFile = new File(this.getUserConfig().getUserFilePath(ownId) + Constant.USER_FRIEND_FILE);
//public static final String USER_FRIEND_FILE = "UserFriendFile.txt";
    try {
FileUtils.writeStringToFile(toFile, sb.toString(), Constant.CHARSET);
} catch (IOException e) {
logger.error(e);
}
}
   
public List fileToFriendIDs(String ownId) {
    List l = new ArrayList();
    File fromFile = new File(this.getUserConfig().getUserFilePath(ownId) + Constant.USER_FRIEND_FILE);
    try {
String fids = FileUtils.readFileToString(fromFile, Constant.CHARSET);
String[] ids = fids.split(",");//分割出來!
if (ids != null) {
    for (int i = 0; i < ids.length; i++) {
      //System.out.println(ids[i]);
      l.add(ids[i]);
    }
}
} catch (IOException e) {
logger.error(e);
}
    return l;
}

@SuppressWarnings("unchecked")
public List findFriendIds(String ownId, int isBlack) {
   List l = this.getFriendDAO().findFriendIds(ownId, isBlack);
   if (l.isEmpty()) {   //填充List
    l.add("0");
   }
   return l;
}

Friend DAO接口中提供如下方法:
public Friend saveFriend(Friend f);
public Friend findFriendByID(String id, String ownId);
public Friend findFriendByName(String fname, String ownId);
public long getFriendNum(String ownId, int isBlack);
public List findFriends(String ownId, int isBlack);
public void removeFriend(Friend f);
public void removeFriend(String id, String ownId);
public List findFriendIds(String ownId, int isBlack);
對於DAO的實現FriendHibernateDAO省略.由於上次忘記分析BookMarksHibernateDAO(拆表用的),這裏我們詳細分析一下FriendsHibernateDAO:(有一個屬性private int modNum,而這個服務類其實也不用了)
public Friend findFriendByID(String id, String ownId) {
StringBuffer sb = new StringBuffer();
sb.append("from Friend");
sb.append(BBSCSUtil.getTableID(ownId, this.getModNum()));
/**
public static int getTableID(String userID, int num) {
int absNum = Math.abs(userID.hashCode());
return (int) (absNum % num); //0~~~9
}
public static int getTableID(long bid, int num) {
return (int) (bid % num);
}

*/
sb.append(" where id = ? and userID = ?");
Object[] o = { id, ownId };
List l = this.getHibernateTemplate().find(sb.toString(), o);
if (l == null || l.isEmpty()) {
   return null;
} else {
   return (Friend) l.get(0);
}

}
其它方法省略之.我們來看看Friend0.java:
public class Friend0 extends Friend implements Serializable {
private static final long serialVersionUID = 8915456842365368615L;
public Friend0() {
super();
}
}
//現在沒這個表了!5555
    

接下來是LoginErrorService:
public LoginError saveLoginError(LoginError loginError) throws BbscsException;
public LoginError findLoginErrorByID(String id); 
public LoginError findLoginErrorByUserID(String userID);
public List findLoginErrorsOutTime(long atime);//取得超過指定時間的LoginError列表
public void removeLoginErrorsOutTime(long atime) throws BbscsException;//刪除超過指定時間的LoginError對象
public LoginError createLoginError(String userID) throws BbscsException;//創建或取得一個已有的LoginError對象
public boolean isCanNotLogin(String userID);//15分鐘之內登錄錯誤次數超過5次,不能登錄
對於bean:
private String id;
private String userID;
private int errorTimes;//登錄時間
private long loginTime;//錯誤次數
其hbm.xml文件中:
//long型的時間

對於服務的實現層,主要還是由DAO去處理的,除了以下兩個方法:
//創建或取得一個已有的LoginError對象
public LoginError createLoginError(String userID) throws BbscsException {
    LoginError loginError = this.getLoginErrorDAO().findLoginErrorByUserID(userID);
    if (loginError == null) {
      loginError = new LoginError();
      loginError.setErrorTimes(1);
      loginError.setLoginTime(System.currentTimeMillis());
      loginError.setUserID(userID);
    }
    else {
      loginError.setErrorTimes(loginError.getErrorTimes() + 1);//加1
      loginError.setLoginTime(System.currentTimeMillis());
    }
    try {
      return this.getLoginErrorDAO().saveLoginError(loginError);//保存
    }
    catch (Exception ex) {
      logger.error(ex);
      throw new BbscsException(ex);
    }
}

/**
   * 15分鐘之內登錄錯誤次數超過5次,不能登錄,也就是15分鐘後進行再進行登錄不會執行本方法爲true值,不過,再次登錄錯誤的話,重新計算機loginError的LoginTime和ErrorTimes值!
      */
public boolean isCanNotLogin(String userID) {
    LoginError loginError = this.getLoginErrorDAO().findLoginErrorByUserID(userID);
    if (loginError != null) {
      if ( (System.currentTimeMillis() - loginError.getLoginTime()) <= 15 * 60000) {
        if (loginError.getErrorTimes() >= 5) {
          return true;
        }
      }
    }
    return false;
}
而DAO提供如下方法:(應該是根據serive imp中的需要而定吧!個人意見)
public LoginError saveLoginError(LoginError loginError);
public LoginError findLoginErrorByID(String id);
public LoginError findLoginErrorByUserID(String userID);
public List findLoginErrorsOutTime(long atime);
public void removeLoginErrorsOutTime(long atime);
public void removeLoginError(LoginError loginError);
DAO實現省略(下同)

下個是NoteService:(先看bean和hbm.xml)
        private String id;
private String fromID;
private String fromUserName;
private String fromNickName;
private String toID;
private String toUserName;
private String toNickName;
private int noteType;//留言類型
private String noteContext;
private Date createTime;//`CreateTime` datetime NOT NULL default ??-00-00 00:00:00', 創建時間
private int isNew;//`IsNew` tinyint(1) default ?', 已讀標誌
private int needRe; //需要回執
private String noteTitle;
        private int isRe;//回覆標誌
private int sysMsg; //系統留言標誌
注意它用實現了Serializable接品,在bean包中也有許多Note0...Note9及Note0.hbm.xml...Note9.hbm.xml ---> 
在service層也有NoteFactory,在serivce imp層NoteFactoryImp和NotesFactoryImp兩種不同的實例化Note對象的同步方法,在DAO實現層也有NotesHibernateDAO用於對相應table(如:bbscs_note_9)的操作,這些與Friend類似,而Subscibe類也差不多如此,因此省略之..
OK,我們繼續看Note.hbm.xml:
//直接text類型,OK!
    //timstamp類型
    
我們繼續看NoteService中的公開方法:
public Note saveNote(Note note) throws BbscsException;
public Note[] createNote(Note inbodNote, Note outboxNote) throws BbscsException;//創建紙條
public Note findNoteByIDFromID(String id, String fromID);
public Note findNoteByIDToID(String id, String toID);
public long getNoteAllNumOutBox(String fromID);//取得發件箱紙條數量
public PageList findNotesOutBox(final String fromId, Pages pages);
public long getNoteAllNumInBox(String toID);//取得收件箱紙條數量
public PageList findNotesInBox(final String toID, Pages pages);
public long getNoteNumInBoxByIsNew(String toID, int isNew);
public List findNotesInIDsOutBox(final String fromId, final List values);//取得發件箱中指定ID的Note列表
public List findNotesInIDsOutBox(final String fromId, final List values);
public List findNotesInIDsInBox(final String toId, final List values);
public void removeNote(Note note) throws BbscsException;
public void removeAllOutBox(String fromID) throws BbscsException;
public void removeAllInBox(String toID) throws BbscsException;
public void removeByIDFromID(String id, String fromID) throws BbscsException;//根據ID和發送者ID刪除Note對象
public void removeByIDToID(String id, String toID) throws BbscsException;
public void removeInIDsFromID(List values, String fromID) throws BbscsException;
public void removeInIDsToID(List values, String toID) throws BbscsException;
我們看實現層,createNote創建紙條,返回一個Note數組:
public Note[] createNote(Note inbodNote, Note outboxNote) throws BbscsException {
    try {
      inbodNote = this.getNoteDAO().saveNote(inbodNote);
      outboxNote = this.getNoteDAO().saveNote(outboxNote);
      Note[] note = {inbodNote, outboxNote};
      return note;
    }
    catch (Exception ex) {
      logger.error(ex);
      throw new BbscsException(ex);
    }
}
由於大部分方法直接給DAO層去完成,我們直接看DAO實現層:(NoteHibernateDAO)
首先是查詢HQL定義
private static final String LOAD_BY_ID_FROMID = "from Note where id = ? and fromID = ?";
private static final String LOAD_BY_ID_TOID = "from Note where id = ? and toID = ?";
private static final String GET_ALL_NUM_OUTBOX =
     "select count(*) from Note where fromID = ? and noteType = ?";
private static final String LOADS_OUTBOX =
      "from Note where fromID = ? and noteType = ? order by createTime desc";
private static final String GET_ALL_NUM_INBOX =
      "select count(*) from Note where toID = ? and noteType = ?";
private static final String LOADS_INBOX =
      "from Note where toID = ? and noteType = ? order by createTime desc";
private static final String GET_NUM_INBOX_BY_ISNEW =
      "select count(*) from Note where toID = ? and noteType = ? and isNew = ?";
private static final String LODAS_INIDS_OUTBOX =
      "from Note where id in (:ids) and fromID = :fromId";
private static final String LODAS_INIDS_INBOX = "from Note where id in (:ids) and toID = :toId";
private static final String REMOVE_ALL_OUTBOX =
      "delete from Note where fromID = ? and noteType = ?";
private static final String REMOVE_ALL_INBOX = "delete from Note where toID = ? and noteType = ?";
private static final String REMOVE_BY_ID_FROMID = "delete from Note where id = ? and fromID = ?";
private static final String REMOVE_BY_ID_TOID = "delete from Note where id = ? and toID = ?";
private static final String REMOVE_INIDS_FROMID =
      "delete from Note where id in (:ids) and fromID = :fromId";
private static final String REMOVE_INIDS_TOID =
      "delete from Note where id in (:ids) and toID = :toId";
下面是取得發件箱紙條數量的方法:
public long getNoteAllNumOutBox(String fromID) {
    Object[] o = {fromID, new Integer(0)}; //noteType=0
    List l = this.getHibernateTemplate().find(GET_ALL_NUM_OUTBOX, o);
    if (l == null || l.isEmpty()) {
      return 0;
    }
    else {
      return ( (Long) l.get(0)).longValue();
    }
}
取得發件箱Note分頁列表:
public List findNotesOutBox(final String fromId, final int firstResult, final int maxResults) {
    return getHibernateTemplate().executeFind(new HibernateCallback() {
      public Object doInHibernate(Session s) throws HibernateException, SQLException {
        Query query = s.createQuery(LOADS_OUTBOX);
        query.setString(0, fromId);
        query.setInteger(1, 0);
        query.setFirstResult(firstResult);
        query.setMaxResults(maxResults);

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

我們看PermissionService,先進入BEAN(權限信息),它有五個屬性:
private Long id;// default ?'
private String permissionName; //權限名稱 default ''
private String resource;//權限資源(URI)default NULL
private String action;//動作,Action default NULL
private int typeID;//權限類型,default `0`
這裏我發現在這個系統的數據庫表設計中它儘量的提供了default值!!!(不過也可能是導出時工具生成的)
 //自動增加鍵!
    
這次我們來看看數據庫表Permission,發現它是一個基本固定不變的定義表,注意: 
權限類型有4種,普通權限(0) 特殊權限(1) 版區普通權限(2) 版區特殊權限(3),這裏都爲0 
122 XXXX(PermissionName)     /amdinUOTimeSet *                       0
209 XXXX(由於我本地亂碼)     /userFace        index,uppage,up,delme   0
OK!看方法:
public Permission savePermission(Permission permission) throws BbscsException;
public Permission updatePermission(Permission permission) throws BbscsException;
public Permission findPermissionByID(long id);
public List findPermissionsAll();
public List findPermissionsByTypeID(int typeID);
public List findPermissionnIDs(List ids);
PermissionServiceImp實現之,首先引入了userPermissionCache,以便在保存和更新後清理緩存數據!
我們直接進入PermissionHibernateDAO:
private static final String LOADS_ALL = "from Permission order by id";
private static final String LOADS_BY_TYPEID = "from Permission where typeID = ? order by id";
private static final String LOADS_IN_IDS = "from Permission where id in (:ids)";
我們只看一個方法:
public List findPermissionnIDs(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 list = query.list();
        return list;
      }
    });
}
發佈了76 篇原創文章 · 獲贊 4 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章