使用 MyBatis 调用 MySQL 存储过程的 Spring Boot 示例 - 银行转账无并发案例
在本文中,我们将介绍如何在 Spring Boot 应用程序中使用 MyBatis 框架调用 MySQL 存储过程,以实现银行转账功能,确保无并发问题。
1. 创建 Spring Boot 项目和 MySQL 存储过程
首先,创建一个 Spring Boot 项目并配置 MySQL 数据源。在 application.properties 文件中添加如下配置:
spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
接下来,创建一个名为 transfer 的 MySQL 存储过程,用于处理银行转账操作,确保在事务中处理转账操作,以避免并发问题:
DELIMITER //
CREATE PROCEDURE transfer(IN sender_id INT, IN receiver_id INT, IN amount DECIMAL(10, 2))
BEGIN
DECLARE sender_balance DECIMAL(10, 2);
DECLARE receiver_balance DECIMAL(10, 2);
SELECT balance INTO sender_balance FROM accounts WHERE id = sender_id;
SELECT balance INTO receiver_balance FROM accounts WHERE id = receiver_id;
IF sender_balance >= amount THEN
UPDATE accounts SET balance = balance - amount WHERE id = sender_id;
UPDATE accounts SET balance = balance + amount WHERE id = receiver_id;
ELSE
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insufficient balance';
END IF;
COMMIT;
END //
DELIMITER ;
2. 配置 MyBatis
添加 MyBatis 依赖到 pom.xml 文件:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
在 application.properties 文件中配置 MyBatis:
mybatis.mapper-locations=classpath:mappers/*.xml
创建一个名为 BankMapper 的接口:
@Mapper
public interface BankMapper {
void transfer(@Param("sender_id") Integer sender_id, @Param("receiver_id") Integer receiver_id, @Param("amount") BigDecimal amount);
}
在 resources/mappers 目录下创建一个名为 BankMapper.xml 的映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.BankMapper">
<select id="transfer" statementType="CALLABLE">
{call transfer(#{sender_id}, #{receiver_id}, #{amount})}
</select>
</mapper>
3. 调用存储过程
现在,我们可以在 Spring Boot 项目中调用存储过程。创建一个名为 BankService 的服务类,并注入 BankMapper 接口:
@Service
public class BankService {
@Autowired
private BankMapper bankMapper;
public void transfer(Integer sender_id, Integer receiver_id, BigDecimal amount) {
bankMapper.transfer(sender_id, receiver_id, amount);
}
}
创建一个名为 BankController
的控制器类,用于处理 HTTP 请求:
@RestController
@RequestMapping("/bank")
public class BankController {
@Autowired
private BankService bankService;
@PostMapping("/transfer")
public ResponseEntity<String> transfer(@RequestParam Integer sender_id, @RequestParam Integer receiver_id, @RequestParam BigDecimal amount) {
try {
bankService.transfer(sender_id, receiver_id, amount);
return ResponseEntity.ok("Transfer successful");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Transfer failed: " + e.getMessage());
}
}
}
4. 测试存储过程调用
现在可以通过发送 HTTP 请求来测试存储过程的调用。启动 Spring Boot 应用程序,然后使用浏览器或 Postman 发送以下请求:
POST http://localhost:8080/bank/transfer?sender_id=1&receiver_id=2&amount=100
响应应为 “Transfer successful”,表明转账操作成功完成。
扫描二维码关注公众号,回复:
14975103 查看本文章
本文中,我们介绍了如何在 Spring Boot 应用程序中使用 MyBatis 框架调用 MySQL 存储过程,实现银行转账功能,确保无并发问题。通过这个示例,你可以学会如何在实际项目中使用 MyBatis 调用存储过程来实现更复杂的业务逻辑。