double整合框架-spring+hibernate、spring+struts、spring+mybatis
本片文章主要介紹框架double整合的簡介和使用、瞭解和熟悉了double整合,對於使用SSM、SSH等流行整合框架具有很重要的意義。本篇文章將帶你一步步的完成double整合。
目錄:
一:spring+hibernate
二:spring+struts
三:spring+mybatis
一:spring+hibernate
簡介:spring+hibernate整合的思路就是不再使用hibernate的配置檔案,而是通過spring注入的方式,連線資料庫,配置hibernate。通過dao層繼承hibernateTemplate這個類,這個類提供setSessionFactory方法,在spring中,給dao層註冊一個bean,並註冊一個bean,配置好hibernate需要的配置資訊 ,並將這個bean注入到dao中的sessionFactory屬性中。使用時獲取該bean,因為dao繼承了這個類,使用時可以直接通過dao呼叫save、get、update、dalete等方法完成操作資料庫。
類似於工廠模式中的sessionFactory被建立 ,並被注入了hibernate的配置資訊。
1. 建立實體類,hero
2. 配置實體類與資料庫對映檔案:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="pojo"> <class name="Hero" table="hero"> <id name="id" column="id"> <generator class="native"> </generator> </id> <property name="name" /> </class> </hibernate-mapping>
3. 建立spring的配置檔案,applicationContext.xml檔案,配置資料庫、設定hibernate方言等、關聯對映檔案。並將這些資訊注入到dao中的sessionFactory屬性中。完成注入。內容如下:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean name="dao" class="HeroDAO"> <property name="sessionFactory" ref="sf" /> </bean> <bean name="sf" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="ds" /> <property name="mappingResources"> <list> <value>pojo/Hero.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=true hbm2ddl.auto=update </value> </property> </bean> <bean name="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> </beans>
4.編寫測試類,完成spring+hibernate的搭配操作資料庫 。在測試類中,讀取spring的配置檔案,獲取dao這個bean,因為該bean繼承了HibernateTemplate類,並被注入了sessionFactory屬性。則該bean可以直接使用父類的方法,完成操作資料庫。
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" });
HeroDAO dao = (HeroDAO) context.getBean("dao");
Hero c = new Hero();
c.setName("Heroyyy");
//增加
dao.save(c);
//獲取
Hero c2 = dao.get(Hero.class, 1);
//修改
c2.setName("Herozzz");
dao.update(c2);
//刪除
dao.delete(c2);
}
至此,已經基本完成了spring與hibernate的整合。
5. 基本使用技巧:
因為spring+hibernate是使用HibernateTemplate來完成的,所以與hibernate的使用有所不同,這裡是使用hibernateTemplate中的方法進行操作的。HibernateTemplate中的find方法,是Hql操作資料庫的方法。
分頁:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" });
CategoryDAO dao = (CategoryDAO) context.getBean("dao");
DetachedCriteria dc = DetachedCriteria.forClass(Hero.class);
int start =5;//從多少開始查詢
int count =10;//每頁顯示數量
List<Hero> cs= dao.findByCriteria(dc,start,count);
System.out.println(cs);
}
模糊查詢:
List<Hero> cs =dao.find("from Heroc where c.name like ?", "%c%");//HQL查詢
for (Heroc : cs) {
System.out.println(c.getName());
}
DetachedCriteria dc = DetachedCriteria.forClass(Hero.class);//Criteria查詢
dc.add(Restrictions.like("name", "%分類%"));
cs =dao.findByCriteria(dc);
for (Heroc : cs) {
System.out.println(c.getName());
}
二:spring+struts整合
對於struts來說,我們最關注的是action的生命週期,spring+struts的整合思路就是struts的action交給你spring來管理。而spring配置的載入是通過web.xml中的監聽器讀取jar包,來載入該配置檔案,註冊好bean之後,在struts中宣告它的物件工廠交給spring來管理。則該bean就可以用作struts的action來使用了。這裡舉例說明訪問一個action,跳轉後臺方法,獲取查詢資料,返回jsp展示資料的過程,具體步驟如下:
1. 匯入struts和spring以及spring+struts的jar包,在web.xml中設定struts的攔截器,和讀取spring的監聽器。配置檔案如下:
<web-app>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 該監聽器負責tomcat啟動時,掃描WEB-INF/lib目錄下是否有 struts2-spring-plugin-2.2.3.1.jar!-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
2. 在WEB-INF下建立applicationContext.xml檔案,建立struts需要的action-bean。指向類為Action業務邏輯類。
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean name="heroActionBean" class="action.HeroAction">
</bean>
</beans>
3. 在src下建立struts的配置檔案:struts.xml檔案,設定action資訊。
<constant name="struts.objectFactory" value="spring"/>為宣告struts的action建立交給spring來管理,指定objectFactory物件工廠的值為spring。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.objectFactory" value="spring"/>
<package name="basicstruts" extends="struts-default">
<action name="listHero" class="heroActionBean" method="list">
<result name="list">list.jsp</result>
</action>
</package>
</struts>
4.HeroAction中提供list方法,並查詢出heroList集合,return "list",並提供list.jsp檔案,通過s標籤或者c標籤遍歷迴圈出heroList集合,完成展示。
啟動tomcat,訪問localhost:8080/SS/listHero,整合完成。
三:spring+mybatis
spring+mybatis的整合就比較有意思了,而且也比較常見。整合思路是原本mybatis的配置檔案所做的事情,通過spring來完成注入,並通過注入SqlsessionFactory的方式,載入mybatis的配置檔案。並通過注入一些整合相關的屬性值,完成double整合。主要整合方式有三種:
㈠注入對映器的方式:採用面對介面的方式,自動註冊mapper中的bean;
㈡sqlsession的方式:
①使用SqlSession的實現類SqlSessionTemplate來完成配置;
②採用抽象類org.mybatis.spring.support.SqlSessionDaoSupport提供SqlSession完成配置;
下面進行分別介紹。
1. 注入對映器的方式,採用mapper介面注入:
此方式的思路就是,建立mapper介面類,在該類中建立與SQLID一致的方法名,並且SQL.xml中的namespace與該類的路徑一致。
㈠配置過程:
①匯入所需要的jar包,建立pojo實體類Hero,建立Hero.xml,建立HeroMapper介面並建立響應的方法。考慮到面對介面程式設計思維方式,還需要建立service介面和service實現類,實現類負責實現dao層介面也就是mapper的介面。這裡為了方便,省去了service的使用,直接呼叫dao也就是mapper介面完成使用。
<mapper namespace="mapper.HeroMapper">
<insert id="add" parameterType="Hero" >
insert into hero ( name ) values (#{name})
</insert>
<select id="list" resultType="Hero">
select * from hero
</select>
</mapper>
public interface HeroMapper {
public int add(Category category);
public List<Category> list();
}
②在src下建立spring配置檔案applicationContext.xml檔案,在該配置檔案中,給SqlSessionFactoryBean類注入dataSorece資料庫配置、mybatis的配置(包括掃描哪些xml檔案、xml中的別名、配置資料來源、開啟事務等等與mybatis相關的配置)。註冊org.mybatis.spring.mapper.MapperScannerConfigurer類,告訴spring-mybatis需要掃描哪些mapper介面類,並自動註冊為bean,並將掃描的xml檔案根據namespace匹配注入到對應的mapper介面的方法中,相當於實現了mapper介面中的方法。因為有了這一步,所以在後面使用mapper介面時,通過@autowired自動獲取該bean,可以直接呼叫方法,就可以呼叫SQL語句塊操作資料庫了。配置檔案如下:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:annotation-config /> //開啟自動掃描包功能
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="pojo" />
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mapper"/>
</bean>
</beans>
注:雖然整合之後可以不需要mybatis的配置檔案,但是一些細緻的配置還是需要mybatis的配置檔案來完成,在這裡可以通過在sqlsessionFactoryBean這個類的註冊時,可以通過configLocation屬性新增mybatis的配置檔案,通過讀取該配置檔案完成xml的對映和xml的別名等其他設定,在這裡就可以免了。
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- <property name="typeAliasesPackage" value="pojo" /> <property name="mapperLocations" value="classpath:mybatis/*.xml"/> --> <!-- 可以使用mybatis 的配置檔案進行細節的配置,也可以代替這裡的一些東西 --> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean>
mybatis配置檔案中:
<configuration> <typeAliases> <package name="pojo"/> </typeAliases> <mappers> <mapper resource="mybatis/Hero.xml"/> </mappers> </configuration>
㈡測試類使用:
編寫測試類:
@RunWith解釋:代表執行測試環境,runwith是一個按照某個測試執行器進行執行測試的註解功能。也就是說,我們使用Junit中的test進行單元測試時,如果這個測試需要執行在某個環境中,例如本例需要執行在spring環境中,就需要用該註解載入這個環境。runwith中告訴程式測試執行環境是什麼(本例中告訴程式我需要執行在spring的測試環境中),然後通過@ContextConfiguration來讀取spring的配置檔案,此時,spring環境被載入。
@Autowired:這是spring中的註解功能,該註解可以自動掃描spring中已經註冊的bean,將該屬性型別、屬性名匹配spring中的bean,如果匹配到了,就把這個bean自動注入到這個屬性中,就相當於做了getBean()操作。在改例中:heroMapper被它修飾,程式發現該屬性是一個可以自動裝配的bean,因為spring配置中通過自動掃描已經把mapper中的介面都註冊成了bean,即HeroMapper介面類已經自動註冊了heroMapper這個bean,並把xml檔案注入到了改bean中。則找到了該bean,將這個bean自動裝配到了這個屬性中了。此時呼叫該屬性中的方法即可呼叫SQL語句塊。
自動裝配過程中:spring會優先尋找屬性名與beanID一致的完成匹配,如果名稱不一致,則會去匹配同類型的bean,如果同類型的bean有多個,則自動注入失敗,報錯。——————這是我自己的猜測理解,沒有理論依據的......
@test這是Junit提供的單元測試註解,可以不通過主執行緒main方法即可完成執行。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class HeroAction {
@Autowired
private HeroMapper heroMapper;
@Test
public void testList() {
List<Hero> cs=heroMapper.getList();
for (Hero c : cs) {
System.out.println(c.getName());
}
}
}
在這個測試類中,載入spring環境,並且自動裝配了heroMapper這個已經完成注入的bean到heroMapper屬性中。通過呼叫該mapper中的方法呼叫SQL語句塊,完成查詢。
2. 採用sqlsession的實現類SqlSessionTemplate的配置方式:
此類方式的思路是:在使用對映器的配置基礎上,拋棄掉MapperScannerConfigurer這個對映類掃描器。spring中新增自動掃描包,掃描的包為需要使用SqlSessionTemplate這個bean的包,然後註冊一個bean:org.mybatis.spring.SqlSessionTemplate。將已經注入好的sqlsessionFactory這個bean作為構造方法的引數傳遞到該類中,用以例項化該物件。此時就完成了sqlsessionFactory的宣告。就可以直接使用了。在使用時,這種配置方式一般是在dao層的實現類中,自動裝配這個bean,然後操作資料庫,也就是在dao實現層使用。當然,在業務邏輯層使用也可以,不會一般不會。
㈠配置方式:
在原有對映器的配置基礎上,修改spring的配置檔案如下:其他配置檔案無需修改。
<beans
<context:annotation-config />
<!-- 自動掃描類 ,配置第二種配置方式使用,是必須的 -->
<!-- <context:component-scan base-package="dao" /> -->
<!-- 配置資料來源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
</bean>
<!-- 註冊sqlsessionFactory -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- <property name="typeAliasesPackage" value="pojo" />
<property name="mapperLocations" value="classpath:mybatis/*.xml"/> -->
<!-- 可以使用mybatis 的配置檔案進行細節的配置,也可以代替這裡的一些東西 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--對映器的配置方式,可以註釋掉-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSession" />
</bean>
<!--sqlSessionTemplate的配置方式-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSession"></constructor-arg>
</bean>
</beans>
㈡編寫測試類,通過sqlSessionTemplate完成操作資料庫。
在dao的實現類中,程式碼如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class HeroDao {
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Test
public void list() {
List<Hero> lh = sqlSessionTemplate.selectList("getList");
for (Hero hero : lh) {
System.out.println(hero.getName());
}
}
}
直接自動裝配這個spring中的bean,然後使用該物件呼叫相應的方法,通過SQLID完成操作資料庫。
3. 抽象類SqlSessionDaoSupport的配置方式(感覺類似於ibatis的使用):
該配置方式的思路是:spring配置檔案中,拋棄上面MapperScannerConfigurer和SqlSessionTemplate的方式。保留sqlsessionFactory這個bean。在dao的實現類中,繼承org.mybatis.spring.support.SqlSessionDaoSupport這個抽象類。並將sqlsessionFactory這個bean完成自動裝配,通過父類的setSqlSessionFactory方法將該bean傳入到父類中。然後通過呼叫父類的getSqlSession()獲取一個sqlsession,通過該sqlsession完成操作資料庫。
㈠配置檔案:
該配置方式不需要額外的配置檔案的修改。只要注入好了sqlsessionFactory即可。
㈡測試類:程式碼如下:
@Repository
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestDaoSupport extends SqlSessionDaoSupport {
/**
* 通過autowired自動注入sqlsessionFactory這個物件,並將該物件放置在父類中,
*/
@Autowired
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
System.out.println("session:"+sqlSessionFactory);
super.setSqlSessionFactory(sqlSessionFactory);
}
@Test
public void getList() {
List<Hero> lh = this.getSqlSession().selectList("getList");//呼叫父類的sqlsession物件
for (Hero hero : lh) {
System.out.println(hero.getName());
}
}
}
至此,完成了spring+mybatis的三種配置方式,目前用的最多的是對映器的使用,因為他更符合面對介面程式設計,而且管理起來也很方便。
4. spring 配置檔案的子配置檔案:
如果專案很大,並且有很多業務場景需要配置多個spring配置,建立多個springBean。如果所有的bean都在一個配置檔案中的話,那管理起來很不方便。此時可以通過建立子spring配置檔案來方便管理:
在spring總配置檔案中新增:
<import resource="spring/spring-*.xml"/>
意思是:載入src/spring/中所有spring-*的檔案。我們在做專案時,可以把所有的spring配置檔案放在spring這個資料夾下,命名方式為spring-xxxx.xml。並且在自配置檔案中,可以共享總配置檔案中的bean。
spring-hero.xml檔案如下:建立了一個service的bean,型別是service的實現類,並在該類中的屬性heroDao(需要有get/set方法)注入heroDao這個bean。使用時,可以直接通過裝配heroService這個bean,來呼叫service實現類中的方法。此處的heroMapper為spring-mybatis自動註冊的bean。
<?xml version="1.0" encoding="UTF-8"?>
<beans
<bean id="heroService" class="com.wht.service.impl.HeroServiceImpl">
<property name="heroMapper" ref="heroMapper" />
</bean>
</beans>