1.导入jar包
2.数据库配置文件jdbc.properties
jdbc.user=root jdbc.password=123 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql:///spring
3.spring-bookstore.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:aop="http://www.springframework.org/schema/aop" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd "> <context:property-placeholder location="classpath:jdbc.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> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <context:component-scan base-package="com.neu.spring"></context:component-scan> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <tx:annotation-driven transaction-manager="txManager"/> </beans>
4.Dao层接口及实现类
public interface BookStoreDao { public float findPriceByIsbn(String isbn); public void userCountdel(String isbn,int userId); public void bookRemain(String isbn); } @Repository("bookStoreDao") public class BookStoreDaoImpl implements BookStoreDao { @Autowired private JdbcTemplate jdbcTemplate; /** * 根据书的编号isbn查询书的库存 */ @Override public void bookRemain(String isbn) { String sql3 = "SELECT remain FROM book WHERE isbn=?"; int remain = jdbcTemplate.queryForObject(sql3, Integer.class, isbn); if(remain<1) { throw new CountException("库存余额不足!!"); } String sql = "UPDATE BOOK SET remain=remain-1 WHERE isbn=?"; jdbcTemplate.update(sql, isbn); } /** * 根据书的编号和用户id,更新用户账户 */ @Override public void userCountdel(String isbn, int userId){ float price = findPriceByIsbn(isbn); String sql = "UPDATE usercounter SET counter=counter-"+price+" WHERE userId=?"; String sql2 = "SELECT counter FROM usercounter WHERE userId=?"; float counter = jdbcTemplate.queryForObject(sql2, Float.class, userId); if(counter<price) throw new CountException("用户余额不足!!"); jdbcTemplate.update(sql,userId); } /** * 根据书的编号查询书的价格 */ @Override public float findPriceByIsbn(String isbn) { String sql = "SELECT price FROM book WHERE isbn=?"; float price = jdbcTemplate.queryForObject(sql, Float.class,isbn); return price; } }
5.Service层接口和实现类
public interface BookService { public void purchase(int userId,String isbn); } @Service("bookService") public class BookServiceImpl implements BookService { @Autowired private BookStoreDao bookStoreDao; @Transactional @Override public void purchase(int userId, String isbn) { //1.获取书的单价 float price = bookStoreDao.findPriceByIsbn(isbn); //2.更新库存 bookStoreDao.bookRemain(isbn); //3.更新用户账户 bookStoreDao.userCountdel(isbn, userId); System.out.println("购买信息:"); System.out.println("userId:"+userId+"---isbn:"+isbn); } }
6.mysql无法检测书的库存和用户账户是否有效,需要手动抛出异常,定义异常类CountException
public class CountException extends RuntimeException { private static final long serialVersionUID = 1L; public CountException(String string) { super(string); } }
7.测试代码
public class BookStoreTest { private ApplicationContext ctx = null; private BookService bookService = null; @Test public void testService(){ ctx = new ClassPathXmlApplicationContext("spring-bookstore.xml"); bookService = (BookService) ctx.getBean("bookService"); bookService.purchase(2018, "1001"); } }
注:如果采用xml配置文件方式声明事务,只需将注解去掉,实体类中生成对应的set方法,修改配置文件如下:
<?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:aop="http://www.springframework.org/schema/aop" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd "> <context:property-placeholder location="classpath:jdbc.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> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="bookService" class="com.neu.spring.bookstore.xml.BookServiceImpl"> <property name="bookStoreDao" ref="bookStoreDao"></property> </bean> <bean id="bookStoreDao" class="com.neu.spring.bookstore.xml.BookStoreDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!--配置事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务属性 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- 根据方法名指定事务属性 --> <tx:method name="purchase" propagation="REQUIRED"/> <tx:method name="get*" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 配置切点,并将切点与事务属性联系起来 --> <aop:config > <aop:pointcut expression="execution(public void com.neu.spring.bookstore.xml.BookServiceImpl.purchase(..))" id="pointCut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/> </aop:config> </beans>