项目分享:通过使用SSH框架的公司-学员关系管理系统(CRM)
 ----------------------------------------------------------------------------------------------
[版權(quán)申明:本文系作者原創(chuàng),轉(zhuǎn)載請注明出處]?
文章出處:http://blog.csdn.net/sdksdk0/article/details/52506671
作者:朱培 ? ? ?ID:sdksdk0 ? ? ?郵箱: zhupei@tianfang1314.cn ??
--------------------------------------------------------------------------------------------
最近在做的是一個通過Struts2、Hibernate、spring框架整合做的一個CRM系統(tǒng),整體開發(fā)比較簡單,就是細(xì)節(jié)的地方處理還是要花費(fèi)一定的功夫,我主要負(fù)責(zé)的是人事管理(包括部門管理、職務(wù)管理、員工基本信息管理)、教學(xué)管理(班級管理、課程類別管理)、系統(tǒng)設(shè)置(修改密碼、登錄、退出)。整體功能比較簡單,適合一般性開發(fā)。涉及的技術(shù)要點(diǎn)就是通過HQL來進(jìn)行數(shù)據(jù)的增刪改查、部門-職務(wù)級聯(lián)、分頁、通過struts進(jìn)行文件上傳下載等。只不過有個別的地方還是花費(fèi)了幾個小時。
?
首先是對整體的開發(fā)環(huán)境的搭建:
通過分模塊開發(fā)來處理,框架的使用時分為了struts和spring,不同的模塊的struts的命名也不同,spring也一樣,同時hibernate放到相應(yīng)的實(shí)體bean的文件夾下面。
?
?
?
在開發(fā)中我們都有很多地方用到了Dao和DaoImpl,所以我們可以將其抽取出來,作為一個基本的Dao,然后讓其他用到的類去集成這個基礎(chǔ)的dao即可,這樣大大減少了開發(fā)的代碼。
在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);//分頁的總記錄數(shù)public int getTotalRecode();//查找T findById(Serializable serializable);}
然后我們需要一個DaoImpl去實(shí)現(xiàn)這個公共dao的方法:
?
?
?
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{private Class daoImplClass;public BaseDaoImpl() {//運(yùn)行時,通過反射獲得 泛型信息的實(shí)際內(nèi)容/// * 運(yùn)行時,this表示當(dāng)前運(yùn)行類(及子類的實(shí)例對象)//1 獲得被參數(shù)化類型 ,例如:BaseDaoImpl<CrmPost>ParameterizedType paramType = (ParameterizedType) this.getClass().getGenericSuperclass();//2 獲得實(shí)例參數(shù)daoImplClass = (Class) paramType.getActualTypeArguments()[0];}@Overridepublic void save(T t) {this.getHibernateTemplate().save(t);}@Overridepublic void update(T t) {this.getHibernateTemplate().update(t);}@Overridepublic void delete(T t) {this.getHibernateTemplate().delete(t);}@Overridepublic void SaveOrUpdate(T t) {this.getHibernateTemplate().saveOrUpdate(t);}@Overridepublic List<T> findAll() {return this.getHibernateTemplate().find("from " + daoImplClass.getName());}@Overridepublic 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);}@Overridepublic List<T> findAllByPage(int startIndex, int pageSize) {String hql = "from " + daoImplClass.getName();return this.getHibernateTemplate().execute(new PageHibernateCallBack(hql, startIndex, pageSize));}@Overridepublic int getTotalRecode() {List<Long> list = this.getHibernateTemplate().find("select count(*) from " + daoImplClass.getName());return list.get(0).intValue();}@Overridepublic 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;}/*** 通過編寫回調(diào)實(shí)現(xiàn)分頁*/class PageHibernateCallBack implements HibernateCallback<List<T>> {private String hql; //查詢hql語句private Object[] params; //對應(yīng)實(shí)際參數(shù)private int firstResult; //分頁開始索引private int maxResults; //分頁每頁顯示個數(shù)public PageHibernateCallBack(String hql, int firstResult, int maxResults ,Object... params) {super();this.hql = hql;this.params = params;this.firstResult = firstResult;this.maxResults = maxResults;}@Overridepublic List<T> doInHibernate(Session session) throws HibernateException,SQLException {// 1 創(chuàng)建queryQuery queryObject = session.createQuery(hql);// 2 封裝參數(shù)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();}}}?
接下來我們就可以愉快的使用這些封裝好的方法了
?
例如我們的員工信息管理模塊中:
頁面效果如下:
?
?
public interface LessontypeDao extends BaseDao<CrmLessontype>{}
實(shí)現(xiàn)方法:
?
?
public class LessontypeDaoImpl extends BaseDaoImpl<CrmLessontype> implements LessontypeDao{}?
然后就是service進(jìn)行處理:
?
public interface LessontypeService {PageBean<CrmLessontype> findAllPage(int pageNum,int pageSize);List<CrmLessontype> findAll();CrmLessontype findById(String lessonTypeId);void addOrEditLessontype(CrmLessontype model);}?
實(shí)現(xiàn)方法:
這里使用了一個分頁查詢的功能。
?
public class LessontypeServiceImpl implements LessontypeService {private LessontypeDao lessontypeDao;public void setLessontypeDao(LessontypeDao lessontypeDao) {this.lessontypeDao = lessontypeDao;}@Overridepublic PageBean<CrmLessontype> findAllPage(int pageNum, int pageSize) {//1 查詢數(shù)據(jù)庫,獲得總記錄數(shù)int totalRecord = lessontypeDao.getTotalRecode();//2 分頁數(shù)據(jù)PageBean<CrmLessontype> pageBean = new PageBean<CrmLessontype>(pageNum, pageSize, totalRecord);//3 查詢分頁結(jié)果pageBean.setData(lessontypeDao.findAllByPage(pageBean.getStartIndex(), pageSize));return pageBean;}@Overridepublic List<CrmLessontype> findAll() {return lessontypeDao.findAll();}@Overridepublic CrmLessontype findById(String lessonTypeId) {return lessontypeDao.findById(lessonTypeId);}@Overridepublic 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">總學(xué)時</td><td width="18%" align="center">收費(fèi)標(biāo)準(zhǔn)</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中進(jìn)行配置:
?
?
<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要跳轉(zhuǎn)的類,說到這里,我們還可以對action進(jìn)行一些封裝,畢竟使用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;@Overridepublic T getModel() {return t;}//注入使用到service//分頁數(shù)據(jù)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();@Overridepublic CrmLessontype getModel() {return this.crmLessontype;}//2 serviceprivate LessontypeService lessontypeService;public void setLessontypeService(LessontypeService lessontypeService) {this.lessontypeService = lessontypeService;}//3 分頁數(shù)據(jù)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";}}?
這樣的話整個開發(fā)流程就完成了。接下來的就是很多類似的操作了。整體來說是很簡單的,當(dāng)然,雖然簡單還是需要花費(fèi)時間的哈!
例如我在修改員工信息整理的時候,就遇到了這個密碼更新的問題。
?
我最開始是在這里把密碼顯示出來的,然后一更新,壞了,把加密后的數(shù)據(jù)又加密一次存進(jìn)去了,因?yàn)槲疫@里這個密碼是通過md5加密處理了,所以回顯出來也沒有多大的意義,畢竟md5密碼不能解密!既然不顯示那么我密碼肯定是沒有修改吧,但是在hibernate中,使用SaveOrUpdate來更新,然后突然,啪的一下密碼變成空了,我想壞了,不能這么干,因?yàn)槿绻@里不顯示的話,這個員工的實(shí)體還是每個選項(xiàng)都要賦值的,所以我在最后面用了另外一個方法:使用bulkUpdate來操作就可以了。
這個地方的話我和修改用戶密碼一起組合起來寫了,所以用了一個if ?..else..
?
@Overridepublic 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);}}
哎,雖然麻煩了一些,好歹功能最后被我實(shí)現(xiàn)了,要是哪位小伙伴有更好的想法,歡迎留言交流哦!希望更懂的小伙伴們可以不吝賜教哦!項(xiàng)目源碼我已經(jīng)放到我的github中啦!
?
?
項(xiàng)目總結(jié):這是一個非常好的SSH框架的項(xiàng)目,非常簡單,整個過程更多的是需要細(xì)心和耐心,對于一些相似的功能如果想要復(fù)制黏貼的話千萬要記得修改相應(yīng)的地方,不然的話...就會”蹦,傻卡拉卡“ 系統(tǒng)就炸掉了,哈哈!還有就是通過js來打開'window.showModalDialog彈出模態(tài)窗口的時候貌似只兼容火狐瀏覽器。至于解決窗口的嵌套我們可以使用
?
if(top.location!= self.location){
????????? top.location= self.location;? //賦值成功之后,將馬上跳轉(zhuǎn)
????? }
來解決。好了,今天的項(xiàng)目分享就到這里啦!明天又是新的一天啦!
?
?
項(xiàng)目源碼:https://github.com/sdksdk0/CRM
?
轉(zhuǎn)載于:https://www.cnblogs.com/sdksdk0/p/6060026.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的项目分享:通过使用SSH框架的公司-学员关系管理系统(CRM)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: ibus无法出现选择框如何解决
 - 下一篇: JS 内置对象 String对象