----------------------------------------------------------------------------------------------
[版权申明:本文系做者原创,转载请注明出处]
文章出处:http://blog.csdn.net/sdksdk0/article/details/52506671
做者:朱培 ID:sdksdk0 邮箱: zhupei@tianfang1314.cn html
--------------------------------------------------------------------------------------------java
最近在作的是一个经过Struts二、Hibernate、spring框架整合作的一个CRM系统,总体开发比较简单,就是细节的地方处理仍是要花费必定的功夫,我主要负责的是人事管理(包括部门管理、职务管理、员工基本信息管理)、教学管理(班级管理、课程类别管理)、系统设置(修改密码、登陆、退出)。总体功能比较简单,适合通常性开发。涉及的技术要点就是经过HQL来进行数据的增删改查、部门-职务级联、分页、经过struts进行文件上传下载等。只不过有个别的地方仍是花费了几个小时。git
首先是对总体的开发环境的搭建:github
经过分模块开发来处理,框架的使用时分为了struts和spring,不一样的模块的struts的命名也不一样,spring也同样,同时hibernate放到相应的实体bean的文件夹下面。spring
在开发中咱们都有不少地方用到了Dao和DaoImpl,因此咱们能够将其抽取出来,做为一个基本的Dao,而后让其余用到的类去集成这个基础的dao便可,这样大大减小了开发的代码。数据库
在BaseDao中咱们能够写好经常使用的几种方法:浏览器
//通用dao接口 public interface BaseDao<T> { //保存 public void save(T t); //更新 public void update(T t); //删除 public void delete(T t); //保存或更新 public void SaveOrUpdate(T t); //查询全部 public List<T> findAll(); //条件查询 public List<T> findAll(String condition,Object... params); //离线查询 public List<T> findAll(DetachedCriteria detachedCriteria); //分页 public List<T> findAllByPage(int startIndex,int pageSize); //分页的总记录数 public int getTotalRecode(); //查找 T findById(Serializable serializable); }
而后咱们须要一个DaoImpl去实现这个公共dao的方法:session
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{ private Class daoImplClass; public BaseDaoImpl() { //运行时,经过反射得到 泛型信息的实际内容 /// * 运行时,this表示当前运行类(及子类的实例对象) //1 得到被参数化类型 ,例如:BaseDaoImpl<CrmPost> ParameterizedType paramType = (ParameterizedType) this.getClass().getGenericSuperclass(); //2 得到实例参数 daoImplClass = (Class) paramType.getActualTypeArguments()[0]; } @Override public void save(T t) { this.getHibernateTemplate().save(t); } @Override public void update(T t) { this.getHibernateTemplate().update(t); } @Override public void delete(T t) { this.getHibernateTemplate().delete(t); } @Override public void SaveOrUpdate(T t) { this.getHibernateTemplate().saveOrUpdate(t); } @Override public List<T> findAll() { return this.getHibernateTemplate().find("from " + daoImplClass.getName()); } @Override public List<T> findAll(String condition, Object... params) { String hql = "from " + daoImplClass.getName() + " where 1=1 " + condition; return this.getHibernateTemplate().find(hql,params); } public List<T> findAll(DetachedCriteria detachedCriteria) { return this.getHibernateTemplate().findByCriteria(detachedCriteria); } @Override public List<T> findAllByPage(int startIndex, int pageSize) { String hql = "from " + daoImplClass.getName(); return this.getHibernateTemplate().execute(new PageHibernateCallBack(hql, startIndex, pageSize)); } @Override public int getTotalRecode() { List<Long> list = this.getHibernateTemplate().find("select count(*) from " + daoImplClass.getName()); return list.get(0).intValue(); } @Override public T findById(Serializable oid) { List<T> allT=this.getHibernateTemplate().find(" from "+daoImplClass.getName()+" where id=? ",oid); if(allT !=null && allT.size()==1){ return allT.get(0); } return null; } /** * 经过编写回调实现分页 */ class PageHibernateCallBack implements HibernateCallback<List<T>> { private String hql; //查询hql语句 private Object[] params; //对应实际参数 private int firstResult; //分页开始索引 private int maxResults; //分页每页显示个数 public PageHibernateCallBack(String hql, int firstResult, int maxResults ,Object... params) { super(); this.hql = hql; this.params = params; this.firstResult = firstResult; this.maxResults = maxResults; } @Override public List<T> doInHibernate(Session session) throws HibernateException, SQLException { // 1 建立query Query queryObject = session.createQuery(hql); // 2 封装参数 if (params != null) { for (int i = 0; i < params.length; i++) { queryObject.setParameter(i, params[i]); } } // 3 分页 if (firstResult >= 0) { queryObject.setFirstResult(firstResult); } if (maxResults > 0) { queryObject.setMaxResults(maxResults); } //4 查询全部 return queryObject.list(); } } }
接下来咱们就能够愉快的使用这些封装好的方法了app
例如咱们的员工信息管理模块中:框架
页面效果以下:
public interface LessontypeDao extends BaseDao<CrmLessontype>{ }
实现方法:
public class LessontypeDaoImpl extends BaseDaoImpl<CrmLessontype> implements LessontypeDao{ }
而后就是service进行处理:
public interface LessontypeService { PageBean<CrmLessontype> findAllPage(int pageNum,int pageSize); List<CrmLessontype> findAll(); CrmLessontype findById(String lessonTypeId); void addOrEditLessontype(CrmLessontype model); }
实现方法:
这里使用了一个分页查询的功能。
public class LessontypeServiceImpl implements LessontypeService { private LessontypeDao lessontypeDao; public void setLessontypeDao(LessontypeDao lessontypeDao) { this.lessontypeDao = lessontypeDao; } @Override public PageBean<CrmLessontype> findAllPage(int pageNum, int pageSize) { //1 查询数据库,得到总记录数 int totalRecord = lessontypeDao.getTotalRecode(); //2 分页数据 PageBean<CrmLessontype> pageBean = new PageBean<CrmLessontype>(pageNum, pageSize, totalRecord); //3 查询分页结果 pageBean.setData(lessontypeDao.findAllByPage(pageBean.getStartIndex(), pageSize)); return pageBean; } @Override public List<CrmLessontype> findAll() { return lessontypeDao.findAll(); } @Override public CrmLessontype findById(String lessonTypeId) { return lessontypeDao.findById(lessonTypeId); } @Override public void addOrEditLessontype(CrmLessontype model) { lessontypeDao.SaveOrUpdate(model); } }
接下来就须要把咱们的service交由spring来管理了,在applicationContext-lessontype.xml中
<bean id="lessontypeService" class="cn.tf.lessontype.service.impl.LessontypeServiceImpl"> <property name="lessontypeDao" ref="lessontypeDao"></property> </bean> <bean id="lessontypeDao" class="cn.tf.lessontype.dao.impl.LessontypeDaoImpl"> <property name="sessionFactory" ref="sessionFactory"></property> </bean>
而后咱们能够看到前台页面是:
<table width="97%" border="1" > <tr class="henglan" style="font-weight:bold;"> <td width="14%" align="center">名称</td> <td width="33%" align="center">简介</td> <td width="13%" align="center">总学时</td> <td width="18%" align="center">收费标准</td> <td width="11%" align="center">编辑</td> </tr> <s:iterator value="pageBean.data"> <tr class="tabtd1"> <td align="center"><s:property value="lessonName"/> </td> <td align="center"><s:property value="remark"/></td> <td align="center"><s:property value="total"/></td> <td align="center"><s:property value="lessonCost"/></td> <td width="11%" align="center"> <s:a namespace="/" action="lessontypeAction_addOrEditUI"> <s:param name="lessonTypeId" value="lessonTypeId"></s:param> <img src="${pageContext.request.contextPath}/images/button/modify.gif" class="img"/> </s:a> </td> </tr> </s:iterator> </table> <table border="0" cellspacing="0" cellpadding="0" align="center"> <tr> <td align="right"> <p:page url="${pageContext.request.contextPath}/lessontypeAction_findAll" data="${pageBean}" /> </td> </tr> </table>
因此这里咱们可使用的action。因此咱们须要在struts中进行配置:
<package name="lessontype" namespace="/" extends="common"> <action name="lessontypeAction_*" class="cn.tf.lessontype.action.LessontypeAction" method="{1}"> <result name="findAll" >/WEB-INF/pages/lessontype/listLessontype.jsp</result> <result name="addOrEditUI">/WEB-INF/pages/lessontype/addOrEditCourseType.jsp</result> <result name="addOrEdit" type="redirectAction">lessontypeAction_findAll</result> </action> </package>
action要跳转的类,说到这里,咱们还能够对action进行一些封装,毕竟使用action也是很是多的:
public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{ public BaseAction(){ try { ParameterizedType parameterizedType=(ParameterizedType) this.getClass().getGenericSuperclass(); Class<T> crmClass=(Class<T>) parameterizedType.getActualTypeArguments()[0]; t=crmClass.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } private T t; @Override public T getModel() { return t; } //注入使用到service //分页数据 private int pageNum; private int pageSize=2; public void setPageNum(int pageNum) { this.pageNum = pageNum; } //简化值栈操做 public void set(String key,Object o){ ActionContext.getContext().getValueStack().set(key,o); } public void push(Object o){ ActionContext.getContext().getValueStack().push(o); } public void put(String key,Object value){ ActionContext.getContext().put(key,value); } public void putSession(String key,Object value){ ActionContext.getContext().getSession().put(key, value); } }
而后咱们就来愉快的引用一下吧:
public class LessontypeAction extends BaseAction<CrmLessontype> { private CrmLessontype crmLessontype = new CrmLessontype(); @Override public CrmLessontype getModel() { return this.crmLessontype; } //2 service private LessontypeService lessontypeService; public void setLessontypeService(LessontypeService lessontypeService) { this.lessontypeService = lessontypeService; } //3 分页数据 private int pageNum; public void setPageNum(int pageNum) { this.pageNum = pageNum; } private int pageSize = 5 ; /** * 查询全部--分页 * @return */ public String findAll(){ PageBean<CrmLessontype> pageBean = this.lessontypeService.findAllPage(pageNum, pageSize); this.set("pageBean", pageBean); return "findAll"; } //打开添加或修改页面 public String addOrEditUI(){ CrmLessontype findLessontype=this.lessontypeService.findById(this.getModel().getLessonTypeId()); this.push(findLessontype); return "addOrEditUI"; } public String addOrEdit(){ this.lessontypeService.addOrEditLessontype(this.getModel()); return "addOrEdit"; } }
这样的话整个开发流程就完成了。接下来的就是不少相似的操做了。总体来讲是很简单的,固然,虽然简单仍是须要花费时间的哈!
例如我在修改员工信息整理的时候,就遇到了这个密码更新的问题。
我最开始是在这里把密码显示出来的,而后一更新,坏了,把加密后的数据又加密一次存进去了,由于我这里这个密码是经过md5加密处理了,因此回显出来也没有多大的意义,毕竟md5密码不能解密!既然不显示那么我密码确定是没有修改吧,可是在hibernate中,使用SaveOrUpdate来更新,而后忽然,啪的一下密码变成空了,我想坏了,不能这么干,由于若是这里不显示的话,这个员工的实体仍是每一个选项都要赋值的,因此我在最后面用了另一个方法:使用bulkUpdate来操做就能够了。
这个地方的话我和修改用户密码一块儿组合起来写了,因此用了一个if ..else..
@Override public void update(CrmStaff crmStaff) { String staffCode=crmStaff.getStaffCode(); if(staffCode!=null){ //修改密码 String loginPwd=crmStaff.getLoginPwd(); String staffId=crmStaff.getStaffId(); String hql1="update CrmStaff c set c.loginPwd=? where c.staffId=?"; this.getHibernateTemplate().bulkUpdate(hql1,loginPwd,staffId); }else{ String loginName=crmStaff.getLoginName(); String staffName=crmStaff.getStaffName(); String gender=crmStaff.getGender(); String postId=crmStaff.getCrmPost().getPostId(); Date onDutyDate=crmStaff.getOnDutyDate(); String staffId=crmStaff.getStaffId(); String hql="update CrmStaff c set c.loginName=? ,c.staffName=?,c.gender=?,c.crmPost.postId=?, c.onDutyDate=? where c.staffId=? "; this.getHibernateTemplate().bulkUpdate(hql, loginName,staffName,gender,postId,onDutyDate,staffId); } }
哎,虽然麻烦了一些,好歹功能最后被我实现了,要是哪位小伙伴有更好的想法,欢迎留言交流哦!但愿更懂的小伙伴们能够不吝赐教哦!项目源码我已经放到个人github中啦!
项目总结:这是一个很是好的SSH框架的项目,很是简单,整个过程更多的是须要细心和耐心,对于一些类似的功能若是想要复制黏贴的话千万要记得修改相应的地方,否则的话...就会”蹦,傻卡拉卡“ 系统就炸掉了,哈哈!还有就是经过js来打开'window.showModalDialog弹出模态窗口的时候貌似只兼容火狐浏览器。至于解决窗口的嵌套咱们可使用
if(top.location!= self.location){
top.location= self.location; //赋值成功以后,将立刻跳转
}
来解决。好了,今天的项目分享就到这里啦!明天又是新的一天啦!