-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
74aa0f6
commit b6c5acf
Showing
1 changed file
with
153 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
--- | ||
title: 批量操作 | ||
date: 2023-10-24 23:49:00 | ||
permalink: /pages/33c2c2/ | ||
article: false | ||
--- | ||
# 批量操作 | ||
|
||
- `3.5.4 +` 版本支持 | ||
|
||
- 事务需要手动自行控制(默认false) | ||
|
||
注意: autoCommit参数在Spring项目下是无效的,具体见SpringManagedTransactionFactory#newTransaction,在原生mybatis下可用 | ||
|
||
- 执行返回值为批量处理结果,业务可根据返回值判断是否成功 | ||
|
||
- saveOrUpdate是个比较有争议的方法,建议批量操作保持为简单的新增或更新操作 | ||
|
||
注意: 如果使用批量的sqlSession去执行查询业务的话,就会变得每次都需要flushStatements | ||
|
||
- 数据能否写入或更新取决于代码能否正确执行到flushStatements | ||
|
||
- 支持Spring与非Spring项目使用 | ||
|
||
- 执行抛出异常为PersistenceException | ||
|
||
# 说明: | ||
|
||
## MybatisBatch<?> | ||
|
||
- 泛型为具体 **实际数据类型** | ||
- sqlSessionFactory可通过容器获取,非Spring容器下可在自行初始化Mybatis时将上下文记录起来 | ||
- dataList为实际的批量数据处理 (非空) | ||
|
||
## MybatisBatch.Method<?> | ||
|
||
- 泛型为 **具体实体** | ||
- mapperClass为具体的实际Mapper类 | ||
|
||
## 使用方式 | ||
|
||
1. 构建MybatisBatch (将数据与sqlSessionFactory绑定起来) | ||
2. 构建MybatisBatch.Method (确定执行执行Mapper类方法) | ||
3. 执行操作 (执行处理操作,将批量参数转换为实际mapper需要的参数) | ||
|
||
示例一: 批量插入用户(数据类型为实体) | ||
|
||
```java | ||
List<H2User> userList = List.of(new H2User(2000L, "测试"), new H2User(2001L, "测试")); | ||
MybatisBatch<H2User> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, userList); | ||
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class); | ||
mybatisBatch.execute(method.insert()); | ||
|
||
// 简写 | ||
MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); | ||
MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.insert()); | ||
``` | ||
|
||
示例二: 批量插入用户(数据类型为非实体) | ||
|
||
```java | ||
List<Long> ids = Arrays.asList(120000L, 120001L); | ||
MybatisBatch<Long> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, ids); | ||
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class); | ||
mybatisBatch.execute(method.insert(id -> { | ||
// 将id转换为实体 | ||
H2User h2User = new H2User(); | ||
h2User.setTestId(id); | ||
return h2User; | ||
})); | ||
|
||
// 简写 | ||
MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); | ||
MybatisBatchUtils.execute(sqlSessionFactory, ids, mapperMethod.insert(id -> { | ||
// 将id转换为实体 | ||
H2User h2User = new H2User(); | ||
h2User.setTestId(id); | ||
return h2User; | ||
})); | ||
``` | ||
|
||
示例三: 自定义方法插入一 | ||
|
||
```java | ||
// mapper方法(方法参数无注解) | ||
@Insert( | ||
"insert into h2user(name,version) values( #{name}, #{version})" | ||
) | ||
int myInsertWithoutParam(H2User user1); | ||
|
||
// 准备数据集合 | ||
List<H2User> h2UserList = new ArrayList<>(); | ||
for (int i = 0; i < 1000; i++) { | ||
h2UserList.add(new H2User("myInsertWithoutParam" + i)); | ||
} | ||
|
||
MybatisBatch<H2User> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, h2UserList); | ||
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class); | ||
mybatisBatch.execute(method.get("myInsertWithoutParam")); | ||
|
||
//简写 | ||
MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); | ||
MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.get("myInsertWithoutParam")); | ||
``` | ||
|
||
示例四: 自定义方法插入(注解) | ||
|
||
```java | ||
// 方法参数带注解 | ||
@Insert( | ||
"insert into h2user(name,version) values( #{user1.name}, #{user1.version})" | ||
) | ||
int myInsertWithParam(@Param("user1") H2User user1); | ||
|
||
// 准备数据集合 | ||
List<H2User> h2UserList = new ArrayList<>(); | ||
for (int i = 0; i < 1000; i++) { | ||
h2UserList.add(new H2User("myInsertWithParam" + i)); | ||
} | ||
|
||
MybatisBatch<H2User> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, h2UserList); | ||
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class); | ||
mybatisBatch.execute(method.get("myInsertWithParam", (user) -> { | ||
// 转换成mapper方法参数 | ||
Map<String, Object> map = new HashMap<>(); | ||
map.put("user1", user); | ||
return map; | ||
})); | ||
|
||
// 简写 | ||
MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); | ||
MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.get("myInsertWithParam", (user) -> { | ||
Map<String, Object> map = new HashMap<>(); | ||
map.put("user1", user); | ||
return map; | ||
})); | ||
|
||
``` | ||
|
||
## 事务处理示例 | ||
|
||
```java | ||
@Autowired | ||
private TransactionTemplate transactionTemplate; | ||
|
||
transactionTemplate.execute((TransactionCallback<List<BatchResult>>) status -> { | ||
MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); | ||
// 执行批量插入 | ||
MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.insert()); | ||
throw new RuntimeException("出错了"); | ||
}); | ||
``` | ||
|