學習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處理的對象分爲持久態和遊離態,當你創建一個匿名對象用於刪除時,如果數據庫其他字段設置不允許爲空,而你創建的匿名對象其他字段爲空時,在刪除操作過程前的對象持久化,則會出現問題,切記切記
聲明:以上英文字符串除了代碼段是貼過來的不會出錯外,其餘純手工(筆者外語學的是俄語。。。),如有出錯,還望海涵
筆者也是在學習階段,有什麼說錯的地方或者描述不詳細的地方還望指出,一塊兒學習