From f6e618d3ec628f95f9259257bcff5cefe2f6d5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Wed, 2 Aug 2023 19:22:40 +0800 Subject: [PATCH] doc: update docs --- docs/zh/base/auto-mapping.md | 10 +++++ docs/zh/base/batch.md | 68 ++++++++++++++++++++++----------- docs/zh/base/chain.md | 12 +++--- docs/zh/base/relations-query.md | 9 +++-- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/docs/zh/base/auto-mapping.md b/docs/zh/base/auto-mapping.md index 61ed9852..6fffaf38 100644 --- a/docs/zh/base/auto-mapping.md +++ b/docs/zh/base/auto-mapping.md @@ -145,6 +145,16 @@ QueryChain.of(accountMapper) .list(); ``` +以上代码执行的 SQL 如下: + +```sql +select tb_account.* + , max(tb_account.age) as maxAge + , avg(tb_account.age) as avgAge +where tb_account.id >= 100 +``` + + ## 多表映射 假设我们定义了一个 `BootVo.java`,其中包含了图书的基本信息,也包含了图书归属的用户信息,例如: diff --git a/docs/zh/base/batch.md b/docs/zh/base/batch.md index 33553f4d..c88bba1d 100644 --- a/docs/zh/base/batch.md +++ b/docs/zh/base/batch.md @@ -23,7 +23,7 @@ insert into tb_account(id,nickname, .....) values (104,"miachel104", ....), (105,"miachel105", ....); ``` -这种有一个特点:在小批量数据执行插入的时候,效率是非常高;但是当数据列表过多时,其生成的 SQL 可能会非常大, 这个大的 SQL +这种有一个特点:在小批量数据执行插入的时候,效率是非常高;但是当数据列表过多时,其生成的 SQL 可能会非常大, 这个大的 SQL 在传输和执行的时候就会变得很慢了。 因此,`BaseMapper.insertBatch` 方法只适用于在小批量数据插入的场景,比如 100 条数据以内。 @@ -39,45 +39,67 @@ Db.executeBatch(accounts.size(), 1000, AccountMapper.class, (mapper, index) -> { mapper.insert(account); }); ``` + +或者 + + +```java +List accounts = .... +Db.executeBatch(accounts, 1000, AccountMapper.class, (mapper, account) -> { + mapper.insert(account); + }); +``` + + `Db.executeBatch` 是通过 JDBC 的 `Statement.executeBatch()` 进行批量执行;这个在大批量数据执行的时候,效率要比 `BaseMapper.insertBatch` 高出许多; -::: tip 提示 -我看到有一些同学担心 `BaseMapper.insertBatch` 被误用,在 `IService` 中通过使用 `Db.executeBatch` 重写了 Service 的 `insertBatch` 方法,这也是没问题的。但还是需要明白, -`BaseMapper.insertBatch` 和 `Db.executeBatch` 的底层实现差异,以及不同的使用场景。 -::: +IService 很多批量操作的方法,也都是通过 `Db.executeBatch` 进行封装的,大家也可以通过其扩展出自己的 "批量操作" 方法来。比如这是一个批量忽略 `null` 的插入示例: -## `Db.updateBatch` 方法 +```java +public boolean saveBatchSelective(Collection entities) { + + int[] result = Db.executeBatch(entities, 1000, + AccountMapper.class, BaseMapper::insertSelective); + + return SqlUtil.toBool(result); +} +``` + + + +## `Db.updateBatch` 方法 这个方法的示例代码如下: ```java List accounts = .... -String sql = "insert into tb_account(user_name,age,birthday) values (?,?,?)"; +String sql = "insert into tb_account(user_name, age, birthday) " + + "values (?, ?, ?)"; Db.updateBatch(sql, new BatchArgsSetter() { - @Override - public int getBatchSize() { - return accounts.size(); - } + @Override + public int getBatchSize() { + return accounts.size(); + } - @Override - public Object[] getSqlArgs(int index) { - Account account = accounts = accounts.get(index); - Object[] args = new Object[3]; - args[0] = account.getUserName; - args[1] = account.getAge(); - args[2] = new Date(); - return args; - } - }); + @Override + public Object[] getSqlArgs(int index) { + Account account = accounts = accounts.get(index); + Object[] args = new Object[3]; + args[0] = account.getUserName; + args[1] = account.getAge(); + args[2] = new Date(); + return args; + } +}); ``` 虽然这个方法叫 `updateBatch`,但一样可以执行 `insert`、`delete`、`update` 等任何 SQL; 这个方法类似 Spring 的 `jdbcTemplate.batchUpdate()` 方法。 -## `Db.updateEntitiesBatch` 方法 +## `Db.updateEntitiesBatch` 方法 这个方法用于批量根据 id 更新 entity,其是对 `Db.executeBatch` 的封装,使用代码如下: ```java List accounts = .... Db.updateEntitiesBatch(accounts, 1000); -``` \ No newline at end of file +``` diff --git a/docs/zh/base/chain.md b/docs/zh/base/chain.md index 0206b97a..6dcb1fcd 100644 --- a/docs/zh/base/chain.md +++ b/docs/zh/base/chain.md @@ -1,6 +1,6 @@ # 链式操作 -在 MyBatis-Flex 中,内置了 `QueryChain.java` 和 `UpdateChain.java` 用于对数据进行链式查询操作和链式数据操作(修改和删除)。 +在 MyBatis-Flex 中,内置了 `QueryChain.java` 、 `UpdateChain.java` 以及 `DbChain.java` 用于对数据进行链式查询操作和链式操作(修改和删除)。 - **QueryChain**:链式查询 - **UpdateChain**:链式更新 @@ -240,15 +240,15 @@ ArticleVo articleVo = articleService.queryChain() // 新增 Row 构建 DbChain.table("tb_account") .set(RowKey.AUTO) - .set("user_name","王帅") - .set("age",18) - .set("birthday",new Date()) + .set("user_name", "王帅") + .set("age", 18) + .set("birthday", new Date()) .save(); // 查询 QueryWrapper 构建 DbChain.table("tb_account") - .select("id","user_name","age","birthday") - .where("age > ?",18) + .select("id", "user_name", "age", "birthday") + .where("age > ?", 18) .list() .forEach(System.out::println); ``` diff --git a/docs/zh/base/relations-query.md b/docs/zh/base/relations-query.md index 19c8f9a5..213be878 100644 --- a/docs/zh/base/relations-query.md +++ b/docs/zh/base/relations-query.md @@ -91,12 +91,12 @@ WHERE account_id IN (1, 2, 3, 4, 5) **注意事项 1:** -在以上的 `@RelationOneToOne` 注解配置中,若 `IDCard.java` 是一个没有 `@Table` 注解修饰的实体类, +在以上的 `@RelationOneToOne` 注解中,若 `IDCard.java` 是 VO、DTO 等,而不是一个带有 `@Table` 注解的 Entity 类, 则需要在 `@RelationOneToOne` 配置上 `targetTable` 用于指定查询的表名。 -假设 `IDCard.java` 没有 `@Table` 注解修饰(比如 vo 或 dto 等),配置如下: -```java 9 +例如: +```java 10 public class Account implements Serializable { @Id(keyType = KeyType.Auto) @@ -104,6 +104,7 @@ public class Account implements Serializable { private String userName; + // 假设 IDCard 类是 vo 或者 dto,需要配置 targetTable @RelationOneToOne(selfField = "id", targetField = "accountId" , targetTable = "tb_idcard") private IDCard idCard; @@ -115,7 +116,7 @@ public class Account implements Serializable { **注意事项 2:** 在 `Account.java` 和 `IDCard.java` 示例中,若他们的关联关系是通过 **中间表** 的方式进行关联,则需要添加 -`joinTable` `joinSelfColumn` `joinTargetColumn` 配置,如下所示: +`joinTable`、 `joinSelfColumn`、 `joinTargetColumn` 配置,如下所示: ```java 9,10,11 public class Account implements Serializable {