1. 程式人生 > >使用SSH框架來完成CRM系統流程總結

使用SSH框架來完成CRM系統流程總結

   今天是國慶節的第四天,也是中間一天。沒有捨得出去玩,因為我覺得像這樣的大塊時間來的不容易,不用去上課,沒有人干擾,用來學習自己喜歡的東西挺幸福的。我用將近一個星期的時間學習別人的CRM系統。自己也是剛學完SSH框架,用SSH框架來實現CRM系統。過程中犯下過許多錯誤。我把一些常遇到的錯誤已經發過部落格。今天,我不想再再往下走,去學新的東西。我想停下來吸收吸收SSH中的東西。 

    關於的自己的CRM系統,我這次先不放程式碼,我需要完善一下。這次先來總結專案流程

    話說SSH:前邊已經提到過使用的框架就是SSH(spring+struts2+hibernate),順帶著稍微總結一下這三個框架吧,框架本來就是軟體的半成品,初學者需要先掌握使用方法,其實最多的是配置的問題(配置有使用xml檔案的形式,也可以採用註解開發的模式,各有好處,xml便於維護,註解用起來速度更快。一定不要把兩個搞混了)。我覺得學習框架就像學習開車,一上來應該先學會開車,因為先學會開車了才能夠給自己帶來方便,至於車的構造,不應該是初學者去搞的(這裡指框架的底層,更深層的是原始碼,但是具體流程還是要掌握一下的,只有掌握具體的流程,在調錯的時候才能一針見血),等能夠使用熟練了以後,就應該挖挖底層了,因為不想造車的司機不是好司機,如果作為初學者,不懂底層可以原諒,如果使用很長時間還不瞭解底層,就有點說不過去了。就像開了十年車,不知道車的構造,車出了問題,不知道哪裡出的問題,這顯得多麼荒謬...

   分說:struts2,就是基於mvc設計模式的web應用框架,web層的框架,一般都是基於前端控制器模型來設計的。

   分說:hibernate,就是一個持久層的ORM框架。(ORM)(Object relational Mapping)物件關係對映。目的就是用來建立實體類和資料庫中表的對映關係。達到操作物件就能操作資料庫的目的。(這裡都稍微總結一下吧,有點小跑題,不要慌,麵包會有的..)

  分說:spring,EE開發的一站式框架。也正是spring將三個框架連線在一起,一起在專案中發力。spring的好處有:輕量,控制反轉,面向切面,可以很方便的對程式進行擴充套件,方便解耦,AOP的程式設計支援,宣告式事務支援,方便程式的測試,方便整合各種優秀的框架,降低javaEE開發API的難度。解耦合的思想很重要,後期方便維護和擴充套件。框架各管一層,spring又將框架連線起來。

   總結完了三個框架,下邊來麵包吧:

    不管是用什麼框架,建立專案搭建必須的環境是第一步,我們需要引入jar包,這是為的專案能跑起來需需要的所有的jar包

antlr-2.7.7.jar asm-3.3.jar asm-commons-3.3.jar asm-tree-3.3.jar c3p0-0.9.2.1.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.apache.commons.logging-1.1.1.jar com.springsource.org.apache.log4j-1.2.15.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar commons-beanutils-1.8.3.jar commons-collections-3.2.1.jar commons-fileupload-1.3.1.jar commons-io-2.2.jar commons-lang-2.5.jar commons-lang3-3.2.jar commons-logging-1.1.1.jar dom4j-1.6.1.jar ezmorph-1.0.6.jar freemarker-2.3.22.jar geronimo-jta_1.1_spec-1.1.1.jar hibernate-c3p0-5.0.7.Final.jar hibernate-commons-annotations-5.0.1.Final.jar hibernate-core-5.0.7.Final.jar hibernate-jpa-2.1-api-1.0.0.Final.jar jandex-2.0.0.Final.jar javassist-3.18.1-GA.jar jboss-logging-3.3.0.Final.jar json-lib-2.4-jdk15.jar jstl.jar log4j-1.2.16.jar log4j-api-2.2.jar log4j-core-2.2.jar mchange-commons-java-0.2.3.4.jar mysql-connector-java-5.1.7-bin.jar ognl-3.0.6.jar slf4j-api-1.6.1.jar slf4j-log4j12-1.7.2.jar spring-aop-4.2.4.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar spring-beans-4.2.4.RELEASE.jar spring-context-4.2.4.RELEASE.jar spring-core-4.2.4.RELEASE.jar spring-expression-4.2.4.RELEASE.jar spring-jdbc-4.2.4.RELEASE.jar spring-orm-4.2.4.RELEASE.jar spring-test-4.2.4.RELEASE.jar spring-tx-4.2.4.RELEASE.jar spring-web-4.2.4.RELEASE.jar standard.jar struts2-core-2.3.24.jar struts2-spring-plugin-2.3.24.jar xwork-core-2.3.24.jar

    匯入完了jar包以後,還需要引入配置檔案,

  1. 建立專案,環境的搭建:匯入jar包
  2. 引入配置檔案
    1. Struts2的框架需要修改的是:
      • Web.xml

<!-- struts2的核心過濾器 -->

<filter> 

<filter-name>struts</filter-name>

<filter-class>org.apache.struts2.dispatcher.ng.filter.Strut sPrepareAndExecuteFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>struts</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

      • Struts.xml
    • spring的框架
      • Jdbc.properties
      • log4j.properties
      • applicationContext.xml
      • web.xml
    • Hibernate的框架
      • Hibernate.cfg.xml ---現在交給spring去管理了
  1. 建立相關的包結構

   關於包的結構,與類的建立有需要注意的點,我們最好是採用介面+實現類的方式,這樣也方便事務的管理。

     如果做功能比較齊全一點的專案,就像我做的CRM管理系統,

這裡說一下封裝繼承的用法,和優點   (體現在dao層) 

 有幾個模組的程式碼有大量的重複,比方說客戶管理模組,聯絡人管理模組,拜訪管理模組,都需要分頁,都需要進行URCD操作,在dao層有很大一部分程式碼是重複的,就是你有我也有的地方,對於這個地方,我們就可以使用泛型,抽取出來公共的程式碼

實現步驟就是寫一個公共的接口出來,其他模組的介面可以來繼承這個介面,由於繼承的優點所在,各個模組相同的部分給父親,然後每個模組又繼承父親,父親有的孩子都可以共享,這樣就可以實現抽取程式碼,簡化程式碼的目的。

比如我crm專案的抽取出來的通用介面

package com.xing.crm.dao;

import java.io.Serializable; import java.util.List;

import org.hibernate.criterion.DetachedCriteria;

/**  * 通用的Dao介面  * @author DELL  *  */ public interface BaseDao<T> {     //儲存的方法     public void save(T t);     //更新的方法     public void update(T t);     //刪除的方法     public void delete(T t);     //查詢一個的方法     public T findById(Serializable id);     //查詢所有的方法     public List<T> findAll();     //統計個數的方法     public Integer findCount(DetachedCriteria detachedCriteria);     //分頁查詢的方法     public List<T> findByPage(DetachedCriteria detachedCriteria,Integer begin, Integer pageSize); }

   BaseDao介面的實現類:(注意我的實現類繼承了hibernate的模板)

package com.xing.crm.dao.impl;

import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List;

import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Projections; import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.xing.crm.dao.BaseDao;

/**  * 通用的Dao的實現類  *   * @author DELL  *  */ public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {

    // 提供構造方法,在構造方法中傳入具體型別的class     private Class clazz;

    /**      * 不想讓子類中有帶引數的構造方法,就必須在父類中提供無參構造,在無參構造中獲取具體型別的Class 具體型別的Class是引數型別中的實際型別引數。      *       * @param clazz      */     public BaseDaoImpl() {         // 反射:第一步獲得class         Class clazz = this.getClass();// 獲取正在被呼叫的類的Class         // 獲取引數化型別         Type type = clazz.getGenericSuperclass();// 如果是CustomerImpl繼承的BaseDaoImpl就獲得BaseDaoImpl<Customer>         // 將type強轉換成引數化型別:         ParameterizedType pType=(ParameterizedType) type;         //通過引數化型別的方法獲得實際型別的引數         Type[] types= pType.getActualTypeArguments();//獲得的引數陣列         //因為我們只有一個引數,所以只需要獲得第一個引數即可         this.clazz=(Class) types[0];//最後一步獲得到實際型別引數Customer     }

    @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 T findById(Serializable id) {         return (T) this.getHibernateTemplate().get(clazz, id);     }

    // 查詢所有的方法     @Override     public List<T> findAll() {         return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName());     }

    // 統計個數的方法     @Override     public Integer findCount(DetachedCriteria detachedCriteria) {         // 設定統計個數的條件         detachedCriteria.setProjection(Projections.rowCount());         List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);         if (list.size() > 0) {             return list.get(0).intValue();         }         return null;     }

    // 分頁查詢的方法     @Override     public List<T> findByPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize) {         detachedCriteria.setProjection(null);         return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, begin, pageSize);     }

}

   接下來再寫模組的dao層介面的時候,介面需要繼承一下BaseDao介面。

接下來再寫模組的dao層的實現類,注意仍然是繼承BaseDaoImpl,就是繼承通用介面的實現類

這樣一來,好處就體現出來了,因為在我的模組實現類中一行程式碼都不需要寫了。如果不這樣寫的話,有十個模組,同樣的程式碼就需要寫十遍,因為每一個模組的dao層的實現類都要這樣來寫。程式碼量直接就體現出來了。這正是體現封裝和繼承的優點。

需要注意的是,我抽取出來的是模組共同的程式碼,並不是說這樣一來,dao層的實現類就真的一行程式碼都不需要了,如果某個模組有特殊的需求,那麼就需要在dao層的實現類中單獨來寫了。

  接下來模組的service正常建立就可以

  但是action類要繼承ActionSupport  並且實現ModelDriven介面