Spring整合Hibernate

来源:互联网 发布:易语言端口转发源码 编辑:程序博客网 时间:2024/06/17 19:16


1、db.properties

jdbc.user=rootjdbc.password=1230jdbc.driverClass=com.mysql.jdbc.Driverjdbc.jdbcUrl=jdbc:mysql:///springjdbc.initPoolSize=5jdbc.maxPoolSize=10
2、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"xsi:schemaLocation="http://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.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><context:component-scan base-package="com.atguigu.spring"></context:component-scan><!-- 导入资源文件 --><context:property-placeholder location="classpath:db.properties"/><!-- 配置 C3P0 数据源 --><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="jdbcUrl" value="${jdbc.jdbcUrl}"></property><property name="driverClass" value="${jdbc.driverClass}"></property><property name="initialPoolSize" value="${jdbc.initPoolSize}"></property><property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property></bean><!-- 配置 Spirng 的 JdbcTemplate --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置 NamedParameterJdbcTemplate, 该对象可以使用具名参数, 其没有无参数的构造器, 所以必须为其构造器指定参数 --><bean id="namedParameterJdbcTemplate"class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"><constructor-arg ref="dataSource"></constructor-arg></bean><!-- 配置事务管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 启用事务注解 --><tx:annotation-driven transaction-manager="transactionManager"/></beans>
3、applicationContext-tx-xml.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.0.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.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><context:component-scan base-package="com.atguigu.spring"></context:component-scan><!-- 导入资源文件 --><context:property-placeholder location="classpath:db.properties"/><!-- 配置 C3P0 数据源 --><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="jdbcUrl" value="${jdbc.jdbcUrl}"></property><property name="driverClass" value="${jdbc.driverClass}"></property><property name="initialPoolSize" value="${jdbc.initPoolSize}"></property><property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property></bean><!-- 配置 Spirng 的 JdbcTemplate --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置 bean --><bean id="bookShopDao" class="com.atguigu.spring.tx.xml.BookShopDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"></property></bean><bean id="bookShopService" class="com.atguigu.spring.tx.xml.service.impl.BookShopServiceImpl"><property name="bookShopDao" ref="bookShopDao"></property></bean><bean id="cashier" class="com.atguigu.spring.tx.xml.service.impl.CashierImpl"><property name="bookShopService" ref="bookShopService"></property></bean><!-- 1. 配置事务管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 2. 配置事务属性 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 根据方法名指定事务的属性 --><tx:method name="purchase" propagation="REQUIRES_NEW"/><tx:method name="get*" read-only="true"/><tx:method name="find*" read-only="true"/><tx:method name="*"/></tx:attributes></tx:advice><!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 --><aop:config><aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))" id="txPointCut"/><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/></aop:config></beans>

Java

1、com.atguigu.spring.jdbc包

1)Department.java

package com.atguigu.spring.jdbc;public class Department {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Department [id=" + id + ", name=" + name + "]";}}
2)DepartmentDao.java

package com.atguigu.spring.jdbc;import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.RowMapper;import org.springframework.jdbc.core.support.JdbcDaoSupport;import org.springframework.stereotype.Repository;/** * 不推荐使用 JdbcDaoSupport, 而推荐直接使用 JdbcTempate 作为 Dao 类的成员变量 */@Repositorypublic class DepartmentDao extends JdbcDaoSupport{@Autowiredpublic void setDataSource2(DataSource dataSource){setDataSource(dataSource);}public Department get(Integer id){String sql = "SELECT id, dept_name name FROM departments WHERE id = ?";RowMapper<Department> rowMapper = new BeanPropertyRowMapper<>(Department.class);return getJdbcTemplate().queryForObject(sql, rowMapper, id);}}
3)Employee.java

package com.atguigu.spring.jdbc;public class Employee {private Integer id;private String lastName;private String email;private Integer dpetId;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Integer getDpetId() {return dpetId;}public void setDpetId(Integer dpetId) {this.dpetId = dpetId;}@Overridepublic String toString() {return "Employee [id=" + id + ", lastName=" + lastName + ", email="+ email + ", dpetId=" + dpetId + "]";}}
4)EmployeeDao.java

package com.atguigu.spring.jdbc;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.stereotype.Repository;@Repositorypublic class EmployeeDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public Employee get(Integer id){String sql = "SELECT id, last_name lastName, email FROM employees WHERE id = ?";RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, id);return employee;}}
5)JDBCTest.java
package com.atguigu.spring.jdbc;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.sql.DataSource;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;import org.springframework.jdbc.core.namedparam.SqlParameterSource;public class JDBCTest {private ApplicationContext ctx = null;private JdbcTemplate jdbcTemplate;private EmployeeDao employeeDao;private DepartmentDao departmentDao;private NamedParameterJdbcTemplate namedParameterJdbcTemplate;{ctx = new ClassPathXmlApplicationContext("applicationContext.xml");jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");employeeDao = ctx.getBean(EmployeeDao.class);departmentDao = ctx.getBean(DepartmentDao.class);namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class);}/** * 使用具名参数时, 可以使用 update(String sql, SqlParameterSource paramSource) 方法进行更新操作 * 1. SQL 语句中的参数名和类的属性一致! * 2. 使用 SqlParameterSource 的 BeanPropertySqlParameterSource 实现类作为参数.  */@Testpublic void testNamedParameterJdbcTemplate2(){String sql = "INSERT INTO employees(last_name, email, dept_id) "+ "VALUES(:lastName,:email,:dpetId)";Employee employee = new Employee();employee.setLastName("XYZ");employee.setEmail("xyz@sina.com");employee.setDpetId(3);SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);namedParameterJdbcTemplate.update(sql, paramSource);}/** * 可以为参数起名字.  * 1. 好处: 若有多个参数, 则不用再去对应位置, 直接对应参数名, 便于维护 * 2. 缺点: 较为麻烦.  */@Testpublic void testNamedParameterJdbcTemplate(){String sql = "INSERT INTO employees(last_name, email, dept_id) VALUES(:ln,:email,:deptid)";Map<String, Object> paramMap = new HashMap<>();paramMap.put("ln", "FF");paramMap.put("email", "ff@atguigu.com");paramMap.put("deptid", 2);namedParameterJdbcTemplate.update(sql, paramMap);}@Testpublic void testDepartmentDao(){System.out.println(departmentDao.get(1));}@Testpublic void testEmployeeDao(){System.out.println(employeeDao.get(1));}/** * 获取单个列的值, 或做统计查询 * 使用 queryForObject(String sql, Class<Long> requiredType)  */@Testpublic void testQueryForObject2(){String sql = "SELECT count(id) FROM employees";long count = jdbcTemplate.queryForObject(sql, Long.class);System.out.println(count);}/** * 查到实体类的集合 * 注意调用的不是 queryForList 方法 */@Testpublic void testQueryForList(){String sql = "SELECT id, last_name lastName, email FROM employees WHERE id > ?";RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);List<Employee> employees = jdbcTemplate.query(sql, rowMapper,5);System.out.println(employees);}/** * 从数据库中获取一条记录, 实际得到对应的一个对象 * 注意不是调用 queryForObject(String sql, Class<Employee> requiredType, Object... args) 方法! * 而需要调用 queryForObject(String sql, RowMapper<Employee> rowMapper, Object... args) * 1. 其中的 RowMapper 指定如何去映射结果集的行, 常用的实现类为 BeanPropertyRowMapper * 2. 使用 SQL 中列的别名完成列名和类的属性名的映射. 例如 last_name lastName * 3. 不支持级联属性. JdbcTemplate 到底是一个 JDBC 的小工具, 而不是 ORM 框架 */@Testpublic void testQueryForObject(){String sql = "SELECT id, last_name lastName, email, dept_id as \"department.id\" FROM employees WHERE id = ?";RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);System.out.println(employee);}/** * 执行批量更新: 批量的 INSERT, UPDATE, DELETE * 最后一个参数是 Object[] 的 List 类型: 因为修改一条记录需要一个 Object 的数组, 那么多条不就需要多个 Object 的数组吗 */@Testpublic void testBatchUpdate(){String sql = "INSERT INTO employees(last_name, email, dept_id) VALUES(?,?,?)";List<Object[]> batchArgs = new ArrayList<>();batchArgs.add(new Object[]{"AA", "aa@atguigu.com", 1});batchArgs.add(new Object[]{"BB", "bb@atguigu.com", 2});batchArgs.add(new Object[]{"CC", "cc@atguigu.com", 3});batchArgs.add(new Object[]{"DD", "dd@atguigu.com", 3});batchArgs.add(new Object[]{"EE", "ee@atguigu.com", 2});jdbcTemplate.batchUpdate(sql, batchArgs);}/** * 执行 INSERT, UPDATE, DELETE */@Testpublic void testUpdate(){String sql = "UPDATE employees SET last_name = ? WHERE id = ?";jdbcTemplate.update(sql, "Jack", 5);}@Testpublic void testDataSource() throws SQLException {DataSource dataSource = ctx.getBean(DataSource.class);System.out.println(dataSource.getConnection());}}
2、com.atguigu.spring.tx包

1)BookShopDao.java

package com.atguigu.spring.tx;public interface BookShopDao {//根据书号获取书的单价public int findBookPriceByIsbn(String isbn);//更新数的库存. 使书号对应的库存 - 1public void updateBookStock(String isbn);//更新用户的账户余额: 使 username 的 balance - pricepublic void updateUserAccount(String username, int price);}
2)BookShopDaoImpl.java

package com.atguigu.spring.tx;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;@Repository("bookShopDao")public class BookShopDaoImpl implements BookShopDao {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic int findBookPriceByIsbn(String isbn) {String sql = "SELECT price FROM book WHERE isbn = ?";return jdbcTemplate.queryForObject(sql, Integer.class, isbn);}@Overridepublic void updateBookStock(String isbn) {//检查书的库存是否足够, 若不够, 则抛出异常String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);if(stock == 0){throw new BookStockException("库存不足!");}String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";jdbcTemplate.update(sql, isbn);}@Overridepublic void updateUserAccount(String username, int price) {//验证余额是否足够, 若不足, 则抛出异常String sql2 = "SELECT balance FROM account WHERE username = ?";int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);if(balance < price){throw new UserAccountException("余额不足!");}String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";jdbcTemplate.update(sql, price, username);}}
3)BookShopService.java

package com.atguigu.spring.tx;public interface BookShopService {public void purchase(String username, String isbn);}
4)BookShopServiceImpl.java
package com.atguigu.spring.tx;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Isolation;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;@Service("bookShopService")public class BookShopServiceImpl implements BookShopService {@Autowiredprivate BookShopDao bookShopDao;//添加事务注解//1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时//如何使用事务, 默认取值为 REQUIRED, 即使用调用方法的事务//REQUIRES_NEW: 事务自己的事务, 调用的事务方法的事务被挂起. //2.使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED//3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚. 也可以通过对应的//属性进行设置. 通常情况下去默认值即可. //4.使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据, //这样可以帮助数据库引擎优化事务. 若真的事一个只读取数据库值的方法, 应设置 readOnly=true//5.使用 timeout 指定强制回滚之前事务可以占用的时间.  //@Transactional(propagation=Propagation.REQUIRES_NEW,//isolation=Isolation.READ_COMMITTED,//noRollbackFor={UserAccountException.class})@Transactional(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.READ_COMMITTED,readOnly=false,timeout=3)@Overridepublic void purchase(String username, String isbn) {try {Thread.sleep(5000);} catch (InterruptedException e) {}//1. 获取书的单价int price = bookShopDao.findBookPriceByIsbn(isbn);//2. 更新数的库存bookShopDao.updateBookStock(isbn);//3. 更新用户余额bookShopDao.updateUserAccount(username, price);}}
5)BookShopServiceImpl.java

package com.atguigu.spring.tx;public class BookStockException extends RuntimeException{/** *  */private static final long serialVersionUID = 1L;public BookStockException() {super();// TODO Auto-generated constructor stub}public BookStockException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);// TODO Auto-generated constructor stub}public BookStockException(String message, Throwable cause) {super(message, cause);// TODO Auto-generated constructor stub}public BookStockException(String message) {super(message);// TODO Auto-generated constructor stub}public BookStockException(Throwable cause) {super(cause);// TODO Auto-generated constructor stub}}
6)Cashier.java

package com.atguigu.spring.tx;import java.util.List;public interface Cashier {public void checkout(String username, List<String> isbns);}
7)CashierImpl.java

package com.atguigu.spring.tx;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;@Service("cashier")public class CashierImpl implements Cashier {@Autowiredprivate BookShopService bookShopService;@Transactional@Overridepublic void checkout(String username, List<String> isbns) {for(String isbn: isbns){bookShopService.purchase(username, isbn);}}}

8)SpringTransactionTest.java

package com.atguigu.spring.tx;import static org.junit.Assert.*;import java.util.Arrays;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringTransactionTest {private ApplicationContext ctx = null;private BookShopDao bookShopDao = null;private BookShopService bookShopService = null;private Cashier cashier = null;{ctx = new ClassPathXmlApplicationContext("applicationContext.xml");bookShopDao = ctx.getBean(BookShopDao.class);bookShopService = ctx.getBean(BookShopService.class);cashier = ctx.getBean(Cashier.class);}@Testpublic void testTransactionlPropagation(){cashier.checkout("AA", Arrays.asList("1001", "1002"));}@Testpublic void testBookShopService(){bookShopService.purchase("AA", "1001");}@Testpublic void testBookShopDaoUpdateUserAccount(){bookShopDao.updateUserAccount("AA", 200);}@Testpublic void testBookShopDaoUpdateBookStock(){bookShopDao.updateBookStock("1001");}@Testpublic void testBookShopDaoFindPriceByIsbn() {System.out.println(bookShopDao.findBookPriceByIsbn("1001"));}}
9)UserAccountException.java

package com.atguigu.spring.tx;public class UserAccountException extends RuntimeException{/** *  */private static final long serialVersionUID = 1L;public UserAccountException() {super();// TODO Auto-generated constructor stub}public UserAccountException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);// TODO Auto-generated constructor stub}public UserAccountException(String message, Throwable cause) {super(message, cause);// TODO Auto-generated constructor stub}public UserAccountException(String message) {super(message);// TODO Auto-generated constructor stub}public UserAccountException(Throwable cause) {super(cause);// TODO Auto-generated constructor stub}}
3、com.atguigu.spring.tx.xml包

1)BookShopDao.java

package com.atguigu.spring.tx.xml;public interface BookShopDao {//根据书号获取书的单价public int findBookPriceByIsbn(String isbn);//更新数的库存. 使书号对应的库存 - 1public void updateBookStock(String isbn);//更新用户的账户余额: 使 username 的 balance - pricepublic void updateUserAccount(String username, int price);}
2)BookShopDaoImpl.java

package com.atguigu.spring.tx.xml;import org.springframework.jdbc.core.JdbcTemplate;public class BookShopDaoImpl implements BookShopDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic int findBookPriceByIsbn(String isbn) {String sql = "SELECT price FROM book WHERE isbn = ?";return jdbcTemplate.queryForObject(sql, Integer.class, isbn);}@Overridepublic void updateBookStock(String isbn) {//检查书的库存是否足够, 若不够, 则抛出异常String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);if(stock == 0){throw new BookStockException("库存不足!");}String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";jdbcTemplate.update(sql, isbn);}@Overridepublic void updateUserAccount(String username, int price) {//验证余额是否足够, 若不足, 则抛出异常String sql2 = "SELECT balance FROM account WHERE username = ?";int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);if(balance < price){throw new UserAccountException("余额不足!");}String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";jdbcTemplate.update(sql, price, username);}}
3)BookStockException.java

package com.atguigu.spring.tx.xml;public class BookStockException extends RuntimeException{/** *  */private static final long serialVersionUID = 1L;public BookStockException() {super();// TODO Auto-generated constructor stub}public BookStockException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);// TODO Auto-generated constructor stub}public BookStockException(String message, Throwable cause) {super(message, cause);// TODO Auto-generated constructor stub}public BookStockException(String message) {super(message);// TODO Auto-generated constructor stub}public BookStockException(Throwable cause) {super(cause);// TODO Auto-generated constructor stub}}
4)SpringTransactionTest.java

package com.atguigu.spring.tx.xml;import java.util.Arrays;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.atguigu.spring.tx.xml.service.BookShopService;import com.atguigu.spring.tx.xml.service.Cashier;public class SpringTransactionTest {private ApplicationContext ctx = null;private BookShopDao bookShopDao = null;private BookShopService bookShopService = null;private Cashier cashier = null;{ctx = new ClassPathXmlApplicationContext("applicationContext-tx-xml.xml");bookShopDao = ctx.getBean(BookShopDao.class);bookShopService = ctx.getBean(BookShopService.class);cashier = ctx.getBean(Cashier.class);}@Testpublic void testTransactionlPropagation(){cashier.checkout("AA", Arrays.asList("1001", "1002"));}@Testpublic void testBookShopService(){bookShopService.purchase("AA", "1001");}}
5)UserAccountException.java

package com.atguigu.spring.tx.xml;public class UserAccountException extends RuntimeException{/** *  */private static final long serialVersionUID = 1L;public UserAccountException() {super();// TODO Auto-generated constructor stub}public UserAccountException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);// TODO Auto-generated constructor stub}public UserAccountException(String message, Throwable cause) {super(message, cause);// TODO Auto-generated constructor stub}public UserAccountException(String message) {super(message);// TODO Auto-generated constructor stub}public UserAccountException(Throwable cause) {super(cause);// TODO Auto-generated constructor stub}}
4、com.atguigu.spring.tx.xml.service包

1)BookShopService.java

package com.atguigu.spring.tx.xml.service;public interface BookShopService {public void purchase(String username, String isbn);}
2)Cashier.java

package com.atguigu.spring.tx.xml.service;import java.util.List;public interface Cashier {public void checkout(String username, List<String> isbns);}
5、com.atguigu.spring.tx.xml.service.impl包

1)BookShopServiceImpl.java

package com.atguigu.spring.tx.xml.service.impl;import com.atguigu.spring.tx.xml.BookShopDao;import com.atguigu.spring.tx.xml.service.BookShopService;public class BookShopServiceImpl implements BookShopService {private BookShopDao bookShopDao;public void setBookShopDao(BookShopDao bookShopDao) {this.bookShopDao = bookShopDao;}@Overridepublic void purchase(String username, String isbn) {try {Thread.sleep(1000);} catch (InterruptedException e) {}//1. 获取书的单价int price = bookShopDao.findBookPriceByIsbn(isbn);//2. 更新数的库存bookShopDao.updateBookStock(isbn);//3. 更新用户余额bookShopDao.updateUserAccount(username, price);}}
2)CashierImpl.java

package com.atguigu.spring.tx.xml.service.impl;import java.util.List;import com.atguigu.spring.tx.xml.service.BookShopService;import com.atguigu.spring.tx.xml.service.Cashier;public class CashierImpl implements Cashier {private BookShopService bookShopService;public void setBookShopService(BookShopService bookShopService) {this.bookShopService = bookShopService;}@Overridepublic void checkout(String username, List<String> isbns) {for(String isbn: isbns){bookShopService.purchase(username, isbn);}}}


0 0