diff --git "a/docs/01.\346\214\207\345\215\227/03.\346\211\251\345\261\225/13.\346\211\271\351\207\217\346\223\215\344\275\234.md" "b/docs/01.\346\214\207\345\215\227/03.\346\211\251\345\261\225/13.\346\211\271\351\207\217\346\223\215\344\275\234.md" new file mode 100644 index 00000000..73a66736 --- /dev/null +++ "b/docs/01.\346\214\207\345\215\227/03.\346\211\251\345\261\225/13.\346\211\271\351\207\217\346\223\215\344\275\234.md" @@ -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 userList = List.of(new H2User(2000L, "测试"), new H2User(2001L, "测试")); +MybatisBatch mybatisBatch = new MybatisBatch<>(sqlSessionFactory, userList); +MybatisBatch.Method method = new MybatisBatch.Method<>(H2UserMapper.class); +mybatisBatch.execute(method.insert()); + +// 简写 +MybatisBatch.Method mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); +MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.insert()); +``` + +示例二: 批量插入用户(数据类型为非实体) + +```java +List ids = Arrays.asList(120000L, 120001L); +MybatisBatch mybatisBatch = new MybatisBatch<>(sqlSessionFactory, ids); +MybatisBatch.Method method = new MybatisBatch.Method<>(H2UserMapper.class); +mybatisBatch.execute(method.insert(id -> { + // 将id转换为实体 + H2User h2User = new H2User(); + h2User.setTestId(id); + return h2User; +})); + +// 简写 +MybatisBatch.Method 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 h2UserList = new ArrayList<>(); +for (int i = 0; i < 1000; i++) { + h2UserList.add(new H2User("myInsertWithoutParam" + i)); +} + +MybatisBatch mybatisBatch = new MybatisBatch<>(sqlSessionFactory, h2UserList); +MybatisBatch.Method method = new MybatisBatch.Method<>(H2UserMapper.class); +mybatisBatch.execute(method.get("myInsertWithoutParam")); + +//简写 +MybatisBatch.Method 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 h2UserList = new ArrayList<>(); +for (int i = 0; i < 1000; i++) { + h2UserList.add(new H2User("myInsertWithParam" + i)); +} + +MybatisBatch mybatisBatch = new MybatisBatch<>(sqlSessionFactory, h2UserList); +MybatisBatch.Method method = new MybatisBatch.Method<>(H2UserMapper.class); +mybatisBatch.execute(method.get("myInsertWithParam", (user) -> { + // 转换成mapper方法参数 + Map map = new HashMap<>(); + map.put("user1", user); + return map; +})); + +// 简写 +MybatisBatch.Method mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); +MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.get("myInsertWithParam", (user) -> { + Map map = new HashMap<>(); + map.put("user1", user); + return map; +})); + +``` + +## 事务处理示例 + +```java +@Autowired +private TransactionTemplate transactionTemplate; + +transactionTemplate.execute((TransactionCallback>) status -> { + MybatisBatch.Method mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class); + // 执行批量插入 + MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.insert()); + throw new RuntimeException("出错了"); +}); +``` +