Spring4-4-整合Hibernate

一.整合目標(biāo)

(1)又IOC容器來管理Hibernate的SessionFactory
(2)讓Hibernate使用上Spring的生命式事務(wù)

二.整合步驟

1.加入hibernate
(1)加入jar包


Paste_Image.png

(2)新建hibernate配置文件hibernate.cfg.xml

    <session-factory>
        <!-- 配置hibernate基本屬性 -->
        <!-- 1.數(shù)據(jù)源配置到IOC容器中,所以在此不需要配置數(shù)據(jù)連接相關(guān)信息 -->
        <!-- 2.關(guān)聯(lián)hbm.xml也在IOC容器配置SessionFactory實例時在進行配置 -->
        
        <!-- 3.配置hibernate的基本屬性:方言,SQL顯示及格式,生成數(shù)據(jù)表的策略以及二級緩存 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        
    </session-factory>

(3)編寫持久化類以及對應(yīng)的.hbm.xml映射文件

Paste_Image.png

2.加入Spring
(1)加入jar包
Paste_Image.png

(2)配置Spring配置文件applicationContext.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:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    <!-- Spring與Hibernate整合 -->
    
    <context:component-scan base-package="lxf.spring.hibernate"></context:component-scan>
    <!-- 配置數(shù)據(jù)源 -->
     <!-- 導(dǎo)入屬性文件 classpath代表類路徑 -->
    <context:property-placeholder location="classpath:db.properties"/> 
    <!--  配置c3p0數(shù)據(jù)源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <!-- 使用外部屬性文件的屬性 -->
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        
        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize"  value="${jdbc.maxPoolSize}"></property>
    </bean>
    
    <!-- 配置Hibernate的SessionFactory實例 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
             <!-- 配置數(shù)據(jù)源屬性 -->
            <property name="dataSource" ref="dataSource"></property>
            <!-- 配置Hibernate 配置文件的位置及名稱
            <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>-->
            <!-- hibernate配置文件的內(nèi)容也可以作為Spring的屬性配置 -->
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                    <prop key="hibernate.hbm2ddl.auto">true</prop>
                </props>
            </property>
            <!-- 配置 Hibernate映射文件的位置以及名稱,可以使用通配符-->
            <property name="mappingLocations" value="classpath:lxf/spring/hibernate/entiries/*.hbm.xml"></property>
    </bean>
    
    <!-- 配置Spring的聲明式事務(wù) -->
    <!-- 1.配置事務(wù)管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <!-- 2.配置事務(wù)屬性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="get*" read-only="true"/>
                <tx:method name="*" />
            </tx:attributes>
    </tx:advice>
    <!-- 3.配置事務(wù)切點,并把切點和事務(wù)屬性關(guān)聯(lián) -->
    <aop:config>
        <!-- 配置切入點 -->
        <aop:pointcut expression="execution( * lxf.spring.hibernate.service.impl.*.*(..))" id="txPointCut"/>
        <!-- 將切入點和屬性關(guān)聯(lián) -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
</beans>

(3)單元測試SpringHibernateTest.java

/**
 * 單元測試Spring整合hibernate類
 * @author lxf
 */
public class SpringHibernateTest {
    private ApplicationContext ctx = null;
    {
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
    /**
     * 測試數(shù)據(jù)源連接
     * @throws SQLException 
     */
    @Test
    public void testDataSource() throws SQLException {
        DataSource dataSource = (DataSource)ctx.getBean("dataSource");
        System.out.println(dataSource.getConnection());     
    }
}

如果配置沒有問題,單元測試會成功,而且會自動在數(shù)據(jù)庫中建立那兩張表

三.Spring hibernate事務(wù)流程

 * 1.在方法開始之前
 * (1)獲取Session
 * (2)把Session和當(dāng)前線程綁定,這樣就可以在Dao中使用
 *              SessionFactory的getCurrentSession方法獲取Session了
 * (3)開啟事務(wù)
 * 
 * 2.若方法正常結(jié)束,則沒有出現(xiàn)異常,則
 * (1)提交事務(wù)
 * (2)使和當(dāng)前線程的Session解除綁定
 * (3)關(guān)閉Session
 * 
 * 3.若方法出現(xiàn)異常,則:
 * (1)回滾事務(wù)
 * (2)使和當(dāng)前線程的Session解除綁定
 * (3)關(guān)閉Session

Spring Hibernate事務(wù)實現(xiàn)除了BookShopDaoImpl.java與其他文件不一樣,其他都一樣:

package lxf.spring.hibernate.dao.impl;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import lxf.spring.hibernate.dao.BookShopDao;
import lxf.spring.hibernate.exception.BookStockException;
import lxf.spring.hibernate.exception.UserAcountException;

@Repository("bookShopDao")
public class BookShopDaoImpl implements BookShopDao {
      
    @Autowired
    private SessionFactory sessionFactory;
    
    //獲得和當(dāng)前線程綁定的session
    public Session getSession()
    {
       return sessionFactory.getCurrentSession();
    }

    @Override
    public double findBookPriceBookId(Integer bookId) {
        String hql ="SELECT b.price FROM Books b WHERE b.book_id = ?";
        Query query = getSession().createQuery(hql).setInteger(0, bookId);
        return (double)query.uniqueResult();
    }

    @Override
    public void updateBookStock(Integer bookId) {
           //先查詢是否有庫存
            String hql ="SELECT b.stock  FROM Books b WHERE b.book_id= ?";
            Query query = getSession().createQuery(hql).setInteger(0, bookId);
            int stock = (int)query.uniqueResult();
            if(stock <= 0)
            {
                throw new BookStockException("圖書庫存不足!");
            }
            //修改庫存
            String hql2 = "UPDATE Books b SET b.stock =b. stock-1 WHERE b.book_id = ?";
            getSession().createQuery(hql2).setInteger(0, bookId).executeUpdate();           
    }

    @Override
    public void updateUserAccount(Integer userId, double price) {
        //先查詢賬戶余額是否夠
        String hql ="SELECT a.balance  FROM Acount a WHERE a.id = ?";
        Query query = getSession().createQuery(hql).setInteger(0, userId);
        double balance = (double)query.uniqueResult();
        if(balance <= 0)
        {
            throw new UserAcountException("用戶賬戶余額不足!");
        }
        //修改賬戶余額
        String hql2 = "UPDATE Acount a SET a.balance = a.balance-? WHERE a.id = ?";
        getSession().createQuery(hql2).setDouble(0, price).setInteger(1, userId).executeUpdate();        
    }
}

代碼演示點擊

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容