阶段整合---hibernate与spring整合

来源:互联网 发布:asp.net与php 编辑:程序博客网 时间:2024/06/18 07:19

一.概述

 spring整合hibernate的优点:
1.由IOC管理hibernate的sessionFactory

2.由hibernate使用上spring的声明事务

二.案例分析


用户与书的案例
 
整合步骤:
一.加入hibernate
1.加入hibernate所需jar包

        
2.数据库相关jar包          
         数据库连接jar包
         mysql-connector-java-5.0.8-bin.jar

         c3p0数据源jar包
          
 3.加入二级缓存jar包(如有需要)

这时候需要加入ehcache.xml文件
 4.建立hibernate.cfg.xml文件
       
<hibernate-configuration>   <!--由于数据源与.hbm.xml文件已经转移到ioc容器中,所以这里只配置基础的项 -->    <session-factory>    <!--配置数据库方言 -->    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>    <!--配置sql语言  -->     <property name="hibernate.show_sql">true</property>    <!-- 配置sql语言格式化 -->    <property name="hibernate.format_sql">true</property>    <!-- 配置数据表生成策略 -->    <property name="hibernate.hbm2ddl.auto">update</property>    <!-- 二级缓存设置 -->    <!-- 启用二级缓存 -->    <property name="cache.use_second_level_cache">true</property>    <!-- 启用查询缓存 -->    <property name="cache.use_query_cache">true</property>    <!-- 配置二级缓存产品 -->    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>    </session-factory></hibernate-configuration>

5.根据持久化类生成hbm.xml文件
持久化类
(1)用户类:
public class Account {private int accountId;//用户idprivate String accountName;//用户名private double balance;//用户余额public int getAccountId() {return accountId;}public void setAccountId(int accountId) {this.accountId = accountId;}public String getAccountName() {return accountName;}public void setAccountName(String accountName) {this.accountName = accountName;}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}}

(2)书类
    
public class Book {private Integer id;//id    private String bookName;//书名    private String isbn;//书编号    private int price;//价格    private int stock;//库存public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public int getStock() {return stock;}public void setStock(int stock) {this.stock = stock;}    }

生成对应的hbm.xml文件
Account.hbm.xml
<hibernate-mapping>    <class name="com.eduask.chp.bean.Account" table="ACCOUNTS">    <cache usage="read-write"/>        <id name="accountId" type="int">            <column name="ACCOUNT_ID" />            <generator class="native" />        </id>        <property name="accountName" type="java.lang.String">            <column name="ACCOUNT_NAME" />        </property>        <property name="balance" type="double">            <column name="BALANCE" />        </property>    </class></hibernate-mapping>

Book.hbm.xml
<hibernate-mapping>    <class name="com.eduask.chp.bean.Book" table="BOOK">    <cache usage="read-write"/>        <id name="id" type="java.lang.Integer">            <column name="ID" />            <generator class="native" />        </id>        <property name="bookName" type="java.lang.String">            <column name="BOOK_NAME" />        </property>        <property name="isbn" type="java.lang.String">            <column name="ISBN" />        </property>        <property name="price" type="int">            <column name="PRICE" />        </property>        <property name="stock" type="int">            <column name="STOCK" />        </property>    </class></hibernate-mapping>

二.加入spring

1.加入spring相关jar包



2.新建applicationContext配置文件
(1)配置数据源 

这个时候需要引用db.properties里的属性
所以新建db.properties
本人用的是mysql数据库
所以对应的db.properties文件是
jdbc.username=root
jdbc.password=root
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/SH

 
<context:property-placeholder location="classpath:db.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property><property name="driverClass" value="${jdbc.driver}"></property><property name="jdbcUrl" value="${jdbc.url}"></property></bean>

配置完成,测试
public void test() throws SQLException {ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");DataSource ds=app.getBean(DataSource.class);System.out.println(ds.getConnection());}
输出正确代表配置成功

 
(2)
<!-- 配置sessionFactory, 通过spring提供的--><bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><property name="configLocation" value="classpath:hibernate.cfg.xml"></property><property name="mappingLocations" value="classpath:com/eduask/chp/bean/*.hbm.xml"></property></bean>

(3)
<!-- 配置spring声明式事务 --><!-- 配置事务管理器 --><bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"></property></bean><!-- 配置事务属性 --><tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes>    <tx:method name="get*" read-only="true"/>    <tx:method name="*"/>  </tx:attributes></tx:advice><!-- 配置事务切点,并把切点与事务属性关联起来 --><aop:config>  <aop:pointcut expression="execution(* com.eduask.chp.service.*.*(..))" id="pointCut"/>  <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/></aop:config></beans>

总的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/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"><!-- 自动扫描包 --><context:component-scan base-package="com.eduask.chp"></context:component-scan><!-- 配置数据源 --><!-- 导入db.properties资源文件 --><context:property-placeholder location="classpath:db.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property><property name="driverClass" value="${jdbc.driver}"></property><property name="jdbcUrl" value="${jdbc.url}"></property></bean><!-- 配置sessionFactory, 通过spring提供的--><bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><property name="configLocation" value="classpath:hibernate.cfg.xml"></property><property name="mappingLocations" value="classpath:com/eduask/chp/bean/*.hbm.xml"></property></bean><!-- 配置spring声明式事务 --><!-- 配置事务管理器 --><bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"></property></bean><!-- 配置事务属性 --><tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes>    <tx:method name="get*" read-only="true"/>    <tx:method name="*"/>  </tx:attributes></tx:advice><!-- 配置事务切点,并把切点与事务属性关联起来 --><aop:config>  <aop:pointcut expression="execution(* com.eduask.chp.service.*.*(..))" id="pointCut"/>  <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/></aop:config></beans>

<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 自动扫描包 -->
<context:component-scan base-package="com.eduask.chp"></context:component-scan>


<!-- 配置数据源 -->
<!-- 导入db.properties资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
</bean>
<!-- 配置sessionFactory, 通过spring提供的-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="mappingLocations" value="classpath:com/eduask/chp/bean/*.hbm.xml"></property>
</bean>
<!-- 配置spring声明式事务 -->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
    <tx:method name="get*" read-only="true"/>
    <tx:method name="*"/> 
 </tx:attributes>
</tx:advice>
<!-- 配置事务切点,并把切点与事务属性关联起来 -->
<aop:config>
  <aop:pointcut expression="execution(* com.eduask.chp.service.*.*(..))" id="pointCut"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans>

<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 自动扫描包 -->
<context:component-scan base-package="com.eduask.chp"></context:component-scan>


<!-- 配置数据源 -->
<!-- 导入db.properties资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
</bean>
<!-- 配置sessionFactory, 通过spring提供的-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="mappingLocations" value="classpath:com/eduask/chp/bean/*.hbm.xml"></property>
</bean>
<!-- 配置spring声明式事务 -->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
    <tx:method name="get*" read-only="true"/>
    <tx:method name="*"/> 
 </tx:attributes>
</tx:advice>
<!-- 配置事务切点,并把切点与事务属性关联起来 -->
<aop:config>
  <aop:pointcut expression="execution(* com.eduask.chp.service.*.*(..))" id="pointCut"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans><?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/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 自动扫描包 -->
<context:component-scan base-package="com.eduask.chp"></context:component-scan>


<!-- 配置数据源 -->
<!-- 导入db.properties资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
</bean>
<!-- 配置sessionFactory, 通过spring提供的-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="mappingLocations" value="classpath:com/eduask/chp/bean/*.hbm.xml"></property>
</bean>
<!-- 配置spring声明式事务 -->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
    <tx:method name="get*" read-only="true"/>
    <tx:method name="*"/> 
 </tx:attributes>
</tx:advice>
<!-- 配置事务切点,并把切点与事务属性关联起来 -->
<aop:config>
  <aop:pointcut expression="execution(* com.eduask.chp.service.*.*(..))" id="pointCut"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans>


<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 自动扫描包 -->
<context:component-scan base-package="com.eduask.chp"></context:component-scan>


<!-- 配置数据源 -->
<!-- 导入db.properties资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
</bean>
<!-- 配置sessionFactory, 通过spring提供的-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="mappingLocations" value="classpath:com/eduask/chp/bean/*.hbm.xml"></property>
</bean>
<!-- 配置spring声明式事务 -->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
    <tx:method name="get*" read-only="true"/>
    <tx:method name="*"/> 
 </tx:attributes>
</tx:advice>
<!-- 配置事务切点,并把切点与事务属性关联起来 -->
<aop:config>
  <aop:pointcut expression="execution(* com.eduask.chp.service.*.*(..))" id="pointCut"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans>


三.建立两层逻辑结构

按常规分三层,这里只整合SH,所以不再加控制web层了

Dao层

新建Dao接口:

package com.eduask.chp.dao;import java.util.List;import com.eduask.chp.bean.Book;public interface BookDao {public double getBookPrice(String  isbn);//获取书本的价格public void updateBookStock(String isbn);//修改书本库存public void updateAccount(double price,String account);//修改余额}

它的实现类:

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 com.eduask.chp.bean.AccountException;import com.eduask.chp.bean.Book;import com.eduask.chp.bean.BookStockException;@Repositorypublic class BookImp implements BookDao{@Autowiredprivate SessionFactory sessionFactory;//获取spring容器中的sessionFactoryprivate Session getSession() {System.out.println("1");return sessionFactory.getCurrentSession();//通过sessionFactory生成session}@Overridepublic double getBookPrice(String isbn) {//获取书价格String hql="select b.price from Book b where b.isbn=?";Query query=getSession().createQuery(hql).setString(0, isbn);return  (double)query.uniqueResult() ;}@Overridepublic void updateBookStock(String isbn) {//修改库存String hqlStock="select b.stock from Book b where b.isbn=?";int stock=(int) getSession().createQuery(hqlStock).setString(0, isbn).uniqueResult();if (stock==0) {throw new BookStockException("库存不足");}String hql="UPDATE Book b SET b.stock=b.stock-1 where b.isbn=?";getSession().createQuery(hql).setString(0, isbn).executeUpdate();}@Overridepublic void updateAccount(double price, String account) {//修改用户余额String hqlBalance="select a.balance from Account a where a.accountName=?";double  balance=(double) getSession().createQuery(hqlBalance).setString(0, account).uniqueResult();System.out.println(balance);if (balance<price) {throw new AccountException("余额不足");}String hql="update Account a set a.balance=a.balance-? where a.accountName=?";getSession().createQuery(hql).setDouble(0, price).setString(1, account).executeUpdate();}}

Service层

接口
public interface BookService{public void purchasing(String isbn,String account);//单个买}

实现类
package com.eduask.chp.service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.eduask.chp.dao.BookDao;@Servicepublic class BookServiceImp implements BookService{@Autowiredprivate BookDao bd;@Overridepublic void purchasing(String isbn, String account) {double price=bd.getBookPrice(isbn);//得到书的单价bd.updateBookStock(isbn);bd.updateAccount(price, account);}}

接口
public interface Cashier {//一次性买多次public void checkout(String username, List<String> isbns);}

实现类

package com.eduask.chp.service;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class CashierImp implements Cashier{@Autowiredprivate BookService bs;@Overridepublic void checkout(String username, List<String> isbns) {for (String isbn : isbns) {bs.purchasing(isbn, username);}}}