由於Spring和Hibernate處於不同的層次,Spring關心的是商務邏輯之間的組合關係,Spring提供了對他們的強大的管理能力, 而Hibernate完成了OR的映射,使開發人員不用再去關心SQL語句,直接與對象打交道。 將Hibernate做完映射之後的對象交給Spring來管理是再合適不過的事情了, Spring也同時提供了對Hibernate的SessionFactory的整合功能。所以spring+hibernate整合對我們實際開發是非常有必要的。Spring整合hibernate有多種方式,我用的只是其中的一種,我這種不需要hibernate的設定檔,直接配置我們的beans.xml裡了。下面我們具體來看一下:
首先我們先把需要的實體類定義出來,我這裡定義的是:
Users.java:public class Users {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
這裡我們整合spring+hibernate主要是來整合的細節,商務邏輯和分層在此就忽略不計了,我直接把所有的東西都寫在了test類裡面了。
下面我們來看一下我們的beans.xml的配置,我們先把代碼貼出來,然後再下面一點點的深入詳解:
Beans.xml:
<?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:p="http://www.springframework.org/schema/p"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
//設定資料庫相關資訊,配置資料來源,它將會被注入到sessionfactory中<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><propertyname="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /><property name="url"value="jdbc:sqlserver://localhost:1433; DatabaseName=test" /><property name="username" value="sa"></property><property name="password" value="123456"></property></bean>//構建sessionfactory的bean,為把sessionfactory注入到dao層構建bean<bean id="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"lazy-init="false">//注入datasource,給sessionfactoryBean內setdatasource提供資料來源<property name="dataSource"><ref bean="dataSource" /></property>//載入實體類的設定檔<property name="mappingResources"><list><value>com/bzu/test/Users.hbm.xml</value><value>com/bzu/test/Log.hbm.xml</value></list></property>//設定hibernate的屬性,相當於hibernate.cfg.xml中的設定屬性<property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop><prop key="hbm2ddl.auto">update</prop><prop key="hibernate.show_sql">true</prop></props></property></bean>//把sessionfactory注入dao層<bean id="test" class="com.bzu.test.test" lazy-init="false"><property name="sessionFactory" ref="sessionFactory"></property></bean></beans>
通過上面的注釋我想大家應該大體對這個設定檔明白些了吧。其實這個也很好理解,大體思路就是首先寫一個datasource的bean,這個bean主要是為hibernate提供資料來源,大家肯定可以想到這個資料來源將會被注入到sessionfactory裡面,因為構建sessionfactory肯定會需要到這個資料來源的資訊。
下一步我們在寫一個sessionfactory的bean,這個bean將被我們用在注入到dao層,進行資料庫操作,當然,他還需要一些屬性進行注入,比如我們剛才寫的datasource,除了這個之外我們還需要配置我們的實體,spring給我們提供了hbm檔案和實體類等多種配置方法。Hbm檔案配置我們這樣寫:
<property name="mappingResources"><list><value>com/bzu/test/Users.hbm.xml</value><value>com/bzu/test/Log.hbm.xml</value></list></property>
屬性值為mappingResources,這個屬性值是一個list,我們可以配置他的value,把我們的設定檔一個個的加入進來。如果你沒有寫設定檔,而是以註解的方式配置的實體類,你當然也可以以實體類的形式加到這裡來:你可以以下方式進行配置:把屬性的name設定成annotatedClasses
<property name="annotatedClasses"><list><value>com.bzu.model.User</value><value>com.bzu.model.Log</value></list></property>
說完配置sessionfactory的的實體,下一步我們還要配置hibernate的的一些屬性,比如建立資料庫表的方式、資料庫方言等。設定hibernate的屬性,我們用hibernateProperties來配置,配置方式,上面代碼已經很清楚的寫到了,在這就不贅述了。
好了,配置完sessionfactory這個bean,下一步我們就要把sessionfactory注入到我們的dao層進行資料庫操作了。這一步就比較簡單了,相信大家能看懂上面的代碼。
看完設定檔,接下來我們就要來測試一下來,試試能不能用hibernate對我們的資料庫進行訪問了。具體來看一下代碼:
package com.bzu.test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.transaction.annotation.Transactional;public class test {private static SessionFactory sessionFactory;public SessionFactory getSessionFactory() {return sessionFactory;}public void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}public static void main(String[] args) throws Exception {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");Session session = sessionFactory.openSession();// ((SessionFactory) ctx.getBean("sessionFactory")).openSession();Users user = new Users();user.setName("nihao");session.save(user);}}
大家可以清楚的看到,上面的內容很簡單,我們寫具體的架構的東西,直接把sessionfactory注入到了test類了,當然了,我們實際開發應用中不會手動的去載入beans.xml的,這裡主要是為了測試,測試一下:
列印出sql語句:
Hibernate: insert into users (name) values (?)
好了,基本上我們這個hibernate+spring整合的差不多了。但在調試這個程式的時候還是出了點小差錯,最後弄了半天才發現錯誤所在,我剛開始寫的時候,是把main裡面的操作都抽出一個方法了,然後再main方法中我是這樣調用的new Test().sava(user),直接就出事了。異常的原因就是我new出來的test的對象就不受spring容器管理了,所以在調用save方法時根本sessionfactory就沒有被注入進去,所以希望大家注意這一點。