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>