`
sgwood
  • 浏览: 120889 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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

阅读更多

我们仍然将分析处于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

分享到:
评论

相关推荐

    对天乙社区bbscs8实现的详细分析一(附文档下载)

    【标题】"对天乙社区bbscs8实现的详细分析一(附文档下载)" 提供的是关于一个名为“天乙社区”的BBS系统——BBScs8的深入解析。这个系列的分析文档可能涵盖了该社区平台的架构设计、功能模块、代码结构以及可能涉及到...

    [论坛社区]天乙社区修改版_bbscs7.rar

    【描述】:“[论坛社区]天乙社区修改版_bbscs7.rar”的描述简洁,主要强调了这是天乙社区的一个修改版,可能包含了开发者或用户对原版论坛功能、界面或性能的改进。RAR是一种常见的文件压缩格式,通常用于打包多个...

    天乙社区开源代码(strut+strping+hibernate)

    【天乙社区开源代码解析】 天乙社区是一个基于开源技术构建的论坛系统,开发者通过分享其源代码,促进了社区间的交流与学习。该系统的核心框架采用了经典的Java Web开发技术栈,包括Struts、Spring和Hibernate,这...

    天乙社区6.0(含源码)

    而"BBSCS_6_0"可能代表了天乙社区6.0的主要应用文件或数据库文件。这可能是一个可执行文件,用于启动社区平台,或者是包含所有社区数据的数据库文件。对于开发者而言,这个文件可以用于测试和调试,也可以作为构建...

    BBSCS_5_3_1.rar_bbs struts_bbs系统_jsp bbs down_天乙社区_虚拟社区

    【BBSCS_5_3_1.rar_bbs struts_bbs系统_jsp bbs down_天乙社区_虚拟社区】 本项目是基于BBS(Bulletin Board System,电子公告板)理念,采用Struts框架,结合JSP、JavaBean和Servlet技术构建的一款网络虚拟社区...

    [论坛社区]天乙社区修改版_bbscs7.zip

    【标题】"天乙社区修改版_bbscs7.zip"是一个包含Java JSP应用源码的压缩包,专为学生毕业设计学习而准备。这个压缩文件可能是某个开发者或团队为了帮助初学者理解Web应用程序开发,特别是Java Web技术,如JSP(Java...

    天乙社区系统(Struts+Spring+Hibernate)源代码

    5. **BBSCS_6_0_4**:这个文件名可能是天乙社区系统的一个特定版本,其中可能包含了系统的核心模块,如用户管理、帖子发布、评论功能等。开发者可以通过分析源代码,学习SSH框架的实际应用,了解如何将这些技术组件...

    天乙社区6.0(Struts+hibernate+spring)源码

    《天乙社区6.0:Struts、Hibernate与Spring整合深度解析》 在软件开发领域,Struts、Hibernate和Spring是三个非常重要的框架,它们分别在MVC(模型-视图-控制器)架构、对象关系映射(ORM)以及依赖注入(DI)和...

    天乙社区论坛源码,适合初级SSH向中等水平的进阶学习资料--源代码

    本源码是在天乙社区论坛基础上的二次开发,实战型项目的源码,适合初级SSH开发的进阶学习。由于源码比较大且一次上传大小有限制,所以分作三个压缩文件。 bbscs7.rar源代码包 lib1.rar(天乙社区论坛源码,适合初级...

    天乙6.0论坛源码,采用s1sh框架

    《天乙6.0论坛源码解析:基于SSH框架的J2EE社区构建》 天乙6.0论坛是一款基于Java技术栈开发的社区软件,其核心架构采用了经典的Struts1、Spring和Hibernate(SSH)框架,这在当时是相当流行的企业级应用开发组合。...

    bbs-cs 天乙社区 v6.0.1(含源码)

    将bbscs6目录COPY直Tomcat/webapps/下,即Tomcat/webapps/bbscs6 修改Tomcat/webapps/bbscs6/WEB-INF/classes/init.properties文件 主要修改 datasource.url=jdbc:mysql://localhost:3306/bbscs6?useUnicode=true&...

    天乙社区论坛源码,适合初级SSH向中等水平的进阶学习资料--lib1.rar

    本源码是在天乙社区论坛基础上的二次开发,实战型项目的源码,适合初级SSH开发的进阶学习。由于源码比较大且一次上传大小有限制,所以分作三个压缩文件。 bbscs7.rar源代码包(天乙社区论坛源码,适合初级SSH向中等...

    BBSCS_5_3_1.rar_javaBean mysql_oracle

    一套Web式网络社区软件,天乙社区采用JSP+JavaBean构架,后台可以使用MYSQL、Oracle、SQL Server等多种数据库,适用于Linux/UNIX、Windows等多种操作系统,具有界面简洁、功能强大、操作方便等特点

    bbs 论坛程序

    天乙社区论坛可能是一个开源的论坛软件,开发者或团队对其原始代码进行了修改和优化,以满足特定需求或提供额外的功能。二次开发通常包括界面改进、性能优化、增加新特性以及修复已知问题等方面的工作。 文件...

    bbs论坛(SSH)

    从【压缩包子文件的文件名称列表】"天乙社区bbsI(ssh)"来看,这应该是一个名为“天乙社区”的BBS论坛的源代码包,包含了SSH框架的具体实现。用户在使用这个项目时,需要将提供的数据库脚本`bbscs7.sql`导入到MySQL...

Global site tag (gtag.js) - Google Analytics