标签:style blog http io ar color os 使用 sp
1. 让Spring的IOC容器生成Hibernate的SessionFactory。
2. 让Hibernate使用上Spring的事务声明。
1. 加入Hibernate。
(1) 导入Hibernate开发包。
(2) 编写Hibernate配置文件:hibernate.cfg.xml。我们在文件只需要配置方言、SQL显示及其格式化、生成数据库表的策略以及二级缓存的
的相关信息。对于数据源信息我们配置到Spring的配置文件中,让Spring的IOC容器来管理数据源,关联的映射文件.hbm.xml也配置在Spring
的配置文件中。
2. 加入Spring
(1) 导入开发包。
(2) 编写Spring的配置文件。配置数据源、配置Hibernate的SessionFactory、配置Spring的事务声明。
模拟情景:用户去买书(规定每次只能买一本书),用户的账户余额会减少,同时书本的库存也会减少。
1. 实体类
package hibernate.entity; /** * 账户 * @author SHI */ public class Account { private Integer id; private String username;// 账户名称 private int balance;//账户余额 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } @Override public String toString() { return "Account [id=" + id + ", username=" + username + ", balance=" + balance + "]"; } }
package hibernate.entity; /** * 书本 * @author SHI */ public class Book { private Integer id; private String bookName;//书本名称 private String bookId;//书本编号 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 getBookId() { return bookId; } public void setBookId(String bookId) { this.bookId = bookId; } 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; } @Override public String toString() { return "Book [id=" + id + ", bookName=" + bookName + ", bookId=" + bookId + ", price=" + price + ", stock=" + stock + "]"; } }2. DAO层代码
package hibernate.dao; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository public class BookDao { @Autowired private SessionFactory sessionFactory; /* * 不推荐使用 HibernateTemplate 和 HibernateDaoSupport,因为 * 这样会导致DAO和Spring API进行耦合,可移植性差。 * private HibernateTemplate hibernateTemplate; * private HibernateDaoSupport daoSupport; */ //获取和当前线程绑定的Session public Session getSession() { return sessionFactory.getCurrentSession(); } /** * 根据书本编号查询书本的价格 * @param bookId * @return */ public double bookPriceById(String bookId) { String hql = "select b.price from Book b where b.bookId = ?"; Query query = this.getSession().createQuery(hql).setString(0, bookId); return (Integer) query.uniqueResult(); } /** * 根据书本编号更新书本的库存数量 * @param bookId */ public void updateBookStock(String bookId) { //1.检查库存数量 String _hql = "select b.stock from Book b where b.bookId = ?"; int result = (Integer) getSession().createQuery(_hql).setString(0, bookId).uniqueResult(); if(result <= 0) { throw new RuntimeException("库存不足..."); } String hql = "update Book b set b.stock = b.stock - 1 where b.bookId = ?"; Query query = getSession().createQuery(hql).setString(0, bookId); query.executeUpdate(); } /** * 更新账户余额 * @param username * @param price */ public void updateUserAccount(String username, double price) { //1.检查账户余额 String _hql = "select a.balance from Account a where a.username = ?"; int balance = (Integer) getSession().createQuery(_hql).setString(0, username).uniqueResult(); if(balance <= price) { throw new RuntimeException("余额不足..."); } String hql = "update Account a set a.balance = a.balance - ? where a.username = ?"; this.getSession().createQuery(hql).setDouble(0, price).setString(1, username).executeUpdate(); } }
3. 业务层代码
package hibernate.service; import hibernate.dao.BookDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BookService { @Autowired private BookDao bookDao; /** * Spring整合Hibernate 事务的流程 * 1. 在方法开始之前 * ①. 获取 Session * ②. 把 Session 和当前线程绑定, 这样就可以在 Dao 中使用 SessionFactory 的 * getCurrentSession() 方法来获取 Session 了 * ③. 开启事务 * * 2. 若方法正常结束, 即没有出现异常, 则 * ①. 提交事务 * ②. 使和当前线程绑定的 Session 解除绑定 * ③. 关闭 Session * * 3. 若方法出现异常, 则: * ①. 回滚事务 * ②. 使和当前线程绑定的 Session 解除绑定 * ③. 关闭 Session */ public void buyBook(String username,String bookId) { //1.获取单价 double price = bookDao.bookPriceById(bookId); //2.更新库存 bookDao.updateBookStock(bookId); //3.更新余额 bookDao.updateUserAccount(username, price); } }
4. 配置文件
(1) Hibernate的配置文件
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="hbm2ddl.auto">update</property> </session-factory> </hibernate-configuration>
(2) Spring配置文件
<?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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <context:component-scan base-package="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:hibernate/hbm/*.hbm.xml"></property> </bean> <!-- 配置Spring事务管理 1.配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 2.配置事务属性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="buyBook"/> </tx:attributes> </tx:advice> <!-- 3.配置事务切入点,以及把事务切入点和事务属性关联 --> <aop:config> <aop:pointcut expression="execution(* hibernate.service.*.*(..))" id="pointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/> </aop:config> </beans>
5. 测试代码。测试的时候可以手动的更改数据可表中的数据,让程序抛出异常,测试事务的使用。
package hibernate; import hibernate.service.BookService; import java.sql.SQLException; import javax.sql.DataSource; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringHibernateTest { private ApplicationContext ac; private BookService bookService; { ac = new ClassPathXmlApplicationContext("bean.xml"); bookService = ac.getBean(BookService.class); } @Test public void testBuyBook() { bookService.buyBook("Kate", "1"); } @Test public void getDataSource() throws SQLException { DataSource dataSource = (DataSource) ac.getBean("dataSource"); System.out.println(dataSource.getConnection()); } }
标签:style blog http io ar color os 使用 sp
原文地址:http://www.cnblogs.com/shi-blog/p/4132829.html