SSH架構用法,及作用(在一位菜鳥使用半年之後歸納的總結),ssh半年之後
SSH架構從接觸以來改變了我對代碼的編寫方式,從最初開始學習到勉強掌握可以說得到不少心得,以下內容出自java初學者對SSH的理解,如有不對的地方還請諒解,希望可以提出來與我交流,謝謝!
SSH顧名思義,struts2,spring,hibernate三大架構組成的從服務端接收請求到資料庫調用並返回的一種流程(個人觀點,詞彙也並不準確)
那麼如何去使用,又有那些有點缺點呢?
在使用這個架構之前我一直都是使用servlet ,那麼servlet是什麼呢?(下面是我從百度上拷貝過來的servlet生命週期解釋)
- 用戶端請求該 Servlet;
- 載入 Servlet 類到記憶體;
- 執行個體化並調用init()方法初始化該 Servlet;
- service()(根據要求方法不同調用doGet() 或者 doPost(),此外還有doHead()、doPut()、doTrace()、doDelete()、doOptions()、destroy())。
- 載入和執行個體化 Servlet。這項操作一般是動態執行的。然而,Server 通常會提供一個管理的選項,用於在 Server 啟動時強制裝載和初始化特定的 Servlet。
Server 建立一個 Servlet的執行個體第一個用戶端的請求到達 ServerServer 調用 Servlet 的 init() 方法(可配置為 Server 建立 Servlet 執行個體時調用,在 web.xml 中 <servlet> 標籤下配置 <load-on-startup> 標籤,配置的值為整型,值越小 Servlet 的啟動優先順序越高)一個用戶端的請求到達 ServerServer 建立一個請求對象,處理用戶端請求Server 建立一個響應對象,響應用戶端請求Server 啟用 Servlet 的 service() 方法,傳遞請求和響應對象作為參數service() 方法獲得關於請求對象的資訊,處理請求,訪問其他資源,獲得需要的資訊service() 方法使用響應對象的方法,將響應傳回Server,最終到達用戶端。service()方法可能啟用其它方法以處理請求,如 doGet() 或 doPost() 或程式員自己開發的新的方法。對於更多的用戶端請求,Server 建立新的請求和響應對象,仍然啟用此 Servlet 的 service() 方法,將這兩個對象作為參數傳遞給它。如此重複以上的迴圈,但無需再次調用 init() 方法。一般 Servlet 只初始化一次(只有一個對象),當 Server 不再需要 Servlet 時(一般當 Server 關閉時),Server 調用 Servlet 的 destroy() 方法。 當時用servlet的時候覺得蠻好用,自從學會ssh就知道,SSH起初配置的東西偏多,比較麻煩,但是項目基礎搭建好了只好就特別方便,比如hibernate連結資料庫在這裡我們需要用到一個BaceDao,用來把dao層的方法統一的抽象出來方便調用,下面是我們項目小組自己編寫的抽象dao層:package com.dazhi.core; import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired; import java.io.Serializable;import java.lang.reflect.ParameterizedType;import java.util.List; public abstract class AbstractBaseDao<T> implements BaseDao<T> { Class<T> tClass;String className; public SessionFactory sessionFactory;@Autowiredpublic void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}public AbstractBaseDao(){ParameterizedType parameterizedType = (ParameterizedType)this.getClass().getGenericSuperclass();tClass = (Class<T>)parameterizedType.getActualTypeArguments()[0];this.className = tClass.getSimpleName();}@Overridepublic Serializable save(T model) {Session session = sessionFactory.getCurrentSession();Serializable serializable = session.save(model);return serializable;} @Overridepublic int save(List<T> lists) {return 0;} @Overridepublic int saveOrUpdate(List<T> lists) {for(T l:lists){sessionFactory.getCurrentSession().saveOrUpdate(l);}return 0;} @Overridepublic void delete(T model) {sessionFactory.getCurrentSession().delete(model);} /*** 大量刪除* @param ids*/@Overridepublic void deleteList(String ids) {String hql = "DELETE FROM " + className + " AS A WHERE A.id IN ("+ids+")";Query query = sessionFactory.getCurrentSession().createQuery(hql);query.executeUpdate();} @Overridepublic void update(T model) {sessionFactory.getCurrentSession().update(model);} // @Transactional@Overridepublic List<T> findList() {return sessionFactory.getCurrentSession().createQuery("FROM "+className).list();} @Overridepublic List<T> findList(String property, Serializable value) {List<Query> query = sessionFactory.getCurrentSession().createQuery("FROM " + className + " AS B WHERE B." + property + "=" + value).list();return (List<T>) query;} @Overridepublic T find(Serializable id) {return (T) sessionFactory.getCurrentSession().get(tClass,id);} @Overridepublic T find(String property, Serializable value) {Query query = sessionFactory.getCurrentSession().createQuery("FROM " + className + " AS B WHERE B." + property + "=:v");query.setParameter("v",value).uniqueResult();return (T)query.uniqueResult();} @Overridepublic List<T> queryForPage(int offset, int length) {Query q = sessionFactory.getCurrentSession().createQuery("FROM "+className);q.setFirstResult(offset);q.setMaxResults(length);return q.list();}@Overridepublic List<T> queryForPage(String hql, int offset, int length) {Query q = sessionFactory.getCurrentSession().createQuery(hql);q.setFirstResult(offset);q.setMaxResults(length);return q.list();}@Overridepublic Integer getCount() {// sessionFactorQuery q = sessionFactory.getCurrentSession().createQuery("SELECT COUNT (*) FROM "+className);return Integer.parseInt(q.list().get(0).toString());}@Overridepublic Integer getCount(String hql) {Query q = sessionFactory.getCurrentSession().createQuery(hql);return Integer.parseInt(q.list().get(0).toString());}} 上面這些方法是增刪改查經常會用到的方法,於是我們把他抽象的寫出來,只要經過觀察就不難發現這些方法的用處了,當然這個方法也不是很完善。用這個的方法就是首先我們需要資料庫有一個表,之後我們也要對應的寫出bean類,每一個bean類都需要有與之對應的service和dao(service整合抽象service,dao要繼承抽象dao),同時我們需要配置hbm檔案,用來確定資料庫與表的關係,這個詳情可以參考hibernate的使用方式,關於hbm檔案的配置與使用,當然連結資料庫還需要配置applicationContext.xml這個檔案,這個檔案的作用就是連結資料庫的地址,使用者名稱,密碼,從這裡寫完一次之後只需要從web.xml中拿來調用就可以了,包括換個資料庫只需要建立一個applicationContext.xml2來代替它是不是方便的多,感覺到美滋滋呢?對了,還是從struts開始講起吧,其實一開始剛上手我也很懵逼,搞不懂到底怎麼用,不過現在我明白了一些,struts使用方式很簡單,首先我們需要先從web.xml中調用struts2來幫我們管理連結地址就好了,也就是說web.xml被struts2取代(只是某些用途上的取代,並不是完全的),下面是web.xml中的寫法
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Archetype Created Web Application</display-name>
//這裡的作用是配置連結資料庫的檔案,更改資料庫只需要applicationContext.xml配置在這裡就好了
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-teacher.xml,classpath:applicationContext-common.xml</param-value>
</context-param>
<filter >
<filter-name > HibernateOpenSession</filter-name >
<filter-class > org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class >
</filter >
<filter-mapping >
<filter-name > HibernateOpenSession</filter-name >
<url-pattern > /*</url-pattern >
</filter-mapping >
<!--<!– 分布式Session共用Filter –>-->
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
//在這裡打上一下代碼就可一讓struts2來幫我們管理連結請求了,是不是很簡單呢
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
然後我們就可以使用struts2了,當然別忘了去下載jar包,如果你使用maven來管理jar包的話
<!-- Struts-->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>${struts.version}</version>
</dependency>
就是這些打在pom檔案中,不知道maven是什麼的可以自己去百度,簡單的來說就是個jar包管理工具用起來方便的很,再也不用自己去找jar包了
之後我們需要一個struts.xml檔案
<action name="paper_*" class="com.dazhi.controller.PaperAction" method="{1}">
<result name="all">/paper/index.jsp</result>
<result name="add">/paper/add.jsp</result>
<result name="one">/paper/update.jsp</result>
<result name="delete">/paper/update.jsp</result>
</action>
就像這樣,如果你可以訪問paper_add.action去找到com.dazhi.controller.PaperAction這個檔案,訪問完會跳轉到這個頁面/paper/add.jsp
在PaperAction這個檔案中你只需要寫一個方法,方法名為add,如下
public String add(){
return "add";
}
這樣就可以實現頁面的跳轉了,之後我們可以調用service一層層去調用BaceDao中的方法,實現增刪改查,同時別忘了每個檔案需要加上spring註解!
把值返回到頁面上只需要ActionContext.getContext().put("對象名",對象名);之後從頁面上使用s標籤去擷取就可以了
這樣看來是不是很簡單呢?