本博文是我的經過對ssh框架的學習、理解還有一些見解而描述出來的,可能有不足之處,請你們諒解,但但願能幫助到你們!html
1、SSH三大框架的概述java
ssh爲 struts+spring+hibernate的一個集成框架,是目前較流行的一種Web應用程序開源框架。程序員
集成SSH框架的系統從職責上分爲四層:表示層、業務邏輯層、數據持久層和域模塊層(實體層),以幫助開發人員在短時間內搭建結構清晰、可複用性好、維護方便的Web應用程序。web
struts2: spring
一、什麼是struts2:sql
Struts2是一個基於MVC設計模式的Web應用框架,它本質上至關於一個servlet,在MVC設計模式中,Struts2做爲控制器(Controller)來創建模型與視圖的數據交互。Struts 2是Struts的下一代產品,是在 struts 1和WebWork的技術基礎上進行了合併的全新的Struts 2框架。其全新的Struts 2的體系結構與Struts 1的體系結構差異巨大。Struts 2以WebWork爲核心,採用攔截器的機制來處理用戶的請求,這樣的設計也使得業務邏輯控制器可以與ServletAPI徹底脫離開,因此Struts 2能夠理解爲WebWork的更新產品。雖然從Struts 1到Struts 2有着太大的變化,可是相對於WebWork,Struts 2的變化很小。數據庫
二、struts2框架的運行結構:apache
解析:客戶端發送請求(HttpServletRequest)到服務器,服務器接收到請求就先進入web.xml配置文件看看有沒有配置過濾器,發現有struts2的過濾器,而後就找到struts.xml配置文件,struts.xml配置文件裏有定義一個action,而後就去找到類名叫IndexAction這個類(此action類必須是繼承ActionSupport接口),而且實現了execute()方法,返回一個字符串爲"success"給struts.xml配置文件,struts.xml配置文件的action會默認調用IndexAction類的execute()方法,result接收到了返回的字符串,而後查找結果字符串對應的(Result),result就會調用你指定的jsp頁面將結果呈現,最後響應回給客戶端。編程
spring:設計模式
一、什麼是spring?
Spring是一個輕量級控制反轉(IoC)和麪向切面(AOP)的容器框架。
二、spring的流程圖:
解析:上圖是在struts結構圖的基礎上加入了spring流程圖,在web.xml配置文件中加入了spring的監聽器,在struts.xml配置文件中添加「<constant name="struts.objectFactory" value="spring" />」是告知Struts2運行時使用Spring來建立對象,spring在其中主要作的就是注入實例,將全部須要類的實例都由spring管理。
hibernate:
一、什麼是hibernate?
Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了很是輕量級的對象封裝,它將POJO與數據庫表創建映射關係,是一個全自動的orm框架,hibernate能夠自動生成SQL語句,自動執行,使得Java程序員能夠爲所欲爲的使用對象編程思惟來操縱數據庫。 Hibernate能夠應用在任何使用JDBC的場合,既能夠在Java的客戶端程序使用,也能夠在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate能夠在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。
二、hibernate的核心構成和執行流程圖:
三、爲何使用Hibernate?
1). 對JDBC訪問數據庫的代碼作了封裝,大大簡化了數據訪問層繁瑣的重複性代碼。
2)、Hibernate是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工做,將軟件開發人員從大量相同的數據持久層相關編程工做中解放出來,使開發更對象化了。
3)、移植性好,支持各類數據庫,若是換個數據庫只要在配置文件中變換配置就能夠了,不用改變hibernate代碼。
4)、支持透明持久化,由於hibernate操做的是純粹的(pojo)java類,沒有實現任何接口,沒有侵入性。因此說它是一個輕量級框架。
2、搭建一個完整的SSH框架項目。
注意事項:
一、本文提綱:本文經過一個將全部圖書借記卡信息查詢出來並顯示到JSP頁面的項目實例講解SSH的整合。建立Struts項目,整合Hibernate,整合Spring。
二、僅是建立SSH項目,對於其餘的擴展例如Struts的國際化,Hibernate的緩存優化,Spring的AOP等,本博文涉及不到。想學習更多的東西請搜索其餘博文。
三、本項目的搭建環境:
Windows 8-64位,Eclipse(開發工具),jdk1.8.0_91,Tomcat 8.0,struts-2.3.30-apps,spring-framework-4.2.2.RELEASE,hibernate-release-5.2.2.Final,sql sever2008.
第一步:在eclipse(開發工具)裏建立web項目(項目名稱:ssh),並生成web.xml文件。
第二步:導入本次項目要使用到的jar包。
struts-2.3.30-apps官網下載地址:http://struts.apache.org/download.cgi#struts252
spring-framework-4.2.2.RELEASE官網下載地址:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-local/org/springframework/spring/4.2.2.RELEASE/spring-framework-4.2.2.RELEASE-dist.zip
hibernate-release-5.2.2.Final官網下載地址:http://hibernate.org/orm/
struts2(jar)包:
spring(jar)包:
注意:struts2-spring-plugin-2.3.30.jar,commons-logging-1.1.3.jar是struts的jar包
hibernate(jar)包:
sql sever數據庫(jar)包:
將全部的項目要用的jar包放入lib文件裏:
第三步:在配置文件web.xml配置一個struts2的過濾器和spring監聽器。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> 3 <display-name>ssh</display-name> 4 <welcome-file-list> 5 <welcome-file>index.action</welcome-file> 6 </welcome-file-list> 7 8 <!-- struts2的過濾器 --> 9 <filter> 10 <filter-name>struts2</filter-name> 11 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 12 </filter> 13 14 <filter-mapping> 15 <filter-name>struts2</filter-name> 16 <url-pattern>/*</url-pattern> 17 </filter-mapping> 18 19 20 <!-- spring的監聽器配置開始 --> 21 <context-param> 22 <param-name>contextConfigLocation</param-name> 23 <param-value>classpath:applicationContext.xml</param-value> 24 </context-param> 25 <listener> 26 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 27 </listener> 28 </web-app>
第四步:在Java Resources下的src目錄下建立四個包(package)進行分層。
第五步:根據數據庫表的字段編寫BookCard(實體類)和BookCard.hbm.xml(映射文件)放到ssh.entity包裏。
BookCard(實體類):
1 package ssh.entity; 2 3 import java.math.BigDecimal; 4 import java.util.Date; 5 6 /* 7 * 跟數據庫表一致,做爲一個java對象 8 * 1個對象表明的是數據庫表中的一行記錄 9 * 1個屬性表明的是表中的一個字段 10 */ 11 public class BookCard { 12 private int cid ; 13 private String name; 14 private String sex ; 15 private Date cardDate; 16 private BigDecimal deposit; 17 18 //定義get()、set()方法 19 public int getCid() { 20 return cid; 21 } 22 public void setCid(int cid) { 23 this.cid = cid; 24 } 25 public String getName() { 26 return name; 27 } 28 public void setName(String name) { 29 this.name = name; 30 } 31 public String getSex() { 32 return sex; 33 } 34 public void setSex(String sex) { 35 this.sex = sex; 36 } 37 public Date getCardDate() { 38 return cardDate; 39 } 40 public void setCardDate(Date cardDate) { 41 this.cardDate = cardDate; 42 } 43 public BigDecimal getDeposit() { 44 return deposit; 45 } 46 public void setDeposit(BigDecimal deposit) { 47 this.deposit = deposit; 48 } 49 50 }
BookCard.hbm.xml(映射文件):
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping> 7 <class name="ssh.entity.BookCard" table="BookCard"> 8 <!-- 卡號 --> 9 <id name="cid" column="cid"> 10 <generator class="native"></generator> 11 </id> 12 <!-- 姓名 --> 13 <property name="name" column="name"></property> 14 <!-- 性別 --> 15 <property name="sex" column="sex"></property> 16 <!-- 辦卡日期 --> 17 <property name="cardDate" column="cardDate"></property> 18 <!-- 押金 --> 19 <property name="deposit" column="deposit"></property> 20 </class> 21 </hibernate-mapping>
第六步:在ssh.service包裏編寫IndexService(接口類)和IndexServiceImpl(實現類)。
IndexService(接口類):
1 package ssh.service; 2 3 import java.util.List; 4 5 import ssh.dao.IndexDao; 6 import ssh.entity.BookCard; 7 8 //建立一個IndexService接口類 9 public interface IndexService { 10 11 12 public List<BookCard> getAllBookCard(); 13 14 }
IndexServiceImpl(實現類):
1 package ssh.service; 2 3 import java.util.List; 4 5 import ssh.dao.IndexDao; 6 import ssh.entity.BookCard; 7 8 //建立IndexServiceImpl(實現類)實現IndexService接口 9 public class IndexServiceImpl implements IndexService { 10 11 //dao實例使用注入方式 12 private IndexDao id; 13 //用於注入使用 14 public void setId(IndexDao id) { 15 this.id = id; 16 } 17 18 19 @Override 20 public List<BookCard> getAllBookCard() { 21 //本類應該編寫業務邏輯的代碼, 22 //但本例沒有業務邏輯,就不用寫。 23 24 //訪問數據庫的代碼,不會出如今service這一層 25 //交給dao來操做數據庫 26 List<BookCard> myBookCardList = id.getAllBookCard(); 27 28 //進行其它的業務邏輯操做,好比增長多一個選項,是否過時 29 //本例不須要 30 //.... 31 32 return myBookCardList; 33 } 34 35 }
第七步:在ssh.dao包裏編寫IndexDao(接口類)和IndexDaoImpl(實現類)。
IndexDao(接口類):
1 package ssh.dao; 2 3 import java.util.List; 4 5 import ssh.entity.BookCard; 6 7 //建立IndexDao(接口類) 8 public interface IndexDao { 9 10 public List<BookCard> getAllBookCard(); 11 12 }
IndexDaoImpl(實現類):
1 package ssh.dao; 2 3 import java.util.List; 4 5 import org.hibernate.Session; 6 import org.hibernate.SessionFactory; 7 import org.hibernate.query.Query; 8 9 import ssh.entity.BookCard; 10 11 //建立IndexDaoImpl(實現類)實現IndexDao接口 12 public class IndexDaoImpl implements IndexDao { 13 14 //在SSH的設計理念:要使用某個實例,那麼就定義聲明一個對象,而後 15 //給它添加set方法(用於spring注入進來) 16 //實現不要關注這個實例來自於那裏,以及怎麼建立,或者它是誰 17 private SessionFactory sessionFactory; 18 19 public void setSessionFactory(SessionFactory sessionFactory) { 20 this.sessionFactory = sessionFactory; 21 } 22 23 24 @Override 25 public List<BookCard> getAllBookCard() { 26 27 //sessionFactory這個實例能夠本身按常規的hibernate傳統寫法建立 28 //也能夠交給spring去託管 29 /* 30 Configuration cfg = new Configuration().configure(); 31 sessionFactory = cfg.buildSessionFactory();*/ 32 33 //獲取session 34 Session session = sessionFactory.openSession(); 35 36 //後面當使用JPA的時候,EntityManager 相似於 Session 37 Query query = session.createQuery("from BookCard"); 38 39 //將全部的數據查詢出來並放到List集合裏 40 List<BookCard> list = query.getResultList(); 41 42 //將集合遍歷循環 43 for(BookCard bookCard:list){ 44 //打印輸出到控制檯 45 System.out.println(bookCard); 46 } 47 48 //關閉session 49 session.close(); 50 //關閉sessionFactory 51 sessionFactory.close(); 52 //返回list集合 53 return list; 54 55 } 56 57 }
第八步:編寫IndexAction(action類)。
1 package ssh.action; 2 3 import java.text.DecimalFormat; 4 import java.util.List; 5 6 import com.opensymphony.xwork2.ActionContext; 7 import com.opensymphony.xwork2.ActionSupport; 8 9 import ssh.entity.BookCard; 10 import ssh.service.IndexService; 11 12 //建立IndexAction(action類)繼承ActionSupport接口 13 public class IndexAction extends ActionSupport { 14 15 private static final long serialVersionUID = 1L; 16 17 //聲明service,但不給它建立具體的實現類的實例, 18 private IndexService is = null; 19 //添加set()方法 20 public void setIs(IndexService is) { 21 this.is = is; 22 } 23 24 //編寫execute()方法 25 public String execute() { 26 27 //獲取IndexService實例,調用getAllBookCard()方法 28 //將結果保存到List集合裏 29 List<BookCard> myBookCardList = is.getAllBookCard(); 30 31 //將查詢出來的結構集打印到控制檯 32 System.out.println("結果集:"+myBookCardList.size()); 33 34 //獲取Context上下文對象 35 ActionContext ac = ActionContext.getContext(); 36 //將myBookCardList集合添加到上下文對象裏 37 ac.put("myBookCardList", myBookCardList); 38 39 //返回一個字符串 40 return "success"; 41 } 42 43 //金額格式轉換 44 public String formatDouble(double s){ 45 DecimalFormat fmat=new DecimalFormat("\u00A4##.0"); 46 return fmat.format(s); 47 } 48 49 }
第九步:編寫struts.xml(struts配置文件)、applicationContext.xml(spring配置文件)、hibernate.cfg.xml(hibernate配置文件)。
注:將這些配置文件放到src裏。
struts.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 <!-- 上面的頭,注意版本,從樣例裏複製過來 showcase.war\WEB-INF\src\java\struts.xml --> 6 7 <struts> 8 <!-- 告知Struts2運行時使用Spring來建立對象 --> 9 <constant name="struts.objectFactory" value="spring" /> 10 11 <!-- 第1步:先定義一個包 --> 12 <package name="mypck001" extends="struts-default"> 13 <!-- 第2步:定義一個action,配置跳轉信息 name 相似於Servlet @WebServlet("/IndexServlet") 14 http://xxxx/xxx/Index.action http://xxxx/xxx/Index class 對應於本身寫的Action類 當不寫method屬性時,默認調用的是execute 15 class="ssh.action.IndexAction" ** new ssh.action.IndexAction() 16 設計思想:關心了具體的實現類必須改成不要關注那個實現類 加入spring後,struts的action節點的class屬性意義發生變化,直接引用spring幫忙建立的實例 17 --> 18 <action name="Index" class="myIndexAction"> 19 <!-- 跳轉是forward/WEB-INF/是防止jsp不通過action就能夠訪問--> 20 <!-- result接收返回的字符串,而後作對應的事情 --> 21 <result name="success">/WEB-INF/jsp/index.jsp</result> 22 </action> 23 </package> 24 </struts>
applicationContext.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xmlns:jee="http://www.springframework.org/schema/jee" 8 xmlns:tx="http://www.springframework.org/schema/tx" 9 xsi:schemaLocation=" 10 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 11 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 12 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 13 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd 14 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> 15 <!-- 相似於財務部門同樣,類就是錢,全部須要類的實例都由srping去管理 --> 16 <bean id="myIndexAction" class="ssh.action.IndexAction" scope="prototype"> 17 <!-- setIs(myIndexService) --> 18 <property name="is" ref="myIndexService"/> 19 </bean> 20 21 <!-- myIndexService = new ssh.service.IndexServiceImpl() --> 22 <bean id="myIndexService" class="ssh.service.IndexServiceImpl" scope="prototype"> 23 <property name="id" ref="myIndexDao"/> 24 </bean> 25 26 <bean id="myIndexDao" class="ssh.dao.IndexDaoImpl" scope="prototype"> 27 <!-- 把sessionFactory 注入給IndexDao --> 28 <property name="sessionFactory" ref="sessionFactory" /> 29 </bean> 30 31 <!-- 添加sessionFactory bane ,注意,該類是Spring提供的 --> 32 <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" scope="prototype"> 33 <!-- 注入Hibernate 配置文件路徑,前面要加上 classpath:--> 34 <property name="configLocation" value="classpath:hibernate.cfg.xml"/> 35 </bean> 36 37 </beans> 38
hibernate.cfg.xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 5 6 <hibernate-configuration> 7 <session-factory> 8 <!-- 數據庫鏈接配置 --> 9 <property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property> 10 <property name="connection.url">jdbc:sqlserver://localhost:1433;DatabaseName=CardDB</property> 11 <property name="connection.username">sa</property> 12 <property name="connection.password">123456</property> 13 <!-- 每一個數據庫都有1個,針對特定的關係型數據庫生成優化的SQL --> 14 <property name="dialect">org.hibernate.dialect.SQLServer2008Dialect</property> 15 16 <!-- 設置默認的數據庫鏈接池 --> 17 <property name="connection.pool_size">5</property> 18 19 <!-- 顯示SQL --> 20 <property name="show_sql">true</property> 21 22 <!-- 格式化SQL --> 23 <property name="format_sql">true</property> 24 25 <!-- 根據schema更新數據表的工具 --> 26 <property name="hbm2ddl.auto">update</property> 27 28 <!-- 數據表映射配置文件 --> 29 <mapping resource="ssh/entity/BookCard.hbm.xml"/> 30 31 </session-factory> 32 </hibernate-configuration>
第十步:建立一個index.jsp頁面將全部數據取出來顯示到頁面上。
注:跳轉是forward,將jsp放到/WEB-INF/是防止jsp不通過action就能夠訪問。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ taglib uri="/struts-tags" prefix="s" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 12 <table border="1"> 13 <tr> 14 <td>卡號</td> 15 <td>姓名</td> 16 <td>性別</td> 17 <td>辦卡日期</td> 18 <td>押金</td> 19 </tr> 20 <!-- 使用struts2標籤庫中的iterator將全部數據遍歷循環顯示出來 --> 21 <s:iterator value="#myBookCardList" status="bcs"> 22 <tr> 23 <td><s:property value="cid"></s:property></td> 24 <td><s:property value="name"></s:property></td> 25 <td><s:property value="sex"></s:property></td> 26 <td><s:date name="cardDate" format="yyyy年MM月dd日"></s:date></td> 27 <td><s:property value="%{formatDouble(deposit)}"></s:property></td> 28 </tr> 29 </s:iterator> 30 <!-- 判斷查詢出來等於0,就顯示「沒有查找到數據」 --> 31 <s:if test="myBookCardList.size()==0"> 32 <tr> 33 <td colspan="7">沒有查找到數據</td> 34 </tr> 35 </s:if> 36 </table> 37 </body> 38 </html>
運行結果:
瀏覽器顯示:
控制檯輸出:
總結:在SSH中使用Struts做爲系統的總體基礎架構,負責MVC的分離,在Struts框架的模型部分,控制業務跳轉,利用Hibernate框架對持久層提供支持,Spring作支持,支持struts和hibernate。具體作法是:用面向對象的分析方法根據需求提出一些模型,將這些模型實現爲基本的Java對象,而後編寫基本的DAO(Data Access Objects)接口,並給出Hibernate的DAO實現,採用Hibernate架構實現的DAO類來實現Java類與數據庫之間的轉換和訪問,最後由Spring作支持,支持struts和hibernate。其實ssh框架最主要的本質是:「高內聚、低耦合」。