JSP 与 MyBatis 实现数据库事务传播示例
在Java Web开发中,数据库事务管理是保证数据一致性和完整性的关键。JSP(JavaServer Pages)作为Java Web开发的一种技术,常与Servlet和JavaBean等技术结合使用。MyBatis则是一个优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。本文将围绕JSP与MyBatis实现数据库事务传播的示例,详细讲解如何进行事务管理。
环境准备
在开始之前,请确保以下环境已正确配置:
1. JDK 1.8及以上版本
2. Tomcat 9.0及以上版本
3. MySQL 5.7及以上版本
4. MyBatis 3.5.6及以上版本
示例需求
假设我们有一个简单的订单系统,包含两个表:`orders`(订单表)和`products`(产品表)。当用户下单购买产品时,我们需要同时更新这两个表的数据。以下是我们需要实现的功能:
1. 当用户下单成功时,向`orders`表插入一条新记录。
2. 向`products`表更新库存数量。
如果在这个过程中出现任何异常,我们需要回滚事务,保证数据的一致性。
代码实现
1. 创建数据库表
我们需要创建两个数据库表:
sql
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
stock INT
);
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
product_id INT,
quantity INT
);
2. 创建实体类
接下来,我们需要创建两个实体类`Product`和`Order`:
java
public class Product {
private int id;
private String name;
private int stock;
// 省略getter和setter方法
}
public class Order {
private int id;
private int userId;
private int productId;
private int quantity;
// 省略getter和setter方法
}
3. 创建MyBatis配置文件
创建`mybatis-config.xml`配置文件,配置数据库连接信息、事务管理器等:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/your_database"/>
<property name="username" value="your_username"/>
<property name="password" value="your_password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/mapper/ProductMapper.xml"/>
<mapper resource="com/example/mapper/OrderMapper.xml"/>
</mappers>
</configuration>
4. 创建Mapper接口和XML文件
创建`ProductMapper`和`OrderMapper`接口,以及对应的XML文件:
`ProductMapper.java`:
java
public interface ProductMapper {
void updateStock(int productId, int quantity);
}
`ProductMapper.xml`:
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.mapper.ProductMapper">
<update id="updateStock" parameterType="map">
UPDATE products SET stock = stock - {quantity} WHERE id = {productId}
</update>
</mapper>
`OrderMapper.java`:
java
public interface OrderMapper {
void insertOrder(Order order);
}
`OrderMapper.xml`:
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.mapper.OrderMapper">
<insert id="insertOrder" parameterType="com.example.Order">
INSERT INTO orders (user_id, product_id, quantity) VALUES ({userId}, {productId}, {quantity})
</insert>
</mapper>
5. 创建JSP页面
创建一个JSP页面`order.jsp`,用于接收用户下单信息:
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Order</title>
</head>
<body>
<form action="order" method="post">
User ID: <input type="text" name="userId"><br>
Product ID: <input type="text" name="productId"><br>
Quantity: <input type="text" name="quantity"><br>
<input type="submit" value="Order">
</form>
</body>
</html>
6. 创建Servlet处理订单
创建一个Servlet类`OrderServlet`,用于处理订单:
java
@WebServlet("/order")
public class OrderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int userId = Integer.parseInt(request.getParameter("userId"));
int productId = Integer.parseInt(request.getParameter("productId"));
int quantity = Integer.parseInt(request.getParameter("quantity"));
SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
// 检查库存
Product product = sqlSession.selectOne("com.example.mapper.ProductMapper.selectById", productId);
if (product.getStock() < quantity) {
response.getWriter().println("Insufficient stock!");
return;
}
// 更新库存
productMapper.updateStock(productId, quantity);
// 插入订单
Order order = new Order();
order.setUserId(userId);
order.setProductId(productId);
order.setQuantity(quantity);
orderMapper.insertOrder(order);
sqlSession.commit();
response.getWriter().println("Order placed successfully!");
} catch (Exception e) {
e.printStackTrace();
response.getWriter().println("An error occurred while placing the order.");
}
}
}
7. 创建MyBatis工具类
创建一个工具类`MyBatisUtil`,用于获取SqlSessionFactory:
java
public class MyBatisUtil {
public static SqlSessionFactory getSqlSessionFactory() {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
} catch (IOException e) {
throw new RuntimeException("Error creating sqlSessionFactory", e);
}
}
}
总结
本文通过一个简单的订单系统示例,详细讲解了如何使用JSP和MyBatis实现数据库事务传播。在实际项目中,我们可以根据需求调整代码,实现更复杂的事务管理。希望本文对您有所帮助。
Comments NOTHING