ssh整合,指的是Spring,hibernate,struts2 這3個框架結合一塊兒,整合hibernate的時候,主要利用的是hibernate自身的持久層實現,而不是使用hibernate對JPA的實現方式。用ssh作crud的總思路以下java
-
使用hibernateweb
-
能夠不須要建立hibernate.cfg.xml文件,由於applicationContext文件已經配置好了spring
-
建立映射文件,並配置在applicationContext文件中sql
-
-
使用spring數據庫
-
建立applicationContext.xml文件express
-
配置datasource,以便讓項目使用數據庫鏈接池功能apache
-
配置LocalSessionFactoryBean,以便建立SessionFactory對象session
-
配置事務管理器,HibernateTransactionManagerapp
-
配置事務環繞通知,以便給服務層的方法增長事務環繞功能框架
-
配置切面,以便真正建立代理,完成事務通知的織入
-
-
使用struts
-
建立struts.xml文件放置在類路徑下
-
在裏面正常的配置action,除了class屬性的值設爲bean的名字之外。
-
-
整合hibernate:
-
總目標是把SessionFactory,注入到dao類中。
-
而且開啓事務支持(針對服務層)後,dao類的代碼編寫就能夠省略掉事務方面的代碼,以簡化dao的編寫。
-
在dao中利用的是Hibernate原生的接口類型(SessionFactory,Session這也是官方推薦的用法)
-
利用session.getCurrentSession,以便服務類調用多個dao時,每個dao獲得的是同一個session對象,也就是同一個Connection對象,這樣才能保證事務。而且不須要手動的調用session.close方法來關閉。事務提交時會自動關閉鏈接
-
-
整合struts2
-
添加ContextLoaderListener以便建立一個Spring容器對象(ApplicationContex實例)
-
在struts.xml文件中配置action的class屬性時,其值是spring配置文件中的bean的名字
-
利用struts-spring插件,改變默認struts框架實例化Action(也就是控制器類型)的默認規則,改由先從spring容器中取(容器對象已經由監聽器建立出來了),取不到就按照本來的規則實例化Action類型
-
-
作CRUD
-
編寫dao
-
編寫service
-
編寫控制器
-
配置struts.xml文件
-
配置applicationContext文件
-
建立Maven項目
正常的maven項目建立,建立好了以後,在pom文件中對插件進行設置
<build> <plugins> <!--用於設定源代碼文件的編碼,以及項目代碼運行的目標jdk版本爲1.8 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- 指定項目中web資源的根目錄,用於maven打包時把此目錄的全部內容拷貝到war中--> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <warSourceDirectory>web</warSourceDirectory> </configuration> </plugin> </plugins> </build>
添加構面
這裏徹底能夠不用作,主要是充分利用Idea開發工具的支持,以便方便咱們後面的代碼編寫,文件配置等功能,主要添加下面幾個構面
-
spring
-
hibernate
-
web
-
struts
使用Spring
這裏主要指的是spring的基本使用,主要包含如下幾個方面
-
添加基本的maven依賴
-
添加applicationContext.xml文件
-
把applicationContext.xml文件交給idea管理
添加spring的基本依賴
基本功能指的是Spring的容器管理,依賴注入,AOP功能
<!-- 這個依賴可讓spring容器有bean管理,依賴注入,基本的切面配置功能,但不支持切點表達式以及其解析--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- 讓spring支持切點表達式功能--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency>
建立spring配置文件
此文件通常命名爲applicationContext.xml,若是名字這樣命名,而且此文件放置在WEB-INF下面,那麼後續使用ContextLoaderListener的時候,就不須要配置Context-param的contextConfigLocation值以指定Spring配置文件的位置了。
此時此刻,spring文件暫不配置任何內容。
Hibernate的基本使用
包含如下任務
-
添加hibernate的相關依賴
-
建立hibernate.cfg.xml文件
-
建立實體類
-
建立實體類的映射文件
Hibernate的依賴
不與spring整合,也不使用鏈接池的話,使用hibernate只須要下面的依賴便可
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.10.Final</version> </dependency
建立hibernate.cfg.xml文件
單獨使用hibernate時,通常 會建立這個文件,但與spring整合,這個文件是能夠刪掉的,由於配置信息都放在了applicationContext文件裏面了。此文件的主要目標有3個
-
設定鏈接到的數據庫
-
驅動類名
-
url
-
username
-
password
-
-
設定hibernate特定的設置,好比開發時可能設置下面幾項,生成環境就配置方言便可
-
方言(dialect)
-
顯示sql
-
格式化顯示的sql語句
-
-
設置實體的映射文件,以便讓Hibernate知道,要處理那些實體
上面的3個方面的配置,能夠用一句話表示(或者記憶):讓此實體用數據庫特定的sql語句保存到數據庫或從數據庫中讀取數據到實體中
這句話也說明了Hibernate的本質:一個持久層的框架。
建立實體類
正常的POJO bean規範的要求編寫,推薦用包裝類型,好比下面
public class CategoryEntity { private int id; private String cname; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } }
編寫實體類的映射文件
<class name="com.entity.CategoryEntity" table="category" schema="dbo" catalog="demo"> <id name="id" column="id"> <generator class="native"/> </id> <property name="cname" column="cname"/> </class>
struts2 的基本使用
包含如下幾個任務
-
把項目轉換爲web項目
-
設置項目的包爲war
-
添加相關依賴
-
建立struts.xml文件
-
在web.xml中配置struts2 的過濾器
struts web 項目設定
給項目添加web構面支持,並在pom文件中設定包爲war包
<packaging>war</packaging>
添加struts基本依賴
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.12</version> </dependency>
建立struts.xml文件
此文件通常名字爲struts.xml文件,並放置在類路徑下面,若是不這樣命名,而且位置不是直接在類路徑下面,須要給StrutsPrepareAndExecuteFilter
過濾器添加參數,以指定此文件。
設定struts的過濾器
此過濾器設置以後才能真正使用struts框架,url-pattern的配置,官方推薦的標準值爲/*
<filter> <filter-name>struts2</filter-name> <filter-lass>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Spring 與Hibernate的整合
主要的任務有:
-
添加依賴
-
配置SessionFactory對象建立的工廠bean
-
配置事務
添加依賴
<!-- 這是一個數據庫驅動的依賴 --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>6.2.1.jre8</version> </dependency> <!-- 這個依賴是spring專門用來與其餘持久層框架進行整合用的一個依賴 裏面有LocalSessionFactoryBean類型 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- 此依賴有事務方面的通知,事務管理器等 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- 這是dbcp鏈接池依賴,徹底能夠換別的鏈接池組件--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.2.0</version> </dependency>
配置SessionFactory的建立
sessionFactory的配置,通常會利用鏈接池組件,因此配置SessionFactory主要就是配置鏈接池以及LocalSessionFactoryBean
設定數據庫配置的properties文件
url=jdbc:sqlserver://localhost\.:1433;database=demo driverclass=com.microsoft.sqlserver.jdbc.SQLServerDriver username=sa password
在applicationContext使用properties文件,local-override表示本地的設定優先,而不是讓整個程序運行過程當中的一些環境變量優先。
<context:property-placeholder location="classpath:db.properties" local-override="true"/>
配置鏈接池
<context:property-placeholder location="classpath:db.properties" local-override="true"/> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <!-- 配置驅動類,值來自於properties文件 --> <property name="driverClassName" value="${driverclass}"></property> <!-- 配置數據庫的鏈接字符串,值來自於properties文件 --> <property name="url" value="${url}"></property> <!-- 配置鏈接到數據庫的用戶名,值來自於properties文件 --> <property name="username" value="${username}"></property> <!-- 配置鏈接到數據庫的密碼,值來自於properties文件 --> <property name="password" value="${password}"></property> <!-- 配置鏈接池中初始的鏈接數量 --> <property name="initialSize" value="5"></property> <!-- 配置鏈接池中最大空閒的鏈接數量 --> <property name="maxIdle" value="10"/> <!-- 配置鏈接池中最大的鏈接數量 --> <property name="maxTotal" value="10"/> </bean>
配置工廠bean
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" destroy-method="destroy"> <!-- 關聯的datasource --> <property name="dataSource" ref="dataSource"/> <!-- 設置被管理的實體映射文件,多個的話,能夠繼續加value子元素, 或者利用通配符好比*.hbm.xml --> <property name="mappingLocations"> <list> <value>classpath:mappers/CategoryEntity.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <!-- 設置顯示hibernate運行的sql語句,開發時用 --> <prop key="hibernate.show_sql">true</prop> <!-- 設置格式化顯示hibernate運行的sql語句,開發時用 --> <prop key="hibernate.format_sql">true</prop> <!-- 針對特定的數據庫設置方言,便於hibernate對生成的sql進行優化 --> <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop> </props> </property> </bean>
至此,SessionFactory對象就已經建立出來了,就能夠注入到dao中了。
配置事務
配置事務管理,使用不一樣的持久層技術,採用的事物管理器是不一樣的。此管理器有commit,rollback功能,但本地事務都是基於所採用的持久層的事務功能,因此事物管理器須要知道全部的持久層的核心對象,好比下面的sessionFactory對象。
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" > <property name="sessionFactory" ref="sessionFactory"/> </bean>
配置事務用的環繞通知:此通知來自於spring-tx這個xsd文件,別配置到了cache文件去了,同時此環繞通知把事務的提交與回滾交給事務管理器去完成,因此須要知道事物管理器,若是事物管理器的名字爲transactionManager是能夠不用配置的。
下面的配置默認事務傳播級別爲Required,並且是碰到RuntimeException異常時,事務纔會回滾。在spring與hibernate整合使用時,spring會對dao類的代碼中拋出的異常有個轉換功能,會轉換爲DataAccessException。此DataAccessException就是RuntimeException異常的子類型。不過hibernate 5這個版本已經把數據庫的異常轉換爲運行時異常了,因此Spring沒有這個異常轉換功能也能夠,但有些持久層框架或老版本的Hibernate拋出的異常不是運行時異常,那麼Spring的這個異常轉換功能就顯得很重要了。
<tx:advice id="transactionInterceptor" transaction-manager="transactionManager"> <tx:attributes> <!-- 配置全部的get開頭的方法 採用只讀事務,只讀事務不能作增刪改操做(須要持久層框架以及jdbc驅動的支持才真正有效) 設置以後會起到必定的優化做用--> <tx:method name="get*" read-only="true"/> <tx:method name="delete*"/> <tx:method name="update*"/> <tx:method name="insert*"/> </tx:attributes> </tx:advice>
配置事務切面
<aop:config> <!--針對全部服務層代碼來配置切面,不是針對dao層,由於可能一個服務類的方法調用多個dao類的方法,配置在服務層,可讓多個dao的方法運行在一個事務下 --> <aop:pointcut id="allServices" expression="execution(public * com.service.*.*(..))"/> <!-- 引用事務環繞通知,以及服務目標類的切點表達式--> <aop:advisor advice-ref="transactionInterceptor" pointcut-ref="allServices"/> </aop:config>
Spring與Struts2的整合
主要的任務
-
配置監聽器
-
action的class設置爲bean
-
整合的插件配置
配置監聽器
配置監聽器,是爲了建立ApplicationContext對象
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
可選的配置上下文參數,用來指定spring配置文件的位置
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
這個監聽器類來自於spring-web裏面,因此須要添加下面的依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.2.RELEASE</version> </dependency>
action配置
action的class屬性值設定爲spring中配置的控制類的名字
<package name="demo" extends="struts-default"> <!-- 設置控制器類中,能夠訪問的方法名--> <global-allowed-methods>list,delete,create,save,edit,update</global-allowed-methods> <action name="category*" class="categoryController" method="{1}"> <result name="list">/category/list.jsp</result> <result name="create">/category/create.jsp</result> <result name="modify" type="redirectAction">categorylist</result> <result name="edit">/category/edit.jsp</result> </action> </package>
整合插件
此插件由struts框架提供,只須要加到類路徑下面便可,因此只須要添加一個插件的依賴
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.5.12</version> </dependency>
CRUD操做
下面以單表的一個查詢操做爲例來講明ssh整合以後代碼的編寫方式
sql語句
create table category ( id int identity(1,1) primary key, cname nvarchar(10) )
dao類的寫法
父dao的代碼,主要是讓全部的子類都有sessionFactory,不用每一個子類都去寫sessionFactory
public class BaseDao { private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } }
public class CategoryDao extends BaseDao { public List<CategoryEntity> getAll(){ Session session = getSessionFactory().getCurrentSession(); return session.createQuery("from CategoryEntity ").list(); } }
applicationContext中的配置
<!-- 這裏配置父dao,並設置爲抽象,主要的目的是爲了避免能直接getBean的方式使用這個bean設置,與實際的BaseDao類型是否是抽象的無關--> <bean id="baseDao" abstract="true" class="com.dao.BaseDao"> <!--注入sessionFactory,這樣全部的子bean就都有sessionFactory能夠用了 --> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!--parent設置的是父bean的名字,父bean的配置,此子bean就均可以使用了。 --> <bean id="categoryDao" class="com.dao.CategoryDao" parent="baseDao"> </bean>
service類的寫法
public class CategoryService { //這樣用來注入dao的,最好是用接口隔離一下 private CategoryDao categoryDao; public CategoryDao getCategoryDao() { return categoryDao; } public void setCategoryDao(CategoryDao categoryDao) { this.categoryDao = categoryDao; } public List<CategoryEntity> getAll(){ return categoryDao.getAll(); } }
spring中的配置
<bean id="categoryService" class="com.service.CategoryService"> <property name="categoryDao" ref="categoryDao"/> </bean>
控制器類的寫法
父類控制器:主要是爲了給全部的控制類提供公共的功能。
public class BaseController extends ActionSupport { }
public class CategoryController extends BaseController implements ModelDriven<CategoryEntity>{ //spring會注入service類型進來 private CategoryService categoryService; public CategoryService getCategoryService() { return categoryService; } public void setCategoryService(CategoryService categoryService) { this.categoryService = categoryService; } public String list(){ List<CategoryEntity> categoryEntityList = categoryService.getAll(); ActionContext.getContext().put("categoryList",categoryEntityList); return "list"; } }
spring中的配置
<bean id="categoryController" class="com.controller.CategoryController"> <property name="categoryService" ref="categoryService"/> </bean>
總結
pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edu</groupId> <artifactId>ssh</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.10.Final</version> </dependency> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>6.2.1.jre8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.12</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.5.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <warSourceDirectory>web</warSourceDirectory> </configuration> </plugin> </plugins> </build> </project>
applicationContext文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:property-placeholder location="classpath:db.properties" local-override="true"/> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverclass}"></property> <property name="url" value="${url}"></property> <property name="username" value="${username}"></property> <property name="password" value="${password}"></property> <property name="initialSize" value="5"></property> <property name="maxIdle" value="10"/> <property name="maxTotal" value="10"/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" destroy-method="destroy"> <property name="dataSource" ref="dataSource"/> <property name="mappingLocations"> <list> <value>classpath:mappers/CategoryEntity.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop> </props> </property> </bean> <bean id="baseDao" abstract="true" class="com.dao.BaseDao"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="categoryDao" class="com.dao.CategoryDao" parent="baseDao"> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" > <property name="sessionFactory" ref="sessionFactory"/> </bean> <tx:advice id="transactionInterceptor" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="delete*"/> <tx:method name="update*"/> <tx:method name="insert*"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="allServices" expression="execution(public * com.service.*.*(..))"/> <aop:advisor advice-ref="transactionInterceptor" pointcut-ref="allServices"/> </aop:config> <bean id="categoryService" class="com.service.CategoryService"> <property name="categoryDao" ref="categoryDao"/> </bean> <bean id="categoryController" class="com.controller.CategoryController"> <property name="categoryService" ref="categoryService"/> </bean> </beans>
web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <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"> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
struts.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="demo" extends="struts-default"> <global-allowed-methods>list,delete,create,save,edit,update</global-allowed-methods> <action name="category*" class="categoryController" method="{1}"> <result name="list">/category/list.jsp</result> <result name="create">/category/create.jsp</result> <result name="modify" type="redirectAction">categorylist</result> <result name="edit">/category/edit.jsp</result> </action> </package> </struts>
db.properties文件
url=jdbc:sqlserver://localhost\.:1433;database=demo driverclass=com.microsoft.sqlserver.jdbc.SQLServerDriver username=sa password