1、 準備工作:
可以利用hibernate tools生成相關映射文件已經po對象、dao對象,dao也可以自己手動編寫,無非就是實現crud,如果通過繼承hibernate提供的HibernateDaoSupport,則可以更輕鬆的實現
常用數據庫的驅動程序及 JDBC URL:
Oracle 數據庫 :
驅動程序包名: ojdbc14.jar
驅動類的名字: oracle.jdbc.driver.OracleDriver
JDBC URL : jdbc:oracle:thin:@ dbip:port:databasename
說明:驅動程序包名有可能會變
JDBC URL 中黑色字體部分必須原封不動的保留,爲該驅動識別的 URL 格式。紅色字體部分需要根據數據庫的安裝情況填寫。其中各個部分含義如下:
dbip – 爲數據庫服務器的 IP 地址,如果是本地可寫: localhost 或 127.0.0.1 。
port – 爲數據庫的監聽端口,需要看安裝時的配置,缺省爲 1521 。
databasename – 爲數據庫的 SID ,通常爲全局數據庫的名字。
舉例如果要訪問本地的數據庫 allandb ,端口 1521 ,那麼 URL 寫法如下:
jdbc:oracle:thin:@localhost:1521:allandb 下載地址如下 :
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html
SQL Server 數據庫
驅動程序包名: msbase.jar mssqlserver.jar msutil.jar
驅動類的名字: com.microsoft.jdbc.sqlserver.SQLServerDriver
JDBC URL : jdbc:microsoft:sqlserver:// dbip:port;DatabaseName=databasename
說明:驅動程序包名有可能會變
JDBC URL 中黑色字體部分必須原封不動的保留,爲該驅動識別的 URL 格式。紅色字體部需要根據數據庫的安裝情況填寫。其中各個部分含義如下:
dbip – 爲數據庫服務器的 IP 地址,如果是本地可寫: localhost 或 127.0.0.1 。
port – 爲數據庫的監聽端口,需要看安裝時的配置,缺省爲 1433 。
databasename – 數據庫的名字 。
舉例如果要訪問本地的數據庫 allandb ,端口 1433 ,那麼 URL 寫法如下:
jdbc: microsoft: sqlserver:@localhost:1433; DatabaseName =allandb
下載地址: http://www.microsoft.com/downloads/details.aspx
MySQL 數據庫
驅動程序包名: mysql-connector-java-3.1.11-bin.jar
驅動類的名字: com.mysql.jdbc.Driver
JDBC URL : jdbc:mysql:// dbip:port/databasename
說明:驅動程序包名有可能會變
JDBC URL 中黑色字體部分必須原封不動的保留,爲該驅動識別的 URL 格式。紅色字體部需要根據數據庫的安裝情況填寫。其中各個部分含義如下:
dbip – 爲數據庫服務器的 IP 地址,如果是本地可寫: localhost 或 127.0.0.1 。
port – 爲數據庫的監聽端口,需要看安裝時的配置,缺省爲 3306 。
databasename – 數據庫的名字 。
舉例如果要訪問本地的數據庫 allandb ,端口 1433 ,那麼 URL 寫法如下:
jdbc:mysql://localhost:3306/allandb
下載地址: http://dev.mysql.com/downloads/connector/j/
Access 數據庫
驅動程序包名:該驅動程序包含在 JavaSE 中,不需要額外安裝。
驅動類的名字: sun.jdbc.odbc.JdbcOdbcDriver
JDBC URL : jdbc:odbc: datasourcename
說明:該驅動只能工作在 Windows 系統中,首先需要在操作系統中建立一個可以訪問 Access 數據庫的本地數據源 (ODBC) ,如果名字爲 allandb ,那麼 URL 寫法如下:
jdbc:odbc:allandb
現只列舉幾個重要的參數,如下表所示:
參數名稱 參數說明 缺省值 最低版本要求
user 數據庫用戶名(用於連接數據庫) 所有版本
password 用戶密碼(用於連接數據庫) 所有版本
useUnicode 是否使用Unicode字符集,如果參數characterEncoding設置爲gb2312或gbk,本參數值必須設置爲true false 1.1g
characterEncoding 當useUnicode設置爲true時,指定字符編碼。比如可設置爲gb2312或gbk false 1.1g
autoReconnect 當數據庫連接異常中斷時,是否自動重新連接? false 1.1
autoReconnectForPools 是否使用針對數據庫連接池的重連策略 false 3.1.3
failOverReadOnly 自動重連成功後,連接是否設置爲只讀? true 3.0.12
maxReconnects autoReconnect設置爲true時,重試連接的次數 3 1.1
initialTimeout autoReconnect設置爲true時,兩次重連之間的時間間隔,單位:秒 2 1.1
connectTimeout 和數據庫服務器建立socket連接時的超時,單位:毫秒。 0表示永不超時,適用於JDK 1.4及更高版本 0 3.0.1
socketTimeout socket操作(讀寫)超時,單位:毫秒。 0表示永不超時 0 3.0.1
關鍵就在於配置文件,下面看一個樣例app.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置數據源-->
<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/auction"/>
<!-- 指定連接數據庫的用戶名 -->
<property name="user" value="root"/>
<!-- 指定連接數據庫的密碼 -->
<property name="password" value="root"/>
<!-- 指定連接數據庫連接池的最大連接數 -->
<property name="maxPoolSize" value="20"/>
<!-- 指定連接數據庫連接池的最小連接數 -->
<property name="minPoolSize" value="1"/>
<!-- 指定連接數據庫連接池的初始化連接數 -->
<property name="initialPoolSize" value="1"/>
<!-- 指定連接數據庫連接池的連接的最大空閒時間 -->
<property name="maxIdleTime" value="20"/>
</bean>
<!--配置數據庫會話工廠-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/ouya/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
</props>
</property>
</bean>
<!--配置事務管理器-->
<!—-配置Spring 事務管理器代理 -->
<bean id="transactionProxyFactory" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- Hibernate模板 -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!--服務層對象-->
<bean id="us" class="com.ouya.UserService">
<property name="userDao">
<ref local="userDao"/>
</property>
</bean>
<!-- spring代理用戶服務對象 -->
<bean id="userService" parent="transactionProxyFactory">
<!-- 如果上面的服務層對象實現了接口,則此處必須設置proxyTargetClass爲true,否則會報classcast異常 -->
<!--<property name="proxyTargetClass" value="true"/>-->
<property name="target" ref="us"/>
</bean>
<!-- 用戶數據訪問對象DATA ACCESS OBJECT -->
<bean id="userDao" class="com.ouya.UserDAO">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
</beans>
可以看到配置文件的步驟:
1、 配置數據源
2、 配置會話工廠(依賴注入上面的數據源,還要注入hbm映射文件[注意正確的位置]、hibernate屬性文件)
3、 配置事務管理器(依賴注入上面的會話工廠)
4、 Spring中聲明事務管理器(根據需要又可分爲幾種,但都要依賴注入上面的事務管理器,此外還需要配置transationAttributes)
後面的一些普通的bean配置就不用說了
上面的例子中使用的聲明事務管理器是:TransactionProxyFactoryBean,這樣的話我們就需要在後面配置目標bean,比如上面的例子中我們的原服務對象是id爲us的UserService(沒有實現接口),所以我們爲他配置了id爲userService的代理對象(目標bean),程序中使用時只能通過使用代理對象才能實現數據庫操作功能(代理對象的父類是上面聲明的事務管理器,一邊我們使用的時候開啓事務),如果直接使用服務對象就無法開啓事務
程序中調用:UserService us = (UserService) app.getBean("userService");
注:userService就是上面配置的代理對象的id,而不是原服務對象的id
但是如果我們想通過原服務對象的id來使用對象,則我們需要使用代理事務管理器BeanNameAutoProxyCreator(根據beanname自動代理),上面的配置文件需要做改動,做兩件事(當然先要刪除原來配置的TransactionProxyFactoryBean,不然就混亂了,可能會報錯的):
1、 增加一個事務攔截器
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
2、 定義自動代理事務管理器
<!-- 定義BeanNameAutoProxyCreator-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 如果服務層對象是接口實現類,則需要設置proxyTargetClass屬性爲true -->
<!--<property name="proxyTargetClass" value="true"-->
<!-- 指定對滿足哪些bean name的bean自動生成業務代理 -->
<property name="beanNames">
<!-- 下面是所有需要自動創建事務代理的bean-->
<list>
<value>us</value>
</list>
<!-- 此處可增加其他需要自動創建事務代理的bean-->
</property>
<!-- 下面定義BeanNameAutoProxyCreator所需的事務攔截器-->
<property name="interceptorNames">
<list>
<!-- 此處可增加其他新的Interceptor -->
<value>transactionInterceptor</value>
</list>
</property>
</bean>
然後我們在程序中調用時應如下:
UserService us = (UserService) app.getBean("us");
注:注意與上面使用TransactionProxyFactoryBean時的調用區別,此處我們用getbean時直接取原服務層對象的id,不需要去配置目標bea,這也正是
BeanNameAutoProxyCreator(根據bean名稱自動代理)的含義所在
附錄:
1、關於hibernate的屬性詳解:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!-- 以下配置都是使用 jdbc.properties 屬性文件中的配置,而之所以可以這樣寫,就是因爲有 屬性佔位符配置的原因 -->
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 連接池維持的最小的連接個數 -->
<property name="minPoolSize" value="5"/>
<!-- 連接池維持的最大的連接個數 -->
<property name="maxPoolSize" value="20"/>
<!-- 最大空閒時間, 當某個連接在這個時間內沒活動後將從池中移除,前提是池中至少多於最少的連接數: minPoolSize -->
<property name="maxIdleTime" value="1800"/>
<!-- 爲加強準備語句的執行性能,此參數指定被緩存的 PreparedStatement 的個數 -->
<property name="maxStatements" value="50"/>
</bean>
Hibernate 會話廠 SessionFactory
Session 就是用於每次與數據庫會話的,因此需要:
數據庫的配置參數,這些參數就是 上面的數據源指定的! 因此我們只需引用即可: ref="dataSource";
實體映射配置 hibernate.cfg.xml 配置
結果緩存配置(這裏使用的是開源的 ehcache)
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 引用前面定義的數據源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 所有實體映射文件列表, 所有的 hbm.xml 文件 -->
<property name="mappingResources">
<list>
<value>org/springframework/samples/jpetstore/domain/Account.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/Banner.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/Category.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/Inventory.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/Item.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/LineItem.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/Order.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/Product.hbm.xml</value>
<value>org/springframework/samples/jpetstore/domain/Supplier.hbm.xml</value>
</list>
</property>
<!-- 傳統上的 hibernate.cfg.xml 文件的參數放在這裏 -->
<property name="hibernateProperties">
<props>
<!-- 指定數據庫方言 -->
<prop key="hibernate.dialect">${hibernate.dialect}
</prop>
<!-- 是否在日誌中輸出所有Hibernate與數據庫交互的SQL語句 -->
<prop key="hibernate.show_sql">true</prop>
<!-- 是否在日誌中輸出的SQL 語句格式化成易讀形式 -->
<prop key="hibernate.format_sql">true</prop>
<!-- 是否顯示統計形式,一般在測試階段使用 -->
<prop key="hibernate.generate_statistics">true</prop>
<!-- 對於級聯查詢,一次性獲取的級聯深度, @todo 需進一步研究 -->
<prop key="hibernate.max_fetch_depth">2</prop>
<!--
Fetch Size 是設定JDBC的Statement讀取數據的時候每次從數據庫中取出的記錄條數,一般設置爲30、50、100。
Oracle數據庫的JDBC驅動默認的Fetch Size=15,設置Fetch Size設置爲:30、50,性能會有明顯提升,如果繼續增大,
超出100,性能提升不明顯,反而會消耗內存。
-->
<prop key="hibernate.jdbc.fatch_size">100</prop>
<!--
不必等到累計到50個SQL之後才執行.只要事務commit後,不管緩存中有多少條sql語句都要執行.
hibernate.jdbc.batch_size參數只是設定一次最多可以提交多少sql語句的上限,提高sql語句的執行效率
-->
<prop key="hibernate.jdbc.batch_size">50</prop>
<!--
(1)create 在每次SesstionFactory 構建時(一般是應用重啓時,或者伴隨着應用服務器重啓時),先將之前數據庫中的所有數據全
部清空,後緊跟着根據所有的hbm.xml 映射文件重新創建新的數據庫表
(2)create-drop 除了create 的所有含義之外,在每次應用的退出前,將進行一次數據空清空。因此這個配置將有兩次清空操作,
一次是退出,一次是啓動時。
(3)update
如果在開發階段理髮了實體對象的映射文件(hbm.xml) 的定義後,此配置將後臺的數據庫表進行更新(如增加表的列)
(4)validate
用於校驗現有的表與現有的配置是否一致。
-->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- 見下面的解釋 -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!--結果緩存配置:- 將ehcache.xml 置於 classpath 中- 如果不設置“查詢緩存”,
那麼hibernate只會緩存使用load()方法獲得的單個持久化對象,如果想緩存使用findall()、 list()、
Iterator()、createCriteria()、createQuery()等方法獲得的數據結果集的話,就需要設置
hibernate.cache.use_query_cache true 才行- 在Hbm文件中添加<cache usage="read-only"/>-
如果需要“查詢緩存”,還需要在使用Query或Criteria()時設置其setCacheable(true);屬性-->
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
<!-- 爲解決 merge()方法語義的歧義 @todo 以後進一步解析或者你可以看一下相應的文檔 -->
<property name="eventListeners">
<map><entry key="merge">
<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</entry></map>
</property>
</bean>
2、Spring的transactionAttributes
PROPAGATION_REQUIRED:支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
PROPAGATION_SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
PROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。
hibernate+spring配置
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.