7 - 0:35
*/
public interface BookDao {
/**
* 查询图书的价格
* @param bookId
* @return
*/
Integer getPriceByBookId(Integer bookId);
/**
* 更新图书的库存
* @param bookId
*/
void updateStockOfBook(Integer bookId);
/**
* 更新用户的余额
* @param userId
* @param price
*/
void updateBalanceOfUser(Integer userId,Integer price);
}
package org.rain.spring.dao.impl;
import org.rain.spring.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
/**
* @author liaojy
* @date 2023/8/27 - 0:45
*/
@Repository
public class BookDaoImpl implements BookDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public Integer getPriceByBookId(Integer bookId) {
String sql = "select price from t_book where book_id = ?";
Integer price = jdbcTemplate.queryForObject(sql, Integer.class,bookId);
return price;
}
public void updateStockOfBook(Integer bookId) {
String sql = "update t_book set stock = stock -1 where book_id = ?";
jdbcTemplate.update(sql, bookId);
}
public void updateBalanceOfUser(Integer userId, Integer price) {
String sql = "update t_user set balance = balance - ? where user_id = ?";
jdbcTemplate.update(sql,price,userId);
}
}
14.3.2、创建业务层接口BookService及其实现类
package org.rain.spring.service;
/**
* @author liaojy
* @date 2023/8/27 - 0:59
*/
public interface BookService {
void buyBook(Integer bookId,Integer userId);
}
package org.rain.spring.service.impl;
import org.rain.spring.dao.BookDao;
import org.rain.spring.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author liaojy
* @date 2023/8/27 - 1:02
*/
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public void buyBook(Integer bookId, Integer userId) {
//查询图书的价格
Integer price = bookDao.getPriceByBookId(bookId);
//更新图书的库存
bookDao.updateStockOfBook(bookId);
//更新用户的余额
bookDao.updateBalanceOfUser(userId,price);
}
}
14.3.3、创建控制层BookController
注意:因为控制层没用到接口,所以方法的访问修饰符要手动设置
package org.rain.spring.controller;
import org.rain.spring.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* @author liaojy
* @date 2023/8/27 - 1:07
*/
@Controller
public class BookController {
@Autowired
private BookService bookService;
public void buyBook(Integer bookId, Integer userId){
bookService.buyBook(bookId,userId);
}
}
14.3.4、配置对注解组件的扫描
<!--扫描注解组件-->
<context:component-scan base-package="org.rain.spring"></context:component-scan>
14.3.5、创建测试类
模拟场景:
-
用户购买图书,先查询图书的价格,再更新图书的库存和用户的余额
-
假设id为1的用户(余额为50),购买id为1的图书(价格为80)
-
购买图书之后,用户的余额应为-30;但由于数据库中余额字段设置了无符号,因此无法将-30插入到余额字段;
此时执行更新用户余额的sql语句会抛出异常
package org.rain.spring.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.rain.spring.controller.BookController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4