SSH實(shí)戰(zhàn)OA 11:BBS模塊

《SSH實(shí)戰(zhàn)OA》系列博客的系統(tǒng)管理、權(quán)限管理等內(nèi)容后面再補(bǔ)上吧胎撇,先繼續(xù)第三個(gè)模塊:網(wǎng)上交流模塊贱傀。網(wǎng)上交流主要做兩個(gè)需求:論壇管理和論壇。

BBS的一些基本術(shù)語:

  1. 板塊:也叫做“版面”胎撤、“討論區(qū)”晓殊,用于對(duì)帖子進(jìn)行分類
  2. 主題:也叫做“主貼”,表示一個(gè)新的話題伤提,可以有很多回帖巫俺,屬于某個(gè)板塊。
  3. 回復(fù):也叫做“回帖”肿男、“跟帖”介汹,屬于某個(gè)主貼却嗡。

論壇模塊的功能說明:

  1. 瀏覽
    • 板塊列表
    • 顯示單個(gè)板塊(主題列表)
    • 顯示單個(gè)主題(主題+回帖列表)
  2. 參與
    • 發(fā)新帖
    • 回帖
  3. 管理文章
    • 主題
      • 設(shè)置類型
      • 移動(dòng)到其他板塊
      • 刪除
      • 修改
    • 回復(fù)
  4. 板塊管理
    • 增刪改查
    • 上下移動(dòng)

板塊管理

1.png

先來看看板塊管理的需求,由上圖可以看出嘹承,板塊管理主要的需求有板塊的新增窗价、刪除,修改叹卷,列表撼港,上移,下移這幾個(gè)需求骤竹。那么對(duì)應(yīng)的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的真實(shí)類型
            ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
            Class<T> clazz = (Class<T>) pt.getActualTypeArguments()[0];
            // 通過反射創(chuàng)建model的實(shí)例
            model = clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    @Override
    public T getModel() {
        return model;
    }
}

在暫未考慮與其他實(shí)體關(guān)聯(lián)的提前下,我們的model類可以這樣設(shè)計(jì):

/**
 * @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都默認(rèn)為L(zhǎng)ong型蒙揣,forum屬性自己的屬性有name,description,position靶溜。name用來記錄板塊名稱,description是對(duì)本板塊的描述懒震,而position是記錄板塊的排序位置罩息,方面上下移動(dòng)的操作。

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默認(rèn)的配置个扰。別忘了在Hibernate的配置文件hiberante.cfg.xml添加本文件的位置瓷炮。
<mapping resource="com/shizongger/oa/domain/Forum.hbm.xml" />

由于目前我采用的是兩層架構(gòu),合并和Serivce層和Dao層锨匆,所以我把Dao層對(duì)數(shù)據(jù)庫基本增刪改查都抽象到DaoSupport抽象類里崭别。這是一個(gè)泛型參數(shù)的抽象類,具體傳遞進(jìn)來的model類型屬于什么類型是在構(gòu)造方法中通過java反射機(jī)制得到的恐锣。

/**
 * @author shizongger
 * @param <T> 實(shí)際操作的daomain實(shí)體
 */
@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() {
        // 使用反射技術(shù)得到T的真實(shí)類型
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 獲取當(dāng)前new的對(duì)象的 泛型的父類 類型
        this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 獲取第一個(gè)類型參數(shù)的真實(shí)類型
    }
    
    /**
     * 增加
     */
    @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);
    }

    /**
     * 根據(jù)id查詢
     */
    @Override
    public T selectById(Long id) {
        return (T) getSession().get(this.clazz, id);
    }
    
    /**
     * 根據(jù)id數(shù)組查找對(duì)象集合
     * @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();
        }
    }
    
    /**
     * 根據(jù)id數(shù)組查詢
     */
    @Override
    public List<T> selectAll() {
        List<T> list = getSession().createQuery("FROM " + this.clazz.getSimpleName()).list();

        return list;
    }

    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }
}

論壇管理的Service實(shí)現(xiàn)類代碼如下:

@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();
    }

    /**
     * 上移當(dāng)前板塊forum的位置position值
     */
    @Override
    public void moveUp(Long id) {
        //獲取當(dāng)前板塊
        Forum forum = selectById(id);
        //上一個(gè)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();
        //最上面的不能再往上移動(dòng)
        if(prexForum == null) {
            return;
        }
        
        //交換當(dāng)前和上一個(gè)的position
        int position = forum.getPosition();
        forum.setPosition(prexForum.getPosition());
        prexForum.setPosition(position);
        
        //更新兩個(gè)對(duì)象到數(shù)據(jù)庫中
        getSession().save(forum);
        getSession().save(prexForum);
    }

    /**
     * 向下移動(dòng)當(dāng)前板塊
     */
    @Override
    public void moveDown(Long id) {
        //獲取當(dāng)前板塊
        Forum forum = selectById(id);
        
        //下一個(gè)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;
        }
        
        //交換當(dāng)前forum和下一個(gè)forum的position
        int position = nextForum.getPosition();
        nextForum.setPosition(forum.getPosition());
        forum.setPosition(position);
        
        //更新兩個(gè)對(duì)象到數(shù)據(jù)庫中去
        getSession().save(nextForum);
        getSession().save(forum);
    }
}

增刪改查功能只需要把model為Forum傳遞進(jìn)去調(diào)用DaoSupport就行了茅主,上移和下移的思路是jsp傳遞forum進(jìn)來,先從數(shù)據(jù)庫獲得一個(gè)forum對(duì)象土榴。如果是上移诀姚,則獲取數(shù)據(jù)庫中position所有小于本forum.position的那個(gè)最大的值。因?yàn)橹灰皇亲钌厦娴陌鍓K玷禽,小于自己position的板塊可能有多個(gè)赫段,而我們只需要最大的那個(gè),也就是僅僅挨著自己的那個(gè)板塊矢赁。然后交換兩者的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"><!--頁面標(biāo)題-->
            ![](${pageContext.request.contextPath }/style/images/title_arrow.gif) 版塊管理
        </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>相關(guān)操作</td>
            </tr>
        </thead>

        <!--顯示數(shù)據(jù)列表-->
        <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>
                    <!-- 最下面的不能再往下移動(dòng) -->
                    <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">![](${pageContext.request.contextPath }/style/images/createNew.png)</a>
        </div>
    </div>
</div>

<div class="Description">
    說明:<br>
    1,顯示的列表按其sortOrder值升序排列撩银。<br>
    2给涕,可以通過上移與下移功能調(diào)整順序。最上面的不能上移,最下面的不能下移够庙。<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>版塊設(shè)置</title>
    <%@ include file="/WEB-INF/jsp/public/commons.jspf" %>
    <script type="text/javascript">
    </script>
</head>
<body>

<!-- 標(biāo)題顯示 -->
<div id="Title_bar">
    <div id="Title_bar_Head">
        <div id="Title_Head"></div>
        <div id="Title"><!--頁面標(biāo)題-->
            ![](${pageContext.request.contextPath }/style/images/title_arrow.gif) 版塊設(shè)置
        </div>
        <div id="Title_End"></div>
    </div>
</div>

<!--顯示表單內(nèi)容-->
<div id="MainArea">
    <s:form action="forumManage_%{id == null ? 'add' : 'edit'}">
        <!-- 隱藏表單內(nèi)容 -->
        <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>
        
        <!-- 表單內(nèi)容顯示 -->
        <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);">![](${pageContext.request.contextPath }/style/images/goBack.png)</a>
        </div>
    </s:form>
</div>

<div class="Description">
    說明:<br>
    1恭应,新添加的版塊默認(rèn)顯示在最下面。<br>
</div>



</body></html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耘眨,一起剝皮案震驚了整個(gè)濱河市昼榛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剔难,老刑警劉巖胆屿,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異钥飞,居然都是意外死亡莺掠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門读宙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人楔绞,你說我怎么就攤上這事结闸。” “怎么了酒朵?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵桦锄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蔫耽,道長(zhǎng)结耀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任匙铡,我火速辦了婚禮图甜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鳖眼。我一直安慰自己黑毅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布钦讳。 她就那樣靜靜地躺著矿瘦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愿卒。 梳的紋絲不亂的頭發(fā)上缚去,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音琼开,去河邊找鬼易结。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衬衬。 我是一名探鬼主播买猖,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼滋尉!你這毒婦竟也來了玉控?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤狮惜,失蹤者是張志新(化名)和其女友劉穎高诺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碾篡,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虱而,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了开泽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牡拇。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖穆律,靈堂內(nèi)的尸體忽然破棺而出惠呼,到底是詐尸還是另有隱情,我是刑警寧澤峦耘,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布剔蹋,位于F島的核電站,受9級(jí)特大地震影響辅髓,放射性物質(zhì)發(fā)生泄漏泣崩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一洛口、第九天 我趴在偏房一處隱蔽的房頂上張望矫付。 院中可真熱鬧,春花似錦绍弟、人聲如沸技即。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽而叼。三九已至,卻和暖如春豹悬,著一層夾襖步出監(jiān)牢的瞬間葵陵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工瞻佛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脱篙,地道東北人娇钱。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像绊困,于是被迫代替她去往敵國和親文搂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容