Spring與Hibernate整合小細節與測試問題

學習SSH框架的童鞋們肯定有一個學習過程,此篇文章詳述了關於Spring和Hibernater整合會遇到的一些小問題,廢話不多說,接下來開始正文

首先貼出來文件目錄結構:


1:Spring和Hibernate支持添加順序

首先添加Spring支持,而後在添加Hibernate支持時,一定要將Hibernate的工具包添加入Spring configuration file中,點擊下一步中勾選Existing Spring configuration file。

這兩步作用則是將以往Hibernate.cfg.xml文件中的內容遷移至Spring配置文件中,完成配置文件的整合(注意文件頭部可能會因爲某些包未引入而產生文件找不到錯誤)

2:整合配合文件中配置事務:聲明式事務配置

作用是使用session進行數據庫操作前後,無需手動調用beginTransaction和事務提交,交由Spring管理,具體配置如下:

<!-- 聲明式事務配置 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
	</bean>
<!-- AOP切面聲明事務管理 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
		<!-- 支持當前事務,如果執行到save開頭的任何方法時沒有事務則開啓一個事務-->
			<tx:method name="save*" propagation="REQUIRED" /> 
			<!-- 支持當前事務,如果執行到update開頭的任何方法時沒有事務則開啓一個事務 -->
			<tx:method name="update*" propagation="REQUIRED" />
			<!-- 支持當前事務,如果執行到add開頭的任何方法時沒有事務則開啓一個事務 -->	
			<tx:method name="add*" propagation="REQUIRED" />
			<!-- 支持當前事務,如果執行到delete開頭的任何方法時沒有事務則開啓一個事務 -->
			<tx:method name="delete*" propagation="REQUIRED" />
			<!-- 支持當前事務,查詢沒有事務,就以非事務方式執行。只讀 -->
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
			<!-- 支持當前事務,查詢沒有事務,就以非事務方式執行。只讀 -->
			<tx:method name="find*" propagation="SUPPORTS" read-only="true" /> 

			<tx:method name="*" read-only="true" propagation="NOT_SUPPORTED" />
		</tx:attributes>
	</tx:advice>

3:類通過配置標籤bean註冊入ApplicationContext.xml

類的註冊分爲有無值注入兩種

簡單的一種無值注入,也就是類中沒有需要通過xml實例對象注入到類中的:

<span style="white-space:pre">	</span><bean id="advice" class="com.aop.advice.Advice"></bean>
複雜點兒的有值注入,也就是類中有私有數據成員爲其他類的對象,這時就需要通過xml實例對象然後進行注入:

<span style="white-space:pre">	</span><bean id="userDao1" class="com.hp.dao.impl.UserDaoJDBCImpl" />
	<bean id="userservice" class="com.hp.service.UserService">
		<property name="userDao" ref="userDao1" />
	</bean>
上貼代碼,就是在UserService類中有一個私有數據成員:private UserDaoJDBCImpl userDao;

過程是:通過bean:userservice獲取對象時,通過配置文件的屬性ref指代的bean,映射到相應的類,實例一個對象,而後進行對象注入到UserService中,實例出來一個UserService對象。

需要注意的是,注入時找的注入方法:應爲set+name屬性首字母大寫(ref屬性映射的類);例如:以上例子找的方法應該爲

public void setUserDao(UserDaoJDBCImpl userDao);

4:SessionFactory注入

session工廠注入點:

考慮到哪兒用到session就注入到哪個類中,可得到結果注入位置應爲dao.impl,即應在每個對數據庫操作的實現類中

注入方式:

1:hibernate配置整合入spring框架中時,spring配置文件中有bean建立了對SessionFactory

<span style="white-space:pre">	</span><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName"
			value="com.mysql.jdbc.Driver">
		</property>
		<property name="url" value="jdbc:mysql://localhost:3306/shop"></property>
		<property name="username" value="sa"></property>
		<property name="password" value="123456"></property>
	</bean>
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<!-- 保證數據庫連接通暢 -->
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<!-- 常規屬性設置,方言(本地化處理) -->
		<property name="hibernateProperties">
			<props>
				<!-- 設置Hibernate方言 -->
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<!-- 是否打印sql -->
				<prop key="hibernate.show_sql">true</prop>
				<!-- 格式化sql -->
				<prop key="hibernate.format_sql">true</prop>
				<!-- 是否自動更新表 -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="hibernate.current_session_context_class">thread</prop>
				<!-- 最大抓取深度,如果爲0,則關閉默認的外連接抓取。建議值爲0-3 -->
				<prop key="hibernate.max_fetch_depth">1</prop>
				<!-- 用於生成有助於調試的註釋信息,默認爲關閉 -->
				<prop key="hibernate.use_sql_comments">true</prop>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
			</props>
		</property>

2:仔細閱讀標註3的有值注入方式,在property 標籤中ref引用SessionFactory的bean id

<span style="white-space:pre">	</span><bean id="productDao" class="com.aop.dao.impl.ProductDaoImpl">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>

3:在Spring框架中自帶有對Session工程的管理類HibernateTemplate,所以值注入的是SessionFactory,但需要轉換成HibernateTemplate進行管理

ProductDaoImpl類中添加HibernateTemplate屬性及必要的注入方法:

<span style="white-space:pre">	</span>//增加hibernateTemplate屬性
	private HibernateTemplate hibernateTemplate;
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.hibernateTemplate =
				new HibernateTemplate(sessionFactory);
	}
然後你就可以把hibernateTemplate當做session來進行數據庫操作了,例如:

<span style="white-space:pre">	</span>public void deleteCategory(Category category) {
		hibernateTemplate.delete(category);
	}
由於前面已經講述了在xml中配置聲明式事務,所以在操作是無需手動控制事務的開啓和提交

5:測試時小問題

之所以貼出來delete刪除方法,是提醒各位需要注意,hibernate處理的對象分爲持久態和遊離態,當你創建一個匿名對象用於刪除時,如果數據庫其他字段設置不允許爲空,而你創建的匿名對象其他字段爲空時,在刪除操作過程前的對象持久化,則會出現問題,切記切記


聲明:以上英文字符串除了代碼段是貼過來的不會出錯外,其餘純手工(筆者外語學的是俄語。。。),如有出錯,還望海涵
筆者也是在學習階段,有什麼說錯的地方或者描述不詳細的地方還望指出,一塊兒學習



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章