1. 程式人生 > >double整合框架-spring+hibernate、spring+struts、spring+mybatis

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>