Spring4整合Hibernate4详细示例
来源:互联网 发布:淘宝1分钱抢购在哪 编辑:程序博客网 时间:2024/05/17 08:56
1. Spring整合Hibernate,主要是解决什么问题?
a、让Spring提供的IOC容器来管理Hibernate的SessionFactory
b、让Hibernate使用Spring提供的声明式事物
2. 整合步骤:
新建一个Java工程,并新建用来保存依赖jar包的lib目录
①. 加入Hibernate支持:
1. 加入Hibernate的required的jar包:
antlr-2.7.7.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-4.0.2.Final.jar
hibernate-core-4.2.5.Final.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
javassist-3.15.0-GA.jar
jboss-logging-3.1.0.GA.jar
jboss-transaction-api_1.1_spec-1.0.1.Final.jar
2.加入MySQL与C3p0连接池支持:
c3p0-0.9.2.1.jar
mchange-commons-java-0.2.3.4.jar
mysql-connector-java-5.1.7-bin.jar
注意:jar包加入之后,需要全部选中,右键-》BuildPath,将其导入
3.添加Hibernate的配置文件(hibernate.cfg.xml):
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <!-- 配置hibernate基本信息 --> <!-- 1.数据源配置在IOC容器中,此处不需要额外配置 --> <!-- 2.关联的.hbm.xml文件也在IOC容器配置SessionFactory时配置 --> <!-- 3.此处配置hibernate的基本信息:数据库方言、SQL显示及格式化,及生成数据表的策略,二级缓存等 --> <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></hibernate-configuration>
4. 创建测试使用的持久化类以及生成Hibernate的映射文件
本例所用到的持久化类以其映射文件如下:
public class Book { private int id;private String bookName;private String isbn;private float price;private int stock;public int getId() {return id;}public void setId(int 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 float getPrice() {return price;}public void setPrice(float price) {this.price = price;}public int getStock() {return stock;}public void setStock(int stock) {this.stock = stock;}}
public class Account { private int id;private String username;private float balance;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public float getBalance() {return balance;}public void setBalance(float balance) {this.balance = balance;}}
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2015-11-15 21:48:02 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping> <class name="com.elgin.spring.hibernate.entity.Book" table="SH_BOOK"> <id name="id" type="int"> <column name="ID" /> <generator class="native" /> </id> <property name="bookName" type="java.lang.String"> <column name="BOOKNAME" /> </property> <property name="isbn" type="java.lang.String"> <column name="ISBN" /> </property> <property name="price" type="float"> <column name="PRICE" /> </property> <property name="stock" type="int"> <column name="STOCK" /> </property> </class></hibernate-mapping>
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2015-11-15 21:48:02 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping> <class name="com.elgin.spring.hibernate.entity.Account" table="SH_ACCOUNT"> <id name="id" type="int"> <column name="ID" /> <generator class="native" /> </id> <property name="username" type="java.lang.String"> <column name="USERNAME" /> </property> <property name="balance" type="float"> <column name="BALANCE" /> </property> </class></hibernate-mapping>
②. 加入Spring支持:
1. 加入Spring的required的jar包:
com.springsource.net.sf.cglib-2.2.0.jarcom.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.3.jar
spring-aop-4.1.0.RELEASE.jar
spring-aspects-4.1.0.RELEASE.jar
spring-beans-4.1.0.RELEASE.jar
spring-context-4.1.0.RELEASE.jar
spring-core-4.1.0.RELEASE.jar
spring-expression-4.1.0.RELEASE.jar
spring-jdbc-4.1.0.RELEASE.jar
spring-orm-4.1.0.RELEASE.jar
spring-test-4.1.0.RELEASE.jar
spring-tx-4.1.0.RELEASE.jar
spring-web-4.1.0.RELEASE.jar
spring-webmvc-4.1.0.RELEASE.jar
同样需要BuildPath!
2.加入Spring的配置文件:applicationContext.xml
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.1.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.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 配置注解自动扫描的包 --> <context:component-scan base-package="com.elgin.spring.hibernate"></context:component-scan> <!-- 配置数据源 --> <!-- 导入资源文件 --> <context:property-placeholder location="classpath:db.properties"/> <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,通过spring提供的 LocalSessionFactoryBean配置--> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- 配置依赖的数据源属性 --> <property name="dataSource" ref="dataSource"></property> <!-- hibernate 配置文件的路径 --> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> <!-- 配置hibernate映射文件的路径,可以使用通配符 --> <property name="mappingLocations" value="classpath:com/elgin/spring/hibernate/entity/*.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="purchase" propagation="REQUIRES_NEW"/> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 配置事物切点,并把事物属性和切点关联起来 --> <aop:config> <aop:pointcut expression="execution(* com.elgin.spring.hibernate.service.*.*(..))" id="txPointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> </beans>依赖的数据库配置文件db.properties:
jdbc.user=rootjdbc.password=root123jdbc.driverClass=com.mysql.jdbc.Driverjdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring_hibernatejdbc.initPoolSize=5jdbc.maxPoolSize=10至此,Spring的配置、Hibernate的配置、以及二者整合的相关配置都配置完毕。下面通过代码测试。
3.整合测试:
工程目录:
新建上述各个目录:
1. 在dao下面新建接口:
public interface BookShopDao { /** * 根据书号获取书的单价 * @param isbn * @return */public float findPriceByIsbn(String isbn);/** * 更新书的库存,使书号对应的书本减少n本 * @param isbn * @param n */public void updateBookStock(String isbn,int n);/** * 更新账户余额,使当前账户金额减少 price*n * @param username * @param price * @param n * @throws BalanceNotEnough */public void updateAccount(String username,float price,int n);}对应的在impl下完成上述接口的实现类(注解@Repository,用来标注持久层,同时表示此组件交给spring的IOC容器管理)
在使用spring的相关注解时,需要在spring的配置文件中开启注解自动扫描:
<!-- 配置注解自动扫描的包 --> <context:component-scan base-package="com.elgin.spring.hibernate"/>
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.elgin.spring.hibernate.dao.BookShopDao;import com.elgin.spring.hibernate.exception.BalanceNotEnough;import com.elgin.spring.hibernate.exception.BookStockNotEnoughException;@Repositorypublic class BookShopDaoImpl implements BookShopDao { @Autowiredprivate SessionFactory sessionfactory;/** * 获取与当前线程绑定的session * @return */private Session getSession(){return sessionfactory.getCurrentSession();}@Overridepublic float findPriceByIsbn(String isbn) {String hql="select b.price from Book b where b.isbn=?";float price=(float) getSession().createQuery(hql).setString(0, isbn).uniqueResult();return price;}@Overridepublic void updateBookStock(String isbn, int n) {//验证书的库存是否充足String hq="Select b.stock from Book b where b.isbn=?";int stock=(int) getSession().createQuery(hq).setString(0, isbn).uniqueResult();if(stock < n){ throw new BookStockNotEnoughException("库存不足");}String hql="update Book b set b.stock=b.stock-? where b.isbn=?";Query query=getSession().createQuery(hql).setInteger(0, n).setString(1, isbn);query.executeUpdate();}@Overridepublic void updateAccount(String username, float price, int n) {//验证余额是否足够String hql="select a.balance from Account a where a.username=?";float balance=(float) getSession().createQuery(hql).setString(0, username).uniqueResult(); if(balance < n*price){ throw new BalanceNotEnough("余额不足"); } String hql1="update Account a set a.balance=a.balance-? where a.username=?"; getSession().createQuery(hql1).setFloat(0, n*price).setString(1, username).executeUpdate();}}实现类中用到的2个异常类:
public class BalanceNotEnough extends RuntimeException {/** * */private static final long serialVersionUID = 1L;public BalanceNotEnough(String msg) {super(msg);}}
public class BookStockNotEnoughException extends RuntimeException {/** * */private static final long serialVersionUID = 1L; public BookStockNotEnoughException(String msg) {super(msg);}}在service包下新建下面的接口:
public interface BookShopService { /** 用户购买n本书 * @param username * @param isbn * @param n */public void purchase(String username,String isbn,int n);}在service.impl下完成它的实现类(@Service 用来标注service层,表示此组件为service并交给Spring的IOC容器管理;@Autowired 自动注入 ,表示此对象由IOC容器负责初始化并注入):
@Servicepublic class BookShopSeviceImpl implements BookShopService {@Autowiredprivate BookShopDao bookShopDao;/** * Spring Hibernate的事物流程 * 1、方法开始之前 * ①. 获取session * ②. 把Session与当前线程绑定,这样就可以使用sessionFactory的getCurrentSession()方法来获取session了 * ③. 开启事务 * * 2、若方法正常结束,未出现异常,则 * ①.提交事物 * ②.把session与当前线程解除绑定 * ③.关闭session * * 3、若方法执行出现异常,则 * ①.回滚事务 * ②.把session与当前线程解除绑定 * ③.关闭session */@Overridepublic void purchase(String username, String isbn, int n) {float price=bookShopDao.findPriceByIsbn(isbn);bookShopDao.updateBookStock(isbn, n);bookShopDao.updateAccount(username, price, n);}}编写单元测试类:
若想使用如下配置进行单元测试,必须要加入spring单元测试的jar包:spring-test-4.1.0.RELEASE.jar
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringHibernateTest { @Autowired private BookShopService bookShopService; @Test public void testPurchaseBook(){ bookShopService.purchase("aaa", "java-1122", 2); }}首先,注释掉测试方法中额外的代码,启动单元测试,让Hibernate生成用到的数据表:SH_BOOK 与SH_ACCOUNT
让后在2个表中各加入测试所需要的数据如下图:
运行上述单元测试方法,执行成功,查看数据库,book的库存STOCK变为43,account中的账户余额变为130.
再次运行,程序抛出异常:
com.elgin.spring.hibernate.exception.BalanceNotEnough: 余额不足
查看数据库发现:
book的库存STOCK仍旧为43,account中的账户余额仍旧为130.
这就是spring的事物的作用,程序出现异常,回滚事务,关闭session。
本次整合测试代码:
本次整合测试代码
- Spring4整合Hibernate4详细示例
- Spring4整合Hibernate4详细示例
- Struts2、Spring4、Hibernate4整合 超详细教程
- Struts2+Hibernate4+Spring4整合
- spring4如何整合hibernate4
- Spring4+Hibernate4整合
- spring4整合hibernate4
- spring4 hibernate4(5) 整合
- spring4, hibernate4 整合问题
- Spring4 整合 Hibernate4
- strut2+hibernate4+spring4整合
- Spring4+Hibernate4整合问题解决
- spring4+hibernate4+struts2整合
- Spring4 整合Hibernate4,Struts2
- Spring4整合Hibernate4.3
- Spring4+Hibernate4整合配置
- springMVC+hibernate4.3+spring4整合
- Spring4.x+Hibernate4.x整合
- CSS制作水平垂直居中对齐
- Android Spinner选择同一个选项时触发onItemSelected事件
- 04-树5- Root of AVL Tree
- Linux内核模块编程-系统调用拦截
- 欢迎使用CSDN-markdown编辑器
- Spring4整合Hibernate4详细示例
- [TwistedFate]UISegmentedControl
- linux 压缩解压缩命令
- Webkit之RenderLayer创建的场景
- nexus安装
- Boosting分类器
- Linux内存管理和性能学习笔记(一):内存测量与堆内存
- String对象和StringBuffer对象末尾追加元素空间效率问题
- Activity的生命进程