SSH实战OA 11:BBS模块。
先来看看板块管理的需求,由上图可以看出,板块管理主要的需求有板块的新增、删除,修改,列表,上移,下移这几个需求。那么对应的Action方法如下:
@Controller @Scope("prototype") public class ForumManageAction extends BaseAction{ Log log = LogFactory.getLog(this.getClass()); /** * @return 板块列表 * @throws Exception */ public String list() throws Exception { List 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 BaseActionextends ActionSupport implements ModelDriven { 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 clazz = (Class ) 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文件如下:
String类型的映射都用Hibernate默认的配置。别忘了在Hibernate的配置文件hiberante.cfg.xml添加本文件的位置。
由于目前我采用的是两层架构,合并和Serivce层和Dao层,所以我把Dao层对数据库基本增删改查都抽象到DaoSupport抽象类里。这是一个泛型参数的抽象类,具体传递进来的model类型属于什么类型是在构造方法中通过java反射机制得到的。
/**
* @author shizongger
* @param 实际操作的daomain实体
*/
@Transactional
@SuppressWarnings("unchecked")
public abstract class DaoSupportImpl implements DaoSupport {
private Log log = LogFactory.getLog(this.getClass());
/**
* sessionFactory工厂
*/
@Autowired
private SessionFactory sessionFactory;
private Class clazz;
@SuppressWarnings("unchecked")
public DaoSupportImpl() {
// 使用反射技术得到T的真实类型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类 类型
this.clazz = (Class) 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 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 selectAll() {
List 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 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 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"%>
版块管理
版块名称 |
版块说明 |
相关操作 |
${name } |
${description } |
|
说明:
1,显示的列表按其sortOrder值升序排列。
2,可以通过上移与下移功能调整顺序。最上面的不能上移,最下面的不能下移。
新增和修改的页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
说明:
1,新添加的版块默认显示在最下面。