SSH实战OA 11:BBS模块

来源:互联网 发布:ubuntu解压缩zip 编辑:程序博客网 时间:2024/06/03 21:30

《SSH实战OA》系列博客的系统管理、权限管理等内容后面再补上吧,先继续第三个模块:网上交流模块。网上交流主要做两个需求:论坛管理和论坛。

BBS的一些基本术语:

  1. 板块:也叫做“版面”、“讨论区”,用于对帖子进行分类
  2. 主题:也叫做“主贴”,表示一个新的话题,可以有很多回帖,属于某个板块。
  3. 回复:也叫做“回帖”、“跟帖”,属于某个主贴。

论坛模块的功能说明:

  1. 浏览
    • 板块列表
    • 显示单个板块(主题列表)
    • 显示单个主题(主题+回帖列表)
  2. 参与
    • 发新帖
    • 回帖
  3. 管理文章
    • 主题
      • 设置类型
      • 移动到其他板块
      • 删除
      • 修改
    • 回复
  4. 板块管理
    • 增删改查
    • 上下移动

板块管理

板块管理
先来看看板块管理的需求,由上图可以看出,板块管理主要的需求有板块的新增、删除,修改,列表,上移,下移这几个需求。那么对应的Action方法如下:

@Controller@Scope("prototype")public class ForumManageAction extends BaseAction<Forum> {    Log log = LogFactory.getLog(this.getClass());    /**     * @return 板块列表     * @throws Exception     */    public String list() throws Exception {        List<Forum> forumList = forumService.selectAll();        ActionContext.getContext().put("forumList", forumList);        return "list";    }    /**     * @return 新增页面     * @throws Exception     */    public String addUI() throws Exception {        return "saveUI";    }    /**     * @return 新增操作     * @throws Exception     */    public String add() throws Exception {        forumService.add(model);        return "toList";    }    /**     * @return 删除操作     * @throws Exception     */    public String delete() throws Exception {        forumService.delete(model.getId());        return "toList";    }    /**     * @return 修改页面     * @throws Exception     */    public String editUI() throws Exception {        Forum forum  = forumService.selectById(model.getId());        ActionContext.getContext().put("forum", forum);        return "saveUI";    }    /**     * @return 修改     * @throws Exception     */    public String edit() throws Exception {        Forum forum = forumService.selectById(model.getId());        if(forum != null) {            forum.setDescription(model.getDescription());            forum.setName(model.getName());            forumService.update(forum);        }        return "toList";    }    /**     * @return 上移     * @throws Exception     */    public String moveUp() throws Exception {        forumService.moveUp(model.getId());        return "toList";    }    /**     * @return 下移     * @throws Exception     */    public String moveDown() throws Exception {        forumService.moveDown(model.getId());        return "toList";    }}

论坛板块ForumAction需要继承基本Action抽象类BaseAction。

public abstract class BaseAction<T> extends ActionSupport implements ModelDriven<T>{    protected T model;    @Autowired    protected DepartmentService departmentService;    @Autowired    protected RoleService roleService;    @Autowired    protected UserService userService;    @Autowired    protected PrivilegeService privilegeService;    @Autowired    protected ForumService forumService;    public BaseAction() {        try {            // 通过反射获取model的真实类型            ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();            Class<T> clazz = (Class<T>) pt.getActualTypeArguments()[0];            // 通过反射创建model的实例            model = clazz.newInstance();        } catch (Exception e) {            throw new RuntimeException(e);        }    }    @Override    public T getModel() {        return model;    }}

在暂未考虑与其他实体关联的提前下,我们的model类可以这样设计:

/** * @date 2017/05/06 * @author shizongger * 论坛板块 */public class Forum {    private Long id; //主键id    private String name; //板块名称    private String description; //板块描述    private int position;  //板块所在位置    //getter/settter}

前几篇文章提到映射的pojo的主键属性id都默认为Long型,forum属性自己的属性有name,description,position。name用来记录板块名称,description是对本板块的描述,而position是记录板块的排序位置,方面上下移动的操作。

Forum.hbm.xml文件如下:

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.shizongger.oa.domain">    <class name="Forum" table="itcast_forum">        <id name="id">            <generator class="native" />        </id>        <property name="name" />        <property name="description" />        <property name="position" />    </class></hibernate-mapping>

String类型的映射都用Hibernate默认的配置。别忘了在Hibernate的配置文件hiberante.cfg.xml添加本文件的位置。
<mapping resource="com/shizongger/oa/domain/Forum.hbm.xml" />

由于目前我采用的是两层架构,合并和Serivce层和Dao层,所以我把Dao层对数据库基本增删改查都抽象到DaoSupport抽象类里。这是一个泛型参数的抽象类,具体传递进来的model类型属于什么类型是在构造方法中通过java反射机制得到的。

/** * @author shizongger * @param <T> 实际操作的daomain实体 */@Transactional@SuppressWarnings("unchecked")public abstract class DaoSupportImpl<T> implements DaoSupport<T> {    private Log log = LogFactory.getLog(this.getClass());       /**     * sessionFactory工厂     */    @Autowired    private SessionFactory sessionFactory;    private Class<T> clazz;    @SuppressWarnings("unchecked")    public DaoSupportImpl() {        // 使用反射技术得到T的真实类型        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类 类型        this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 获取第一个类型参数的真实类型    }    /**     * 增加     */    @Override    public void add(T entity) {        log.info("add:" + entity.toString());        getSession().save(entity);    }    /**     * 删除     */    @Override    public void delete(Long id) {        Object object = selectById(id);        if(object != null) {            getSession().delete(object);        }    }    /**     * 修改     */    @Override    public void update(T entity) {        getSession().update(entity);    }    /**     * 根据id查询     */    @Override    public T selectById(Long id) {        return (T) getSession().get(this.clazz, id);    }    /**     * 根据id数组查找对象集合     * @param ids id的列表     * @return     */    @Override    public List<T> getByIds(Long[] ids) {        if (ids == null || ids.length == 0) {            return Collections.EMPTY_LIST;        } else {            return getSession().createQuery(//                    "FROM " + clazz.getSimpleName() + " WHERE id IN (:ids)")//                    .setParameterList("ids", ids)//                    .list();        }    }    /**     * 根据id数组查询     */    @Override    public List<T> selectAll() {        List<T> list = getSession().createQuery("FROM " + this.clazz.getSimpleName()).list();        return list;    }    protected Session getSession() {        return sessionFactory.getCurrentSession();    }}

论坛管理的Service实现类代码如下:

@Service@Transactional@SuppressWarnings("unchecked")public class ForumServiceImpl extends DaoSupportImpl<Forum> implements ForumService {    Log log = LogFactory.getLog(this.getClass());    @Override    public void add(Forum forum) {        super.add(forum);        forum.setPosition(forum.getId().intValue());    }    @Override    public List<Forum> selectAll() {        return getSession()                .createQuery("FROM Forum f ORDER BY f.position")                .list();    }    /**     * 上移当前板块forum的位置position值     */    @Override    public void moveUp(Long id) {        //获取当前板块        Forum forum = selectById(id);        //上一个forum        Forum prexForum = (Forum)getSession()                            .createQuery("FROM Forum f WHERE f.position < ? ORDER BY f.position DESC")                            .setParameter(0, forum.getPosition())                            .setFirstResult(0)                            .setMaxResults(1)                            .uniqueResult();        //最上面的不能再往上移动        if(prexForum == null) {            return;        }        //交换当前和上一个的position        int position = forum.getPosition();        forum.setPosition(prexForum.getPosition());        prexForum.setPosition(position);        //更新两个对象到数据库中        getSession().save(forum);        getSession().save(prexForum);    }    /**     * 向下移动当前板块     */    @Override    public void moveDown(Long id) {        //获取当前板块        Forum forum = selectById(id);        //下一个forum        Forum nextForum = (Forum)getSession()                            .createQuery("FROM Forum f WHERE f.position > ? ORDER BY f.position ASC")                            .setParameter(0, forum.getPosition())                            .setFirstResult(0)                            .setMaxResults(1)                            .uniqueResult();            //最下面的不能再往下移        if(nextForum == null) {            return;        }        //交换当前forum和下一个forum的position        int position = nextForum.getPosition();        nextForum.setPosition(forum.getPosition());        forum.setPosition(position);        //更新两个对象到数据库中去        getSession().save(nextForum);        getSession().save(forum);    }}

增删改查功能只需要把model为Forum传递进去调用DaoSupport就行了,上移和下移的思路是jsp传递forum进来,先从数据库获得一个forum对象。如果是上移,则获取数据库中position所有小于本forum.position的那个最大的值。因为只要不是最上面的板块,小于自己position的板块可能有多个,而我们只需要最大的那个,也就是仅仅挨着自己的那个板块。然后交换两者的position值。

前端列表list.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head>    <title>版块列表</title>    <%@ include file="/WEB-INF/jsp/public/commons.jspf" %>        <script type="text/javascript">    </script>    <style type="text/css">        .disabled{            color: gray;            cursor: pointer;        }        </style></head><body><div id="Title_bar">    <div id="Title_bar_Head">        <div id="Title_Head"></div>        <div id="Title"><!--页面标题-->            <img src="${pageContext.request.contextPath }/style/images/title_arrow.gif" width="13" height="13" border="0"> 版块管理        </div>        <div id="Title_End"></div>    </div></div><div id="MainArea">    <table class="TableStyle" cellspacing="0" cellpadding="0">        <!-- 表头-->        <thead>            <tr id="TableTitle" valign="MIDDLE" align="CENTER">                <td width="250px">版块名称</td>                <td width="300px">版块说明</td>                <td>相关操作</td>            </tr>        </thead>        <!--显示数据列表-->        <tbody id="TableData" class="dataContainer" datakey="forumList">        <!-- 遍历forumList -->        <s:iterator value="#forumList" status="status">            <tr class="TableDetail1 demodata_record">                <td>${name }&nbsp;</td>                <td>${description }&nbsp;</td>                <td>                    <s:a action="forumManage_delete?id=%{id}" onclick="return delConfirm()">删除</s:a>                    <s:a action="forumManage_editUI?id=%{id }">修改</s:a>                    <!-- 最上面不能往上移 -->                    <s:if test="#status.first">                        <span class="disabled">上移</span>                    </s:if>                    <s:else>                        <s:a action="forumManage_moveUp?id=%{id }">上移</s:a>                    </s:else>                    <!-- 最下面的不能再往下移动 -->                    <s:if test="#status.last">                        <span class="disabled">下移</span>                    </s:if>                    <s:else>                        <s:a action="forumManage_moveDown?id=%{id }">下移</s:a>                    </s:else>                </td>            </tr>        </s:iterator>        </tbody>    </table>    <!-- 其他功能超链接 -->    <div id="TableTail">        <div id="TableTail_inside">            <a href="forumManage_addUI.action"><img src="${pageContext.request.contextPath }/style/images/createNew.png"></a>        </div>    </div></div><div class="Description">    说明:<br>    1,显示的列表按其sortOrder值升序排列。<br>    2,可以通过上移与下移功能调整顺序。最上面的不能上移,最下面的不能下移。<br></div></body></html>

新增和修改的页面

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head>    <title>版块设置</title>    <%@ include file="/WEB-INF/jsp/public/commons.jspf" %>    <script type="text/javascript">    </script></head><body><!-- 标题显示 --><div id="Title_bar">    <div id="Title_bar_Head">        <div id="Title_Head"></div>        <div id="Title"><!--页面标题-->            <img src="${pageContext.request.contextPath }/style/images/title_arrow.gif" width="13" height="13" border="0"> 版块设置        </div>        <div id="Title_End"></div>    </div></div><!--显示表单内容--><div id="MainArea">    <s:form action="forumManage_%{id == null ? 'add' : 'edit'}">        <!-- 隐藏表单内容 -->        <s:hidden name="id" value="%{#request.forum.id}"></s:hidden>        <div class="ItemBlock_Title1"><!-- 信息说明<DIV CLASS="ItemBlock_Title1">            <IMG BORDER="0" WIDTH="4" HEIGHT="7" SRC="${pageContext.request.contextPath }/style/blue/images/item_point.gif" /> 版块信息 </DIV>  -->        </div>        <!-- 表单内容显示 -->        <div class="ItemBlockBorder">            <div class="ItemBlock">                <table class="mainForm" cellspacing="0" cellpadding="0">                    <tbody>                        <tr>                            <td width="100">版块名称</td>                            <td><s:textfield name="name" cssClass="InputStyle" value="%{#request.forum.name}" > *</s:textfield></td>                        </tr>                        <tr>                            <td>版块说明</td>                            <td><s:textarea name="description" cssClass="TextareaStyle" value="%{#request.forum.description}"></s:textarea></td>                        </tr>                    </tbody>                </table>            </div>        </div>        <!-- 表单操作 -->        <div id="InputDetailBar">            <input src="${pageContext.request.contextPath }/style/images/save.png" type="image">            <a href="javascript:history.go(-1);"><img src="${pageContext.request.contextPath }/style/images/goBack.png"></a>        </div>    </s:form></div><div class="Description">    说明:<br>    1,新添加的版块默认显示在最下面。<br></div></body></html>
0 1
原创粉丝点击