SSH实战OA 11:BBS模块
来源:互联网 发布:ubuntu解压缩zip 编辑:程序博客网 时间:2024/06/03 21:30
《SSH实战OA》系列博客的系统管理、权限管理等内容后面再补上吧,先继续第三个模块:网上交流模块。网上交流主要做两个需求:论坛管理和论坛。
BBS的一些基本术语:
- 板块:也叫做“版面”、“讨论区”,用于对帖子进行分类
- 主题:也叫做“主贴”,表示一个新的话题,可以有很多回帖,属于某个板块。
- 回复:也叫做“回帖”、“跟帖”,属于某个主贴。
论坛模块的功能说明:
- 浏览
- 板块列表
- 显示单个板块(主题列表)
- 显示单个主题(主题+回帖列表)
- 参与
- 发新帖
- 回帖
- 管理文章
- 主题
- 设置类型
- 移动到其他板块
- 删除
- 修改
- 回复
- 主题
- 板块管理
- 增删改查
- 上下移动
板块管理
先来看看板块管理的需求,由上图可以看出,板块管理主要的需求有板块的新增、删除,修改,列表,上移,下移这几个需求。那么对应的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 } </td> <td>${description } </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>
- SSH实战OA 11:BBS模块
- SSH实战OA 02:SSH框架搭建
- SSH实战OA 01:项目说明
- SSH实战OA 03:设计BaseDAo
- SSH实战OA 05:Struts2标签
- SSH实战OA 04:Struts2的OGNL表达式
- ssh整合OA
- SSH框架-OA
- jQuery2.0应用开发:SSH框架整合jQuery2.0实战OA办公自动化(VSS、operamasks-UI框架)
- jQuery2.0应用开发:SSH框架整合jQuery2.0实战OA办公自动化(VSS、operamasks-UI框架)
- jQuery2.0应用开发:SSH框架整合jQuery2.0实战OA办公自动化(VSS、operamasks-UI框架)
- jQuery2.0应用开发:SSH框架整合jQuery2.0实战OA办公自动化(VSS、operamasks-UI框架)
- OA实战项目
- OA项目实战
- OA审批流转模块
- OA员工管理模块
- OA项目--模块
- 项目视频讲解_jQuery2.0应用开发-SSH框架整合jQuery2.0实战OA办公自动化(VSS、operamasks-UI框架)
- 十进制和二进制的相互转换
- mysql处理海量数据时的一些优化查询速度方法
- 反编译pyc得到python源码
- 指针与引用
- 一幅图理解计算机系统硬件组成
- SSH实战OA 11:BBS模块
- postman中 form-data、x-www-form-urlencoded、raw、binary的区别
- java开发系统内核:实现系统API调用
- 不容易系列之一
- android webview 加载H5页面,设置字体不随系统设置变化
- ffmpeg实战教程(五)libswscale,libavfilter实践指南
- Top100论文导读:深入理解卷积神经网络CNN(Part Ⅰ)
- 1090. Highest Price in Supply Chain 解析
- ContentResolver query 参数详解