Skip to content

Commit

Permalink
批量操作
Browse files Browse the repository at this point in the history
  • Loading branch information
nieqiurong committed Oct 24, 2023
1 parent 74aa0f6 commit b6c5acf
Showing 1 changed file with 153 additions and 0 deletions.
153 changes: 153 additions & 0 deletions docs/01.指南/03.扩展/13.批量操作.md
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("出错了");
});
```

0 comments on commit b6c5acf

Please sign in to comment.