现在的位置: 首页 > 综合 > 正文

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

2018年02月11日 ⁄ 综合 ⁄ 共 23110字 ⁄ 字号 评论关闭

我们仍然将分析处于service包中,首分析下上次没有分析的ForumArchiveService:(它只有一个方法)
public interface ForumArchivesService {
 public void createForumArchives() throws BbscsException;
}
看applicationContext.xml中:
<bean id="forumArchivesServiceTarget"
  class="com.laoer.bbscs.service.imp.ForumArchivesServiceImp">
  <property name="forumHistoryDAO">
   <ref bean="forumHistoryDAO" />
/**
<bean id="forumHistoryDAO"
  class="com.laoer.bbscs.dao.hibernate.ForumHibernateDAO">
  <constructor-arg>
   <value>History</value>
  </constructor-arg>
  <property name="sessionFactory">
   <ref local="sessionFactory" />
  </property>
 </bean>
而以前讲过的forumMain:
<bean id="forumMainDAO"
  class="com.laoer.bbscs.dao.hibernate.ForumHibernateDAO">
  <constructor-arg>
   <value>Main</value>
  </constructor-arg>
  <property name="sessionFactory">
   <ref local="sessionFactory" />
  </property>
 </bean>
对于这个forumHistoryDAO,其实它只不过是一个ForumHibernateDAO的引用而已,只不过加了个History构造参数!
public ForumHibernateDAO(String flag) {
  super();
  this.flag = flag; //flag不是main了,而是History了!!!那后面的
 private String getObjName() {
  return "Forum" + this.flag;//ForumHistory!
 }

 private Class getForumClass() {
  return Constant.FORUM_CLASS_MAP.get(this.flag); //ForumHistory.class!
 }
*/
  </property>
  <property name="forumArchivesDAO">
   <ref bean="forumArchivesDAO" /> /**com.laoer.bbscs.dao.jdbc.ForumArchivesJDBCDAO,其实这个JDBC操作由
this.getJdbcTemplate().update(sql, o);完成的!!!注意需导入org.springframework.jdbc.core.support.JdbcDaoSupport;
public void saveForumArchives(long bid, Forum f) {
  String sql = "insert into bbscs_forumarchives_"
    + (bid % 10)  
    + " (ParentID, MainID, BoardID, BoardName, ReNum, Face, UserID, UserName, NickName, Title, Detail, Sign, ArtSize, Click, PostTime, LastTime, IPAddress, IsNew, Elite, EliteID, Agree, BeAgainst, CanNotDel, CanNotRe, Commend, DelSign, DelUserID, DelUserName, DelTime, DelIP, Amend, DoEliteName, DoEliteTime, HaveAttachFile, AttachFileName, LastPostUserName, LastPostTitle, LastPostNickName, IsTop, IsLock, Auditing, AuditingAttachFile, IsVote, IsHidden, IsHiddenValue, EditType, QuoteText, QuoteEditType, PostType, TitleColor, UserBlog, IndexStatus, EmailInform, MsgInform, VoteID, TagID, TagName, IsGuest, PreviewAttach, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";  //由bid决定写入10个表中的其中一个!!!
  Object[] o = new Object[] { f.getParentID(), f.getMainID(), f.getBoardID(), f.getBoardName(), f.getReNum(),
    f.getFace(), f.getUserID(), f.getUserName(), f.getNickName(), f.getTitle(), f.getDetail(), f.getSign(),
    f.getArtSize(),....};
  this.getJdbcTemplate().update(sql, o);
 }

 private String attachFileName2String(List attachFileName) {  //将List--->String
  String text = "";
  if (attachFileName != null) {
   for (int i = 0; i < attachFileName.size(); i++) {
    String fileName = (String) attachFileName.get(i);
    text = text + fileName + ",";
   }
   if (text.endsWith(",")) {
    text = text.substring(0, (text.length() - 1));
   }
  }
  return text;
 }
*/
  </property>

  <property name="boardService">
   <ref bean="boardService" />
  </property>
  <property name="tempConfiguration">
   <ref bean="tempConfiguration" />
  </property>
  <property name="forumConfig">
   <ref bean="forumConfig" />
  </property>
  <property name="sysConfig">
   <ref bean="sysConfig" />
  </property>
 </bean>
在其实现类ForumArchiveServiceImp中注入了forumHistoryDAO,boardService,tempConfiguration,forumConfig,SysConfig等其它服务和DAO...其中,tempConfiguration是一个freemarker.template下面的Configuration对象.
public void createForumArchives() throws BbscsException {
  for (int y = 12; y >= 3; y--) {
   Calendar cld = Calendar.getInstance();
   cld.set(Calendar.HOUR_OF_DAY, 0);
   cld.set(Calendar.MINUTE, 0);
   cld.set(Calendar.SECOND, 0);
   cld.set(Calendar.MILLISECOND, 0);
   cld.add(Calendar.MONTH, -y);//三个月之前的任意月,注意这个add方法会改变年份,若y为12,则是一年前的时间,若为3,则是(相对现在)三个月前的时间
   logger.info("计算时间点:" + Util.formatDateTime(cld.getTime()));
/**
public static String formatDateTime(Date date) {
  SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  return outFormat.format(date);
 }
*/
   long atime = cld.getTimeInMillis();//long型时间atime
   cld.add(Calendar.MONTH, -1);//一个月之前
   String month = Util.formatDate(cld.getTime(), "yyyy-MM");
   logger.info("存档月份:" + month);//若现在是2007-7,则这里是2007-6

   List blist = this.getBoardService().findBoardsByParentID(0, 1, -1, Constant.FIND_BOARDS_BY_ORDER);//以前讲过,从最顶层找起!useStat=1,hidden=-1,0
//Criteria c.addOrder(Order.asc("orders"));
   for (int i = 0; i < blist.size(); i++) {
    Board b = (Board) blist.get(i);
    if (b.getBoardType() == 3) {
     this.createForumArchivesFile(b, atime, month);
    }
    List bclist = this.getBoardService().findBoardsByParentID(b.getId(), 1, -1,
      Constant.FIND_BOARDS_BY_ORDER);//各大版块的子版!
    for (int j = 0; j < bclist.size(); j++) {
     Board bc = (Board) bclist.get(j);
     if (bc.getBoardType() == 3) {
      this.createForumArchivesFile(bc, atime, month);
     }//我认为这个方法少了对子版的子版的深度保存!!!
    }
   }
  }
 }
@SuppressWarnings("unchecked")
 private void createForumArchivesFile(Board b, long atime, String month) throws BbscsException {
  if (!BBSCSUtil.ArchivesMonthInFile(b.getId(), month)) { //所在月没存过!
/**

 public static List<String> getArchivesMonths(long bid) {
  List<String> l = new ArrayList<String>();
  File archivesMonthsFile = new File(Constant.ROOTPATH + "archives/archivesmonths-" + bid + ".txt");
  String month = "";
  try {
   month = FileUtils.readFileToString(archivesMonthsFile, Constant.CHARSET);
  } catch (IOException e) {
   return l;
  }
  String[] months = month.split(",");
  if (months.length > 0) {
   for (int i = (months.length - 1); i >= 0; i--) {
    if (StringUtils.isNotBlank(months[i])) {
     l.add(months[i]);
    }
   }
  }
  return l;  //archivesMonthsFile-bid.txt中存的是这个bid的存档时间!
 }

 public static boolean ArchivesMonthInFile(long bid, String month) {
  List<String> l = getArchivesMonths(bid);
  for (String m : l) {  //JDK5.0
   if (m.equalsIgnoreCase(month)) {
    return true;
   }
  }
  return false;
 }
*/
   try {
    this.getTempConfiguration().setDirectoryForTemplateLoading(
      new File(Constant.ROOTPATH + Constant.FTL_PATH));//public static String FTL_PATH = "WEB-INF/templates/";
    this.getTempConfiguration().setDefaultEncoding(Constant.CHARSET);
    this.getTempConfiguration().setNumberFormat("0.##########");
    Locale locale = new Locale("zh", "CN");//前者指语言后者是国家
    this.getTempConfiguration().setLocale(locale);
    Template temp = this.getTempConfiguration().getTemplate("archivesPostMain.ftl");//产生一个Template!!!
我们用记事本等工具打开它
/**
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>帖子存档--${boardName}(${month})</title>
<link href="../../../css/archiveslist.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div id="forums">
<table cellpadding="0" cellspacing="0">
  <caption>${month}</caption>
  <tr class="trt">
   <th class="name" scope="col">主题</th>
   <th scope="col">回复</th>
   <th scope="col">作者</th>
   <th scope="col">发帖时间</th>
  </tr>
  <#list mainlist as fm>
  <tr>
    <td class="name1"><a href="${fm["postdir"]}${fm["id"]}.html" target="_blank">${fm["title"]}</a></td>
 <td>[+${fm["renum"]}]</td>
    <td>${fm["username"]}</td>
    <td>${fm["postTime"]}</td>
  </tr>
  </#list>
  <tr class="trp">
    <td colspan="4" class="name">分页:${pagebreak}</td>
  </tr>
</table>
</div>
</body>
</html>
*/
    long total = this.getForumHistoryDAO().getForumNumBeforeDate(b.getId(), atime);//历史帖子数(注: 
历史帖是3个月以前的帖子,系统每天会把3个月以前的帖子写入历史帖。)

    if (total > 0) { //有过时(超过3个月的)帖子时,把month写入
     BBSCSUtil.writeMonthToFile(b.getId(), month);//month是存储时间而已
    }

    int allPage = (int) Math.ceil((total + 40 - 1) / 40);
/**
Math.ceil(x):比x大的最小值。  
  Math.round(x):四舍五入。  
  Math.floor(x):比x小的最大值。  
  Math.round(x)返回long型,其余的返回double   型。
*/
    logger.info(b.getBoardName() + " total:" + total + " allPage:" + allPage);

    for (int i = 1; i <= allPage; i++) {
     int spage = (i - 1) * 40;开始记录数编号
     List l = this.getForumHistoryDAO().findForumsBeforeDate(b.getId(), atime, spage, 40);
/**
public List findForumsBeforeDate(final long bid, final long atime, final int firstResult, final int maxResults) {
  final String sql = "from " + this.getObjName()
    + " where boardID = ? and isNew = 1 and postTime < ? order by postTime desc";
  return getHibernateTemplate().executeFind(new HibernateCallback() {
   public Object doInHibernate(Session s) throws HibernateException, SQLException {
    Query query = s.createQuery(sql);
    query.setLong(0, bid);
    query.setLong(1, atime);
    query.setFirstResult(firstResult);
    query.setMaxResults(maxResults);

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

*/
     List mainlist = new ArrayList();
     for (int j = 0; j < l.size(); j++) {
      Forum f = (Forum) l.get(j); //Forum通用BEAN!
      Map pmap = new HashMap();
      pmap.put("id", f.getMainID());
      pmap.put("title", f.getTitle());
      pmap.put("renum", f.getReNum());
      pmap.put("username", f.getUserName());
      pmap.put("postTime", Util.formatDate6(new Date(f.getPostTime())));
/**
 public static String formatDate6(Date myDate) {
  SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
  String strDate = formatter.format(myDate);
  return strDate;
 }
*/
      pmap.put("postdir", Util.formatDate4(new Date(f.getPostTime())) + "/" + (f.getPostTime() % 100)
        + "/");
/**
public static String formatDate4(Date myDate) {
  SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
  String strDate = formatter.format(myDate);
  return strDate;
 }
*/
      mainlist.add(pmap); //用于历史帖列表显示吧!所以不用内容!

      List fl = this.getForumHistoryDAO().findForumsTopic(b.getId(), f.getId(), 0, 0, -1,
        new OrderObj[] { new OrderObj("postTime", Constant.ORDER_ASC) });//以它为主帖,返回按postTime的回复List
      List topiclist = new ArrayList();
      for (int x = 0; x < fl.size(); x++) {
       Forum tf = (Forum) fl.get(x);
       Map tmap = new HashMap();
       tmap.put("id", tf.getMainID());
       tmap.put("title", tf.getTitle());
       tmap.put("username", tf.getUserName());
       tmap.put("posttime", Util.formatDateTime(new Date(tf.getPostTime())));
       tmap.put("content", this.getForumDetail(tf, b).toString());
/**
private StringBuffer getForumDetail(Forum f, Board board) {
  StringBuffer sb = new StringBuffer();
  if (StringUtils.isNotBlank(f.getQuoteText())) {
   sb.append("<blockquote class="quote1"><strong>");
   sb.append("引用");
   sb.append(":</strong><br />");
   if (f.getQuoteEditType() == 0) {
    sb.append(BBSCSUtil.filterText(f.getQuoteText(), (board.getAllowHTML() == 1),
      (board.getAllowUBB() == 1), true));
   } else {
    sb.append(BBSCSUtil.filterScript(f.getQuoteText()));
   }
   sb.append("</blockquote>");
  }
  if (f.getHaveAttachFile() != 0 && f.getAttachFileName() != null && !f.getAttachFileName().isEmpty()) {
   sb.append(this.getAttachFile(f)); //有附件!!!
  } else {
   sb.append("<div id="upfile");
   sb.append(f.getId());
   sb.append("" class="font5" style="display:none"></div>");
  }

  if (f.getIsVote() == 0) {
   String detail = this.getForumDetail(f);
   if (f.getEditType() == 0) {
    sb.append(BBSCSUtil.filterText(detail, (board.getAllowHTML() == 1), (board.getAllowUBB() == 1), true));
   } else {
    sb.append(BBSCSUtil.filterScript(detail));
   }
  } else {
   if (f.getEditType() == 0) {
    sb.append(BBSCSUtil.filterText(f.getDetail(), (board.getAllowHTML() == 1), (board.getAllowUBB() == 1),
      true));
   } else {
    sb.append(BBSCSUtil.filterScript(f.getDetail()));
   }
  }
  return sb;
 }
对于getAttachFile()方法我们省略分析之,我们看下:
public static String filterText(String sign, boolean useHTML, boolean useUBB, boolean useSmile) {
  if (!useHTML) {
    sign = TextUtils.htmlEncode(sign);
  }
  if (useUBB) {
   sign = getUBB2HTML(sign);
  }
  if (useSmile) {
   sign = replaceSmile(sign);
  }
  sign = sign.replaceAll(" ", "<BR/>");
  sign = filterScript(sign);
  return sign;
 }
public static String getFileTypeIcon(String fileExt) {
  String fileTypeIcon = (String) Constant.ICON_MAP.get(fileExt);
  if (fileTypeIcon == null) {
   fileTypeIcon = "default.icon.gif";
  }
  return fileTypeIcon;
 }
需要注意的是ICON_MAP在Constant中有定义值了!
*/
       topiclist.add(tmap);
       if (x != 0) { //非第一个帖,就是mainID是自己的帖子!
        this.forumArchivesDAO.saveForumArchives(b.getId(), tf);//存档!
        this.getForumHistoryDAO().removeForum(tf);//从历史帖中删除之
       }
      }

      Template temptopic = this.getTempConfiguration().getTemplate("archivesPostTopic.ftl");
/**下面是这个ftl的部分代码:
<body>
<div id="topic">
<#list topiclist as fm>
<div class="postdiv" id="post${fm["id"]}">
  <div class="title" id="title${fm["id"]}">${fm["title"]}</div>
  <div class="author" id="author${fm["id"]}">作者:${fm["username"]} (发表时间:${fm["posttime"]})</div>
  <div class="content" id="content${fm["id"]}">
  ${fm["content"]}
  </div>
</div>
</#list>
<div align="center" class="postdiv">
<script type="text/javascript"><!--
google_ad_client = "pub-9505761087047507";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text";
google_ad_channel = "";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</div>
</body>
</html>
*/

      OutputStream out = new FileOutputStream(BBSCSUtil.getArchivesPostTopicPath(b.getId(), month, f
        .getPostTime())
        + f.getId() + ".html");
/**
 public static String getArchivesPostMainListWebPath(long bid, String month) {
  StringBuffer sb = new StringBuffer();
  sb.append("archives/");
  sb.append(bid);
  sb.append("/");
  sb.append(month);
  sb.append("/");
  return sb.toString();
 }
public static String getArchivesPostTopicPath(long bid, String month, long posttime) {
  StringBuffer sb = new StringBuffer();
  sb.append(Constant.ROOTPATH);
  sb.append(getArchivesPostMainListWebPath(bid, month));
  sb.append(Util.formatDate4(new Date(posttime)));
  sb.append("/");
  sb.append((posttime % 100));
  sb.append("/");
  File ft = new File(sb.toString());
  if (!ft.exists()) {
   ft.mkdirs();
  }
  return sb.toString();
 }
*/
      Writer writer = new OutputStreamWriter(out, Constant.CHARSET);
      Map root = new HashMap();
      root.put("topoctitle", f.getTitle());
      root.put("topiclist", topiclist);

      temptopic.process(root, writer);
      writer.flush();//处理f存档!

      this.forumArchivesDAO.saveForumArchives(b.getId(), f);//保存好f
      this.getForumHistoryDAO().removeForum(f);//从历史帖中删除之
     }
     StringBuffer sb = new StringBuffer();
     for (int x = 1; x <= allPage; x++) {
      sb.append("[<a href="");
      sb.append(x);
      sb.append(".html">");
      if (x == i) {
       sb.append("<strong>");
       sb.append(x);
       sb.append("</strong>");
      } else {
       sb.append(x);
      }
      sb.append("</a>] ");
     }

     OutputStream out = new FileOutputStream(BBSCSUtil.getArchivesPostMainListPath(b.getId(), month) + i
       + ".html"); //i是页码,如果有30页的话,那就是30个文件了!
     Writer writer = new OutputStreamWriter(out, Constant.CHARSET);
     Map root = new HashMap();
     root.put("boardName", b.getBoardName());
     root.put("month", month);
     root.put("mainlist", mainlist);
     root.put("pagebreak", sb.toString());

     temp.process(root, writer);//这些参数与文件中的参数一致!
     writer.flush();
    }

   } catch (Exception e) {
    logger.error(e);
    throw new BbscsException(e);
   }
  }
 }
对于上面的部分可以查看历史帖选项查看效果!

接下来是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:
<hibernate-mapping package="com.laoer.bbscs.bean">
  <class name="Friend" table="bbscs_friend">
    <id name="id" column="ID" type="string" unsaved-value="null">
      <generator class="uuid"/>
    </id>
    <property column="UserID" length="40" name="userID" not-null="true" type="string"/>
    <property column="UserName" length="20" name="userName" not-null="true" type="string"/>
    <property column="FriendID" length="40" name="friendID" not-null="true" type="string"/>
    <property column="FriendName" length="20" name="friendName" not-null="true" type="string"/>
    <property column="FriendComment" length="2000" name="friendComment" type="string"/>//length=2000?--->对应表中的`FriendComment` text, //说明
    <property column="IsBlack" length="1" name="isBlack" type="int"/>//`IsBlack` tinyint(1) default Ɔ'
  </class>
</hibernate-mapping>
看服务层的方法:
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<String> l = new ArrayList<String>();
    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();
 }
}
<hibernate-mapping package="com.laoer.bbscs.bean">
  <class name="Friend0" table="bbscs_friend_0">//现在没这个表了!5555
    <id name="id" column="ID" type="string" unsaved-value="null">
      <generator class="uuid"/>
    </id>
    <property column="UserID" length="40" name="userID" not-null="true" type="string"/>
    <property column="UserName" length="20" name="userName" not-null="true" type="string"/>
    <property column="FriendID" length="40" name="friendID" not-null="true" type="string"/>
    <property column="FriendName" length="20" name="friendName" not-null="true" type="string"/>
    <property column="FriendComment" length="2000" name="friendComment" type="string"/>
    <property column="IsBlack" length="1" name="isBlack" type="int"/>
  </class>
</hibernate-mapping>

接下来是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文件中:
<hibernate-mapping package="com.laoer.bbscs.bean">
  <class name="LoginError" table="bbscs_loginerror">
    <id name="id" column="ID" type="string" unsaved-value="null">
      <generator class="uuid"/>
    </id>
    <property column="UserID" length="40" name="userID" not-null="true" type="string"/>
    <property column="ErrorTimes" length="11" name="errorTimes" not-null="true" type="int"/>
    <property column="LoginTime" length="20" name="loginTime" type="long"/>//long型的时间
  </class>
</hibernate-mapping>
对于服务的实现层,主要还是由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

抱歉!评论已关闭.