论坛系统(基于SSH实现)
学web后台开发已经有一段时间了,是时候做一点小总结。前段时间学习了一个小项目——论坛系统,是基于Spring+Struts1+Hibernate框架开发的,虽然Struts1框架已逐渐比较少人用了,但作为初学者我觉得还是有必要了解一下。在实现完这个小系统后,我想把它改成基于Struts2实现的,毕竟Struts2比Struts1优秀得多。但了解到目前很多企业公司都采用了Spring+SpringMVC+Mybatis的组合框架,所以后来我把这个系统改成了基于Spring+SpringMVC+Mybatis实现的,SSM比SSH好就不用我多说了。下面先介绍基于SSH实现的,想看基于SSM实现的可直接看下一篇文章。
整个工程目录以及数据库表如下图:
代码下载
运行效果:
界面虽然丑了点,但我们这里只专注于后台开发,界面就交给前端吧!下面UI的代码就不贴出来了,自己下载看吧。
1、系统功能模块
本系统包括5个模块:用户模块、版面类型模块、版面模块、帖子模块和回帖模块。
用户模块:包括用户的注册、登录、注销、以及查看用户资料等功能。发表帖子、发表回帖、设置版主等都需要用到用户信息。注册时将记录用户的注册IP、注册时间等,登录时将记录用户的登录IP、登录时间等。
版面类别模块:本系统为二级结构,即先创建版面类别,然后才创建版面。本模块包括创建版面类别,列出所有的类别、首页等。首页将列出所有的版面类别、各类别下对应的版面、帖子总数、回帖总数、最后发表的帖子或者回复、版主等。
版面模块:包括创建版面、设置版主,列出所有本版的帖子等。帖子列表包括帖子标题、作者、发表时间、回帖数、人气、最后回复人、最后回复时间等。
帖子模块 :包括发表帖子、浏览帖子等。发表帖子时记录发表帖子的IP等;浏览帖子时分页列出所有的回帖,并更新帖子的人气(浏览次数)等。
回帖模块:包括发表回帖等。
2、数据库设计
实体类使用Hibernate的注解的方式配置,数据库表结构由实体类决定,DDL语句由Hibernate自动生成。本系统包括5个实体类:Person(用户)、Category(版面类型)、Board(版面)、Thread(帖子)、Reply(回帖)。所有实体类都继承自BaseBean,BaseBean中定义了主键id、乐观锁键version、删除标志位deleted、创建日期dateCreated等基本字段。各实体类之间存在着一对一、一对多、多对多等关系,实体类关系图如下图:
2.1、BaseBean基类代码
BaseBean基类代码以及Hibernate配置如下(getter、setter方法略,下同):
注意:实体类中的父类要使用@MappedSuperclass
package bean;
@MappedSuperclass //实体类父类
public class BaseBean {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Version //版本列,hibernate自动维护该列
private Integer version;
private boolean deleted;
@Temporal(value = TemporalType.TIMESTAMP)
private Date dateCreated;
}
package bean;
@Entity
@Table
public class Person extends BaseBean {
private String account;
private String password;
private String sex;
private String name;
private String birthday;
private String email;
private String ipCreated;
@Temporal(value = TemporalType.TIMESTAMP)
private Date dateLastActived;
private String ipLastActived;
@ManyToMany(mappedBy = "administrators")
private Set boardsAdministrated = new HashSet();
}
package bean;
@Entity
@Table
@org.hibernate.annotations.Entity
public class Category extends BaseBean {
private String name;
@OneToMany(mappedBy = "category")
private List boards = new ArrayList();
}
package bean;
@Entity
@Table
public class Board extends BaseBean {
@ManyToOne
@JoinColumn(name = "category_id")
private Category category;
private String name;
private String description;
private int threadCount;
private int replyCount;
@ManyToOne
@JoinColumn(name = "last_reply_id")
private Reply lastReply;
@ManyToOne
@JoinColumn(name = "last_thread_id")
private Thread lastThread;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "board_administrator", joinColumns = { @JoinColumn(name = "board_id") }, inverseJoinColumns = { @JoinColumn(name = "person_id") })
private Set administrators = new HashSet();
}
package bean;
@Entity
@Table
@org.hibernate.annotations.Entity
public class Thread extends BaseBean {
@ManyToOne
@JoinColumn(name = "board_id")
private Board board;
private String title;
@Basic(fetch = FetchType.LAZY)
@Column(columnDefinition="longtext")
private String content;
@ManyToOne
@JoinColumn(name = "author_id")
private Person author;
private String ipCreated;
private int hit;
@ManyToOne
@JoinColumn(name = "author_last_replied_id")
private Person authorLastReplied;
@Temporal(TemporalType.TIMESTAMP)
private Date dateLastReplied;
private boolean readonly;
private boolean topped;
private int replyCount;
}
package bean;
@Entity
@Table
@org.hibernate.annotations.Entity
public class Reply extends BaseBean {
@ManyToOne
@JoinColumn(name = "thread_id")
private Thread thread;
private String title;
@Basic(fetch = FetchType.LAZY)
private String content;
@ManyToOne
@JoinColumn(name = "author_id")
private Person author;
private int floor;
private String ipCreated;
}
bean.Board
bean.Category
bean.Person
bean.Reply
bean.Thread
org.hibernate.dialect.MySQLDialect
true
update
thread
PROPAGATION_REQUIRED
......
package dao;
public interface IDao {
public T find(Class clazz, int id);
public void create(T baseBean);
public void save(T baseBean);
public void delete(T baseBean);
public List list(String hql);
public int getTotalCount(String hql, Object... params);
public List list(String hql, int firstResult, int maxSize,
Object... params);
public Query createQuery(String hql);
}
package dao;
public class DaoImpl extends HibernateDaoSupport implements IDao {
@SuppressWarnings("unchecked")
public T find(Class clazz, int id) {
return (T) getHibernateTemplate().get(clazz, id);
}
public void create(T baseBean) {
getHibernateTemplate().persist(baseBean);
}
public Query createQuery(String hql) {
return getSession().createQuery(hql);
}
public void delete(T baseBean) {
getHibernateTemplate().delete(baseBean);
}
@SuppressWarnings("unchecked")
public List list(String hql) {
return getHibernateTemplate().find(hql);
}
public int getTotalCount(String hql, Object... params) {
Query query = createQuery(hql);
for (int i = 0; params != null && i < params.length; i++)
query.setParameter(i + 1, params[i]);
Object obj = createQuery(hql).uniqueResult();
return ((Long) obj).intValue();
}
@SuppressWarnings("unchecked")
public List list(String hql, int firstResult, int maxResults,Object... params) {
Query query = createQuery(hql);
for (int i = 0; params != null && i < params.length; i++)
query.setParameter(i + 1, params[i]);
List list = createQuery(hql).setFirstResult(firstResult).setMaxResults(maxResults).list();
return list;
}
public void save(T baseBean) {
getHibernateTemplate().save(baseBean);
}
}
package Service;
public interface IService {
public T find(Class clazz, int id);
public void create(T baseBean);
public void save(T baseBean);
public void delete(T baseBean);
public List list(String hql);
public int getTotalCount(String hql, Object... params);
public List list(String hql, int firstResult, int maxSize,
Object... params);
}
package Service;
public abstract class ServiceImpl implements IService {
protected IDao dao;
public IDao getDao() {
return dao;
}
public void setDao(IDao dao) {
this.dao = dao;
}
public T find(Class clazz, int id) {
return dao.find(clazz, id);
}
public abstract void create(T baseBean);
public void delete(T baseBean) {
baseBean.setDeleted(true);
dao.save(baseBean);
}
public int getTotalCount(String hql, Object... params) {
return dao.getTotalCount(hql, params);
}
public void save(T baseBean) {
dao.save(baseBean);
}
public List list(String hql) {
return dao.list(hql);
}
public List list(String hql, int firstResult, int maxSize,
Object... params) {
return dao.list(hql, firstResult, maxSize, params);
}
}
package form;
public class ForumForm extends ActionForm {
private String action;
private String title;
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
package action;
public abstract class ForumAction extends DispatchAction {
protected Log log = LogFactory.getLog(getClass());
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception {
ForumForm forumForm = (ForumForm) form;
forumForm.setTitle("轻量级 Java EE 论坛程序");
System.out.println("execute action:"+forumForm.getAction());
if (forumForm.getAction() == null|| forumForm.getAction().trim().length() == 0) {
return this.list(mapping, form, request, response);
}
return super.execute(mapping, form, request, response);
}
public abstract ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception;
}
package Service;
public interface IPersonService extends IService {
/** 根据帐号查找用户 */
public T findPersonByAccount(String account);
/** 根据帐号、密码查找用户 */
public T getPerson(String account, String password);
}
package Service;
public class PersonServiceImpl extends ServiceImpl implements IPersonService {
@SuppressWarnings("unchecked")
@Override
public T findPersonByAccount(String account) {
List person = this.getDao().createQuery(" select p from Person p "+ " where lower(p.account) = lower(:account) and deleted = false ")
.setParameter("account", account.trim()).list();
if (person.size() > 0)
return person.get(0);
return null;
}
@SuppressWarnings("unchecked")
@Override
public T getPerson(String account, String password) {
List list = this.getDao().createQuery(" select p from Person p where p.account = :account "+ " and p.password = :password and p.deleted = false ")
.setParameter("account", account).setParameter("password",MD5Util.calc(password)).list();
if (list.size() > 0)
return list.get(0);
return null;
}
@Override
public void create(T person) {
if (findPersonByAccount(person.getAccount()) != null)
throw new RuntimeException("帐号 " + person.getAccount() + " 已经存在。");
person.setPassword(MD5Util.calc(person.getPassword()));
this.getDao().create(person);
}
}
package form;
public class PersonForm extends ForumForm {
private Person person = new Person();
private String password;
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
return null;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
}
}
package action;
public class PersonAction extends ForumAction {
private IPersonService personService;
//默认方法 返回到注册页面
public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
return this.initAdd(mapping, form, request, response);
}
public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
PersonForm personForm = (PersonForm) form;
personForm.setTitle("用户注册");
return mapping.findForward("add");
}
public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
PersonForm personForm = (PersonForm) form;
personForm.setTitle("用户注册");
Person person = personForm.getPerson();
person.setIpCreated(request.getRemoteAddr());
person.setIpLastActived(request.getRemoteAddr());
person.setDateCreated(new Date());
person.setDateLastActived(new Date());
if (person.getAccount() == null|| person.getAccount().trim().length() == 0) {
request.setAttribute("message", "请输入帐号");
return this.initAdd(mapping, form, request, response);
}
if (person.getPassword() == null|| person.getPassword().trim().length() == 0|| !person.getPassword().equals(personForm.getPassword())) {
request.setAttribute("message", "密码不一致");
return this.initAdd(mapping, form, request, response);
}
try {
personService.create(person);
PersonUtil.setPersonInf(request, response, person);
request.setAttribute("message", "注册成功");
return new ActionForward("success", "/jsp/person/success.jsp",false);
} catch (Exception e) {
request.setAttribute("message", "注册失败,原因:" + e.getMessage());
return this.initAdd(mapping, form, request, response);
}
}
public IPersonService getPersonService() {
return personService;
}
public void setPersonService(IPersonService personService) {
this.personService = personService;
}
}
//结合前面代码
loginInterceptor
注册界面的效果如下:
package action;
public class PersonAction extends ForumAction {
private IPersonService personService;
//结合前面相关代码
public ActionForward initLogin(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
PersonForm personForm = (PersonForm) form;
personForm.setTitle("用户登录");
return new ActionForward("login", "/jsp/person/login.jsp", false);
}
public ActionForward login(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {
PersonForm personForm = (PersonForm) form;
personForm.setTitle("用户登录");
Person person = personService.getPerson(personForm.getPerson().getAccount(), personForm.getPerson().getPassword());
if (person == null)
throw new AccountException("用户名密码错误");
PersonUtil.setPersonInf(request, response, person);
person.setIpLastActived(request.getRemoteAddr());
person.setDateLastActived(new Date());
personService.save(person);
request.setAttribute("message", "欢迎回来");
return new ActionForward("success", "/jsp/person/success.jsp", false);
}
public ActionForward logout(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {
PersonForm personForm = (PersonForm) form;
personForm.setTitle("用户注销");
request.getSession(true).setAttribute(PersonUtil.PERSON_INFO, null);
return new ActionForward("login", "/jsp/person/login.jsp", false);
}
}
package action;
public class PersonAction extends ForumAction {
private IPersonService personService;
//结合前面代码
public ActionForward view(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {
PersonForm personForm = (PersonForm) form;
personForm.setTitle("查看用户资料");
Person person = personService.find(Person.class, personForm.getPerson().getId());
request.setAttribute("person", person);
return new ActionForward("view", "/jsp/person/viewPerson.jsp", false);
}
}
运行效果:
package Service;
public interface ICategoryService extends IService {
}
package Service;
public class CategoryServiceImpl extends ServiceImpl implements ICategoryService {
@Override
public void create(T category) {
if (dao.createQuery(" from Category c where c.name = :name and c.deleted = false ").setParameter("name", category.getName()).list().size() > 0)
throw new RuntimeException("类别 " + category.getName() + " 已经存在。");
dao.create(category);
}
}
package form;
public class CategoryForm extends ForumForm {
private Category category = new Category();
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
return null;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
}
}
package action;
public class CategoryAction extends ForumAction {
private ICategoryService categoryService;
public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
CategoryForm categoryForm = (CategoryForm) form;
List categoryList = categoryService.list(" from Category where deleted = false ", 0, Integer.MAX_VALUE,null);
request.setAttribute("categoryList", categoryList);
return new ActionForward("list", "/jsp/category/listCategory.jsp",false);
}
public ICategoryService getCategoryService() {
return categoryService;
}
public void setCategoryService(ICategoryService categoryService) {
this.categoryService = categoryService;
}
}
package action;
public class CategoryAction extends ForumAction {
private ICategoryService categoryService;
public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
CategoryForm categoryForm = (CategoryForm) form;
categoryForm.setTitle("添加类别");
return new ActionForward("add", "/jsp/category/addCategory.jsp", false);
}
public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
CategoryForm categoryForm = (CategoryForm) form;
categoryForm.setTitle("添加类别");
Category category = categoryForm.getCategory();
category.setDateCreated(new Date());
categoryService.create(category);
request.setAttribute("category", category);
return new ActionForward("add", "/jsp/category/success.jsp", false);
}
}
运行效果:
package Service;
public interface IBoardService extends IService {
}
package Service;
public class BoardServiceImpl extends ServiceImpl implements IBoardService {
@Override
public void create(T board) {
if (dao.createQuery(" from Board b where b.deleted = false and b.name = :name ").setParameter("name", board.getName().trim()).list().size() > 0)
throw new RuntimeException("版面 " + board.getName() + " 已经存在。");
dao.create(board);
}
}
package form;
public class BoardForm extends ForumForm {
private Category category = new Category();
private Board board = new Board();
private int[] adminId;
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
return null;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
}
//省略getter和setter方法
}
package action;
public class BoardAction extends ForumAction {
private ICategoryService categoryService;
private IBoardService boardService;
private IThreadService threadService;
private IPersonService personService;
@Override
@SuppressWarnings("all")
public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
BoardForm boardForm = (BoardForm) form;
Board board = boardService.find(Board.class, boardForm.getBoard().getId());
boardForm.setBoard(board);
int totalCount = threadService.getTotalCount(" select count(t) from Thread t "+ " where t.deleted = false and t.board.id = "+ board.getId(), null);
Pagination pagination = new Pagination(request, response);
pagination.setRecordCount(totalCount);
List threadList = threadService.list(" select t from Thread t "+ " where t.deleted = false and t.board.id = " + board.getId()
+ " order by t.dateLastReplied desc ", pagination.getFirstResult(), pagination.getPageSize(), null);
request.setAttribute("board", board);
request.setAttribute("pagination", pagination);
request.setAttribute("threadList", threadList);
boardForm.setTitle("帖子列表 - 版面:" + board.getName());
return new ActionForward("list", "/jsp/thread/listThread.jsp", false);
}
//省略setter和getter方法
}
实现效果:
package action;
public class BoardAction extends ForumAction {
private ICategoryService categoryService;
private IBoardService boardService;
private IThreadService threadService;
private IPersonService personService;
public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
BoardForm boardForm = (BoardForm) form;
boardForm.setTitle("添加版面");
List categoryList = categoryService.list(" from Category c where c.deleted = false ");
request.setAttribute("categoryList", categoryList);
return new ActionForward("add", "/jsp/board/addBoard.jsp", false);
}
public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
BoardForm boardForm = (BoardForm) form;
boardForm.setTitle("添加版面");
Category category = categoryService.find(Category.class, boardForm.getCategory().getId());
Board board = boardForm.getBoard();
board.setCategory(category);
board.setDateCreated(new Date());
boardService.create(board);
request.setAttribute("category", category);
return new ActionForward("success", "/jsp/board/success.jsp", false);
}
}
实现效果:
package action;
public class BoardAction extends ForumAction {
private ICategoryService categoryService;
private IBoardService boardService;
private IThreadService threadService;
private IPersonService personService;
public ActionForward initSetAdmin(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
BoardForm boardForm = (BoardForm) form;
Board board = boardService.find(Board.class, boardForm.getBoard().getId());
List personList = personService.list(" from Person p where p.deleted = false ");
int[] adminId = new int[board.getAdministrators().size()];
int i = 0;
for (Iterator it = board.getAdministrators().iterator(); it.hasNext(); i++) {
Person p = it.next();
adminId[i] = p.getId();
}
boardForm.setAdminId(adminId);
request.setAttribute("board", board);
request.setAttribute("personList", personList);
boardForm.setTitle("设置管理员 - 版面:" + board.getName());
return new ActionForward("success", "/jsp/board/setAdmin.jsp", false);
}
public ActionForward setAdmin(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
BoardForm boardForm = (BoardForm) form;
Board board = boardService.find(Board.class, boardForm.getBoard().getId());
board.getAdministrators().clear();
int[] adminId = boardForm.getAdminId();
for (int i = 0; adminId != null && i < adminId.length; i++) {
Person person = personService.find(Person.class, adminId[i]);
board.getAdministrators().add(person);
}
boardService.save(board);
boardForm.setTitle("设置管理员 - 版面:" + board.getName());
return new ActionForward("success", "/jsp/board/success.jsp", false);
}
}
实现效果:
package Service;
public interface IThreadService extends IService {
public void updateHit(Integer threadId);
}
package Service;
public class ThreadServiceImpl extends ServiceImpl implements IThreadService {
@Override
@SuppressWarnings("all")
public void create(T thread) {
dao.create(thread);
int totalCount = dao.getTotalCount(" select count(t) from Thread t "+ " where t.deleted = false and t.board.id = "+ thread.getBoard().getId(), null);
dao.createQuery(" update Board b "+ " set b.lastThread.id = :lastThreadId, b.lastReply.id = null, threadCount = :threadCount "+ " where b.id = :boardId ").setParameter(
"lastThreadId", thread.getId()).setParameter("boardId",thread.getBoard().getId()).setParameter("threadCount",totalCount).executeUpdate();
}
public void updateHit(Integer threadId) {
dao.createQuery(" update Thread t set t.hit = t.hit + 1 where t.id = :id ").setParameter("id", threadId).executeUpdate();
}
}
package form;
public class ThreadForm extends ForumForm {
private Thread thread = new Thread();
private Board board = new Board();
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
return null;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
}
//省略setter和getter方法
}
package action;
public class ThreadAction extends ForumAction {
private IThreadService threadService;
private IPersonService personService;
private IBoardService boardService;
private IReplyService replyService;
@Override
@SuppressWarnings("all")
public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
return this.view(mapping, form, request, response);
}
@SuppressWarnings("all")
public ActionForward view(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
ThreadForm threadForm = (ThreadForm) form;
Thread thread = threadService.find(Thread.class, (int) threadForm.getThread().getId());
int totalCount = replyService.getTotalCount(" select count(r) from Reply r "+ " where r.deleted = false and r.thread.id = "
+ threadForm.getThread().getId(), null);
Pagination pagination = new Pagination(request, response);
pagination.setRecordCount(totalCount);
List replyList = replyService.list(" from Reply r where r.deleted = false and r.thread.id = "+ threadForm.getThread().getId()
+ " order by r.id asc ", pagination.getFirstResult(),pagination.getPageSize(), null);
threadService.updateHit(thread.getId());
request.setAttribute("category", thread.getBoard().getCategory());
request.setAttribute("board", thread.getBoard());
request.setAttribute("thread", thread);
request.setAttribute("pagination", pagination);
request.setAttribute("replyList", replyList);
threadForm.setTitle("浏览帖子 - 标题:" + thread.getTitle());
return new ActionForward("list", "/jsp/thread/viewThread.jsp", false);
}
//省略setter和getter方法
}
实现效果:
package action;
public class ThreadAction extends ForumAction {
private IThreadService threadService;
private IPersonService personService;
private IBoardService boardService;
private IReplyService replyService;
public ActionForward initAdd(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
ThreadForm threadForm = (ThreadForm) form;
Board board = boardService.find(Board.class, threadForm.getBoard().getId());
threadForm.setBoard(board);
request.setAttribute("board", board);
threadForm.setTitle("发表帖子 - 版面:" + board.getName());
return new ActionForward("add", "/jsp/thread/addThread.jsp", false);
}
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
ThreadForm threadForm = (ThreadForm) form;
Board board = boardService.find(Board.class, threadForm.getBoard().getId());
PersonInfo personInfo = PersonUtil.getPersonInfo(request, response);
Person person = personService.find(Person.class, personInfo.getId());
Thread thread = threadForm.getThread();
thread.setBoard(board);
thread.setAuthor(person);
thread.setAuthorLastReplied(null);
thread.setDateCreated(new Date());
thread.setDateLastReplied(new Date());
thread.setDeleted(false);
thread.setIpCreated(request.getRemoteAddr());
thread.setReadonly(false);
thread.setReplyCount(0);
thread.setTopped(false);
threadService.create(thread);
threadForm.setTitle("发表帖子 - 版面:" + board.getName());
return this.list(mapping, form, request, response);
}
}
运行效果:
package Service;
public interface IReplyService extends IService {
}
package Service;
public class ReplyServiceImpl extends ServiceImpl implements IReplyService {
@Override
public void create(T reply) {
dao.create(reply);
// 更新帖子最后回复、最后回复日期、作者、回帖数
int count = dao.getTotalCount(" select count(r) from Reply r "+ " where r.deleted = false and r.thread.id = "+ reply.getThread().getId(), null);
dao.createQuery(" update Thread t "+ " set t.authorLastReplied.id = :authorLastReplied, "+ " t.dateLastReplied = :dateLastReplied, "
+ " t.replyCount = :replyCount "+ " where t.id = :threadId ").setParameter("authorLastReplied", reply.getAuthor().getId()).setParameter(
"dateLastReplied", reply.getDateCreated()).setParameter("replyCount", count).setParameter("threadId",reply.getThread().getId()).executeUpdate();
// 更新版面的最后发表数、最后发表时间
int replyCount = dao.getTotalCount(" select count(r) from Reply r "+ " where r.deleted = false " + " and r.thread.board.id = "+ reply.getThread().getBoard().getId(), null);
dao.createQuery(" update Board b " + " set b.lastThread.id = null, "+ " b.lastReply.id = :lastReplyId, "
+ " b.replyCount = :replyCount "+ " where b.id = :boardId ").setParameter(
"lastReplyId", reply.getId()).setParameter("boardId",reply.getThread().getBoard().getId()).setParameter("replyCount", replyCount).executeUpdate();
int floor = dao.getTotalCount(" select count(r) from Reply r "+ " where r.thread.id = " + reply.getThread().getId(), null);
// 回帖处于第几楼
reply.setFloor(floor);
dao.save(reply);
}
}
package form;
public class ReplyForm extends ForumForm {
private Thread thread = new Thread();
private Reply reply = new Reply();
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
return null;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
}
//省略setter和getter方法
}
package action;
public class ReplyAction extends ForumAction {
private IPersonService personService;
private IThreadService threadService;
private IReplyService replyService;
public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
ReplyForm replyForm = (ReplyForm) form;
return null;
}
public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
ReplyForm replyForm = (ReplyForm) form;
Thread thread = threadService.find(Thread.class, (int) replyForm.getThread().getId());
request.setAttribute("category", thread.getBoard().getCategory());
request.setAttribute("board", thread.getBoard());
request.setAttribute("thread", thread);
replyForm.setTitle("回复帖子 - 标题:" + thread.getTitle());
return new ActionForward("add", "/jsp/reply/addReply.jsp", false);
}
public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
ReplyForm replyForm = (ReplyForm) form;
Thread thread = threadService.find(Thread.class, (int) replyForm.getThread().getId());
PersonInfo personInfo = PersonUtil.getPersonInfo(request, response);
Person person = personService.find(Person.class, personInfo.getId());
Reply reply = replyForm.getReply();
reply.setThread(thread);
reply.setDateCreated(new Date());
reply.setDeleted(false);
reply.setAuthor(person);
replyService.create(reply);
request.setAttribute("category", thread.getBoard().getCategory());
request.setAttribute("board", thread.getBoard());
request.setAttribute("thread", thread);
request.setAttribute("reply", reply);
replyForm.setTitle("回复帖子 - 标题:" + thread.getTitle());
return new ActionForward("success", "/jsp/reply/success.jsp", false);
}
//省略setter和getter方法
}
实现效果: