前言
SSH分別代表Struts,Spring,Hibernate.
Struts用來響應用戶的action,對應到相應的類進行處理。需要struts對應的包。
hibernate:用來把實體類對應到數據庫。提供增刪改查的基本操作實現。需要hibernate對應的包以及mysql的jdbc驅動包。
spring:
- 管理struts:在xml配置文件中爲struts的action進行值注入。
- 管理hibernate:在xml配置文件中配置hibernate的配置信息(dataSource,sessionFactory),即不需要原來的hibernate的xml文件。爲hibernate的dao操作注入sessionfactory屬性值。
Spring整合Struts2
Spring容器創建
首先需要創建Spring容器,在web應用中創建spring容器有兩種方式:
- 直接在web.xml文件中配置spring
- 利用第三方MVC框架的擴展點,創建Spring容器。
第一種方法最常見,爲了讓Spring容器隨web應用的啓動而啓動,需要藉助ServletContextListener監聽器完成,該監聽器在web應用啓動時回調自定義方法來啓動spring容器。
spring提供ContextLoaderListener監聽類,該類實現ServletContextListener接口,在創建時自動查找WEB-INF下的applicationContext.xml配置文件。
如果只有一個配置文件,在web.xml裏如下添加配置代碼:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
如需要指定多個配置文件,或更改配置文件路徑,需使用
Spring工廠模式
web應用中,用戶請求向控制器發送,控制器攔截到用戶請求後,需要調用業務邏輯組件來處理用戶請求。而控制器該如何獲取業務邏輯組件呢?
過去的策略是,直接通過new關鍵字創建業務邏輯組件,然後調用邏輯組件的方法,通過其返回值確定結果。這樣做降低了代碼耦合性,並由於控制器創建組件,會造成控制器與業務邏輯組件分工不明,等。
現在,我們採用工廠模式。將控制器與業務邏輯組件分開,由Spring擔任工廠,負責業務邏輯組件的創建與生產。控制器只從spring中獲取業務組件。
控制器訪問Spring容器中業務邏輯組件的兩種策略:
- Spring容器負責管理控制器Action,並利用依賴注入爲控制器注入業務邏輯組件。
- 利用Spring的自動裝配,Action自動從Spring容器中獲取所需的業務邏輯組件。
下面分別介紹兩種策略:
1.Spring管理控制器
在這之前,我們需要現在web.xml中配置一下Struts2:
<!-- STR1.定義Struts2核心Filter,說明使用struts過濾器攔截web請求,默認查找src下的struts.xml配置文件 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
<!--
下面的配置信息用來說明:程序中運行的action放置在哪個包下面,對於list.action的請求,它會自動在這個包下面尋找ListAction.class的類
如果沒有這句話,那麼所有的action請求只能在struts.xml中進行配置。
-->
<!-- <init-param>
<param-name>actionPackages</param-name>
<param-value>
com.action
</param-value>
</init-param>-->
</filter>
<!-- STR2.下面的配置表示對於所有請求都交給struts來處理。 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Struts2的核心控制器首先攔截用戶請求,然後將請求轉發給對應的Action處理,在此過程中,Struts2將負責創建Action實例,並調用其execute()方法。而,我們需要將Action實例交給Spring容器管理,不由Struts2產生,這個改變需要由Struts2提供的Spring插件(
struts2-spring-plugin-2.2.1.jar)完成。
Spring插件提供一個僞Action,當我們在struts.xml文件中配置Action時,需要指定其class屬性,過去是指定Action實例的實現類。但現在我們需指定爲Spring容器中的Bean ID,這樣Struts通過Spring容器獲取Action對象。
所以,struts配置文件struts.xml爲:
<!-- 配置文件根元素 -->
<struts>
<!-- 指定Web應用的默認編碼集。該屬性對於處理中文請求參數非常有用,
對於獲取中文請求參數值,應該將該屬性值設置爲GBK或者GB2312 當設置該參數爲GBK時,
相當於調用HttpServletRequest的setCharacterEncoding方法 -->
<constant name="struts.i18n.encoding" value="utf-8" />
<!-- 開發模式,如若“false”則爲產品模式 -->
<constant name="struts.devMode" value="true" />
<!-- 代表了每一個獨立的模塊 -->
<package name="default" namespace="/" extends="struts-default">
<!-- 定義用戶請求Action -->
<!-- 方法一:Spring管理控制器,class名loginAction爲僞控制器,對應spring容器中的Bean實例 -->
<action name="loginPor" class="loginAction">
<!-- 邏輯視圖配置邏輯頁面 -->
<result name="error">/error.jsp</result>
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
在applicationContext.xml中需配置上文Action實例,並將業務邏輯組件注入到實例中:
<!-- 方法一:Spring管理控制器.定義業務邏輯組件,實現類MyServiceImpl -->
<bean id="myService" class="com.hqs.ssh.service.imp.MyServiceImpl" />
<!-- 讓Spting管理的Action實例,,,scope變量範圍,prototype表示每次對該bean的實例請求都會導致一個新的實例創建 -->
<bean id="loginAction" class="com.hqs.ssh.action.LoginAction" scope="prototype">
<!-- 依賴注入業務邏輯組件 -->
<property name="ms" ref="myService"/>
</bean>
2.自動裝配
該策略下,Action還是Spring插件創建,Spring插件在創建Action實例時,利用自動裝配策略,將對應業務邏輯組件注入Action實例。
struts.xml配置:
<!-- 方法二:自動裝配,class爲Action實現類,與不整合spring配置相同 -->
<action name="loginPor" class="com.hqs.ssh.action.LoginAction">
applicationContext.xml配置:
<!-- 方法二:自動裝配,id與爲所需的業務組件名(即xxxaction.java方法中定義的業務組件名)。缺點:可讀性差,不利於解耦 -->
<bean id="ms" class="com.hqs.ssh.service.imp.MyServiceImpl" />
2015/10/2 10:15:49
Spring整合Hibernate
現在,很少使用JDBC的方式來訪問持久層,大部分時候以ORM框架來訪問持久層,Hibernate是比較優秀的ORM框架。
DAO模式:所有數據庫訪問,都通過DAO組件完成,DAO組件封裝數據庫的增、刪、改等操作。
Spring提供如下三個工具類(或接口)來支持DAO組件實現:
- HibenateDaoSupport
- HibernateTemplate
- HibernateCallback
Hibernate配置
當通過Hibernate進行持久層訪問時,必須先獲得SessionFactory對象,它是單個數據庫映射關係編譯後的內存鏡像。
Hibernate SessionFactory配置示範
<!-- Hibernate整合。HIB1.定義數據源Bean,使用C3P0數據源實現 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- 指定連接數據庫的驅動 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<!-- 指定連接數據庫的URL -->
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
<!-- 指定連接數據庫的用戶名 -->
<property name="user" value="root"/>
<!-- 指定連接數據庫的密碼 -->
<property name="password" value="root"/>
<!-- 指定連接數據庫連接池的最大連接數 -->
<property name="maxPoolSize" value="40"/>
<!-- 指定連接數據庫連接池的最小連接數 -->
<property name="minPoolSize" value="1"/>
<!-- 指定連接數據庫連接池的初始化連接數 -->
<property name="initialPoolSize" value="1"/>
<!-- 指定連接數據庫連接池的連接的最大空閒時間 -->
<property name="maxIdleTime" value="20"/>
</bean>
<!-- HIB2.定義SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 依賴注入數據源,注入正是上面定義的dataSource -->
<property name="dataSource" ref="dataSource"/>
<!-- mappingResouces屬性用來列出全部映射文件 -->
<property name="mappingResources">
<list>
<!-- 以下用來列出Hibernate映射文件 -->
<value>com/hqs/ssh/domain/User.hbm.xml</value>
</list>
</property>
<!-- HIB3.定義SessionFactory的屬性 -->
<property name="hibernateProperties">
<!-- 配置Hibernate屬性 -->
<value>
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=true;
</value>
</property>
</bean>
在Spring的IoC容器中配置了SessionFactory Bean後,它將隨應用啓動而加載,並可以將其注入到其他Bean,如DAO組件。一旦DAO組件獲取了SessionFactory Bean的引用,就可以訪問數據庫。
<!-- HIB4.定義DAO Bean-->
<bean id="userDao" class=
"com.hqs.ssh.dao.impl.UserDaoImpl">
<!-- 注入持久化操作所需的SessionFactory -->
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
HibernateTemplate
HibernateTemplate提供持久化訪問模板化,只需要提供一個SessionFactory的引用,就可以執行持久化操作。
DAO組件的實現基於HibernateTemplate:
public class UserDaoImpl implements UserDao{
//定義一個HibernateTemplate對象,用於執行持久化操作
private HibernateTemplate ht = null;
//Hibernate持久化操作所需的SessionFactory
private SessionFactory sessionFactory;
//依賴注入SessionFactory的setter方法
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
//初始化HibernateTemplate的方法,執行持久化操作
private HibernateTemplate getHibernateTemplate()
{
if (ht == null)
{
ht = new HibernateTemplate(sessionFactory);
}
return ht;
}
/**
* 加載User實例
* @param id 需要加載的User實例的標識屬性值
* @return 指定id對應的User實例
*/
public User get(Integer id)
{
return getHibernateTemplate()
.get(User.class, id);
}
/**
* 保存User實例
* @param User 需要保存的User實例
* @return 剛剛保存的User實例的標識屬性值
*/
public Integer save(User user)
{
return (Integer)getHibernateTemplate()
.save(user);
}
/**
* 修改User實例
* @param User 需要修改的User實例
*/
public void update(User user)
{
getHibernateTemplate().update(user);
}
/**
* 刪除User實例
* @param User 需要刪除的User實例
*/
public void delete(User user)
{
getHibernateTemplate().delete(user);
}
}
2015/10/2 10:16:10
參考自:輕量級javaee企業應用實戰