----------------------------------------------------------------------------------------------
[版權申明:本文系做者原創,轉載請註明出處]
文章出處: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; //賦值成功以後,將立刻跳轉
}
來解決。好了,今天的項目分享就到這裏啦!明天又是新的一天啦!