类似于树形数据结构的留言展示功能的实现
•发布于   •作者 Secret  •504 次浏览  •来自 博客

 一、 树形数据结构

            树形结构是一层次的嵌套结构。 一个树形结构的外层和内层有相似的结构, 所以这种结构多可以递归的表示。经典数据结构中的各种树状图是一种典型的树形结构:一颗树可以简单的表示为根, 左子树, 右子树。 左子树和右子树又有自己的子树。

    

        举一个简单的例子,比如我们想查看一个文件夹里面有多少文件,首先打开这个文件夹,这个文件夹里面可能有多个文件或者文件夹,子文件夹里面可能然后文件文件夹,然后再里面还有文件或者文件夹,直到把所有的文件夹打开,但我们也不知道要打开多少次。 我用项目中用到的一个评论显示功能的说明如何使用递归展示这种数据结构。

        数据库中表字段的设计:
 字段
 ct_id
 o_id
 a_id
 ct_context
ct_date 
 ct_parent_id
 意义
 主键
 评论人ID
 评论的文章的ID
 内容
 时间
 是某一条评论回复的ID
        说明:ct_parent_id为0表示为文章下的评论,其他表示这是评论/回复的回复,该字段表示回复的是哪条评论/回复。

        实体类字段:(构造器以及get/set方法就不贴出来了)

        private Integer ct_id;// 评论ID
	private Integer o_id;// 评论人ID
	private String o_login_name;// 评论人登录名
	private Integer a_id;// 评论文章ID
	private String ct_context;// 评论内容
	private String ct_date;// 评论时间
	private Integer ct_parent_id;// 0表示是评论 其他表示评论的回复
	private Comment childComment;// 表示该评论的回复

        当用户请求查看文章时,在文章底部显示文章的评论。我们需要将文章以及对应的评论信息放入域对象中,通过jsp页面展示出来。关键的service层方法代码如下:
/** * 获得文章的详细信息 */ @Override public Article getDetail(Integer a_id) { // 根据文章ID查询文章 Article article = articleDao.selectByPrimaryKey(a_id); // 浏览次数+1 articleDao.UpdateViewCount(articleDao.selectViewCountByAid(a_id) + 1, a_id); // 查询文章下面的所有评论 List<Comment> comments = commentDao.selectCommentByAid(a_id); // 设置评论数量 article.setCommentCount(comments.size()); // 遍历评论 for (int i = 0; i < comments.size(); i++) { // 获得评论对应的评论回复 getChildComment(comments.get(i)); } article.setCommentList(comments); return article; } /** * 获得评论/回复的回复 * @param comment:评论/回复对象 */ private void getChildComment(Comment comment) { // 查询该评论/回复的回复 Comment childComment = commentDao.selectByParentId(comment.getCt_id()); // 判断该评论/回复是否有回复 if (childComment != null) { // 如果有存进该评论/回复对象中 comment.setChildComment(childComment); // 查询该评论/回复的回复 getChildComment(childComment); } // 如果没有方法结束 }

            这样我们通过getDetail方法就能将所需要的信息放在一个Article对象中,现在要做的是将评论/回复在页面展示出来,很容易我们知道 显示的时候也应该用到递归。但在JSP页面如何实现不写Java代码实现递归呢?我们要用到动态倒入JSP页面。

<div id="postcomments">
    <ol id="comment_list" class="commentlist">		
	<c:if test="${empty ArticleDetail.commentList}">
	    <p>暂时还没有评论哦...</p>
	</c:if>	
        <c:forEach items="${ArticleDetail.commentList}" var="comments">
	    <c:set var="comment" value="${comments}" scope="request"></c:set>
    	    <li class="comment-content">
                <div class="comment-main">
	            <p><a class="address" href="#" rel="nofollow" target="_blank">
                        ${requestScope.comment.o_login_name}</a>
	                <span class="time">${requestScope.comment.ct_date}</span><br>
		        ${requestScope.comment.ct_context}
		     </p>
	        </div>
	        <c:import url="recursive.jsp" charEncoding="UTF-8" /> 
	    </li>
          </c:forEach>
     </ol>
</div>

        这里注意域对象的使用!

        recursive.jsp中的代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
	
    <c:choose>
	<c:when test="${not empty requestScope.comment.childComment}">
	    <c:set value="${requestScope.comment.o_login_name}"  var="parent_login_name" scope="request"></c:set>
	    <c:set  value="${requestScope.comment.childComment}"  var="comment" scope="request"></c:set>
	    <div class="comment-main" style="margin-left: 30px">
                <p>
		    <a class="address" href="#" target="_blank">${requestScope.comment.o_login_name}</a>
		    <span> 回复</span>
		    <a class="address" href="#" target="_blank">${requestScope.parent_login_name}:</a>
		    ${requestScope.comment.ct_context}<br>
		    <span class="time">${requestScope.comment.ct_date}</span>
		</p>
	     </div> 
	    <c:import url="recursive.jsp" charEncoding="UTF-8" /> 
	</c:when>
	<c:otherwise>
	    <form action="/BeeCommunity/comment/doAdd.do" method="post">
	        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
		回复:<input placeholder="回复" name="ct_context" />
		<input type="hidden" name="a_id" value="${ArticleDetail.a_id}" /> 
		<input type="hidden" name="ct_parent_id" value="${requestScope.comment.ct_id}" />
		<input type="submit" value="提交" />
	    </form>
	</c:otherwise>
    </c:choose>

        要注意的是<c:import />标签的使用,也可以使用<jsp:include />,但不能使用include指令<%@include  %>。这里涉及到静态引入和动态引入的区别:

           对于静态包含,<%@include%>,中包含的文件,只是简单的嵌入到主文件中,就是在jsp页面转化成Servlet时才嵌入到主文件中,因为运行的结果是只生成了一个Servlet。

而对于动态包含<jsp:incude>,如果被包含文件是动态的,那么就会生成两个Servlet,也就是被包含文件也要经过jsp引擎编译执行生成一个Servlet,两个Servlet通过request和reponse进行通信。如果被包含的文件是静态的,那么这种情况和<%@include>就很相似,只生成了一个Servlet,但是他们之间没有进行简单的嵌入,而依然是通过request和reponse进行的通信。

            最终效果:



0 回复
回到顶部

©2017 Powered by 三十三行伪代码
皖ICP备17005175号-3