我用的框架mybatis plus
时间: 2025-04-09 22:19:11 浏览: 35
<think>好的,用户之前询问了如何在使用MyBatis Plus时进行批量插入并关联主表和流程表。现在用户进一步说明他们使用的是MyBatis Plus,需要更具体的指导。我需要回顾之前的回答,看看是否有需要调整的地方,以确保适用于MyBatis Plus。
首先,之前的回答提到了JPA和JDBC两种方案,但用户现在用的是MyBatis Plus,所以需要调整示例代码和策略。MyBatis Plus有自己的批量插入方法,比如使用ServiceImpl的saveBatch方法,但需要注意其默认的批量操作并不是真正的批量SQL,而是分批次插入,需要配置正确的批量执行器。
接下来,主表插入后获取主键的方式不同。MyBatis Plus在插入后会自动回填主键,前提是实体类的主键字段配置了@TableId(type = IdType.AUTO)或者其他生成策略。需要确认用户是否正确配置了主键生成策略,以确保流程表能正确获取到主表的主键ID。
然后,关联关系的建立。在MyBatis Plus中,可能需要手动设置外键值,而不是像JPA那样通过对象关联自动处理。需要指导用户如何在插入主表后,遍历主表记录,获取生成的主键,然后为每个流程表记录设置对应的order_id。
性能优化方面,MyBatis Plus的saveBatch方法默认可能不会启用真正的批量插入,需要用户配置SQL注入器,使用ExecuteBatch类型的执行器。同时,可以建议使用事务管理,批量提交,以及结合数据库连接池参数优化,比如rewriteBatchedStatements等。
验证部分,需要检查主键是否回填,流程表的外键是否不为空。此外,数据库外键约束的开启和测试也是必要的。
可能用户在实际操作中遇到的问题包括主键未正确生成、批量插入效率低、关联关系未正确设置等。需要针对MyBatis Plus的特性给出解决方案,比如正确的主键策略配置、启用真正的批量插入、手动设置外键值等。
总结,我需要将之前的JPA示例转换为MyBatis Plus的代码示例,突出MyBatis Plus的特性和最佳实践,确保用户能够顺利实现批量插入并正确关联主表和流程表。</think>以下是基于**MyBatis Plus**实现主表与流程表批量插入关联的完整方案,涵盖$\textcolor{green}{关键配置}$、$\textcolor{green}{关联策略}$和$\textcolor{green}{性能优化}$:
---
### $\textcolor{green}{一、基础配置}$
#### $\textcolor{orange}{1.1 实体类定义}$
```java
// 主表实体(Order)
@TableName("t_order")
public class Order {
@TableId(type = IdType.AUTO) // 自增主键
private Long orderId;
private String orderNo;
// 其他字段...
}
// 流程表实体(OrderProcess)
@TableName("t_order_process")
public class OrderProcess {
@TableId(type = IdType.AUTO)
private Long processId;
private Long orderId; // 外键字段
private String processType;
// 其他字段...
}
```
#### $\textcolor{orange}{1.2 Mapper接口增强}$
```java
public interface OrderMapper extends BaseMapper<Order> {
// 批量插入方法(需在XML中实现)
int insertBatch(@Param("list") List<Order> list);
}
public interface OrderProcessMapper extends BaseMapper<OrderProcess> {
@Insert("<script>" +
"INSERT INTO t_order_process(order_id, process_type) VALUES " +
"<foreach collection='list' item='item' separator=','>(#{item.orderId}, #{item.processType})</foreach>" +
"</script>")
int batchInsert(@Param("list") List<OrderProcess> list);
}
```
---
### $\textcolor{green}{二、关联插入实现}$
#### $\textcolor{orange}{2.1 分阶段插入法(推荐)}$
```java
// 第一阶段:插入主表
List<Order> orders = dataList.stream()
.map(d -> new Order(d.getOrderNo()))
.collect(Collectors.toList());
// 使用MyBatis Plus批量插入(需开启批量模式)
boolean mainResult = orderService.saveBatch(orders);
if(!mainResult) throw new RuntimeException("主表插入失败");
// 第二阶段:构建流程数据
List<OrderProcess> processes = new ArrayList<>();
for (Order order : orders) {
processes.add(new OrderProcess(order.getOrderId(), "PAYMENT"));
processes.add(new OrderProcess(order.getOrderId(), "APPROVAL"));
}
// 批量插入流程表
boolean processResult = orderProcessService.saveBatch(processes);
```
#### $\textcolor{orange}{2.2 SQL执行验证}$
```sql
-- 检查主表记录数
SELECT COUNT(*) FROM t_order WHERE order_no LIKE 'TEST%';
-- 检查关联完整性
SELECT * FROM t_order_process
WHERE order_id IN (
SELECT order_id FROM t_order WHERE order_no LIKE 'TEST%'
);
```
---
### $\textcolor{green}{三、性能优化方案}$
#### $\textcolor{orange}{3.1 启用真批量模式}$
```yaml
# application.yml配置
mybatis-plus:
global-config:
db-config:
id-type: auto
configuration:
default-executor-type: batch # 启用批处理执行器
```
#### $\textcolor{orange}{3.2 事务优化}$
```java
@Transactional(rollbackFor = Exception.class)
public void batchInsertWithTransaction(List<Order> orders, List<OrderProcess> processes) {
orderService.saveBatch(orders);
orderProcessService.saveBatch(processes);
}
```
#### $\textcolor{orange}{3.3 分批处理(10万+数据量)}$
```java
// 主表分页插入
int batchSize = 2000;
ListUtils.partition(orders, batchSize).forEach(batch -> {
orderMapper.insertBatch(batch); // 使用自定义批量方法
});
// 流程表分页插入
ListUtils.partition(processes, batchSize*2).forEach(batch -> {
orderProcessMapper.batchInsert(batch);
});
```
---
### $\textcolor{green}{四、常见问题解决}$
#### $\textcolor{orange}{4.1 主键未回填问题}$
$\textcolor{red}{症状:}$流程表的order_id字段为null
$\textcolor{blue}{解决方案:}$
1. 确认主表使用`@TableId(type = IdType.AUTO)`
2. 检查数据库自增字段设置
3. 在插入后立即调用`order.getId()`触发回填
#### $\textcolor{orange}{4.2 批量插入效率低}$
$\textcolor{red}{优化步骤:}$
1. 在JDBC URL添加参数:
```properties
url: jdbc:mysql://host/db?rewriteBatchedStatements=true&useSSL=false
```
2. 调整Service层批量提交大小:
```java
orderService.saveBatch(orders, 1000); // 每批1000条
```
#### $\textcolor{orange}{4.3 多线程冲突}$
```java
// 使用并行流时的线程安全写法
List<OrderProcess> processes = orders.parallelStream()
.flatMap(order -> Stream.of(
new OrderProcess(order.getOrderId(), "TYPE1"),
new OrderProcess(order.getOrderId(), "TYPE2")
))
.collect(Collectors.toList());
```
---
### $\textcolor{green}{五、方案对比}$
| 方案 | 优点 | 缺点 | 适用场景 |
|------|------|------|---------|
| saveBatch() | 使用简单 | 受限于框架批量逻辑 | 小数据量(≤1万) |
| 自定义XML | 完全控制SQL | 需要手写SQL | 复杂批量插入 |
| 存储过程 | 极高性能 | 维护成本高 | 超大数据量(≥50万) |
---
$\textcolor{red}{关键总结:}$
1. **关联绑定**:通过内存中主表对象获取ID后显式设置到流程表
2. **事务控制**:建议将主表和流程表插入放在同一事务中
3. **性能平衡点**:常规项目建议每批2000-5000条数据提交一次
阅读全文
相关推荐


















