docs: update docs

This commit is contained in:
开源海哥 2023-07-10 11:19:47 +08:00
parent e3253fd62e
commit 81016ec601
2 changed files with 55 additions and 45 deletions

View File

@ -57,8 +57,8 @@ export default defineConfig({
text: '基础功能', text: '基础功能',
items: [ items: [
{text: '增、删、改', link: '/zh/base/add-delete-update'}, {text: '增、删、改', link: '/zh/base/add-delete-update'},
{text: '查询(多表和分页)', link: '/zh/base/query'}, {text: '基础查询', link: '/zh/base/query'},
{text: '一对多、多对一', link: '/zh/base/relations-query'}, {text: '关联查询', link: '/zh/base/relations-query'},
{text: '批量操作', link: '/zh/base/batch'}, {text: '批量操作', link: '/zh/base/batch'},
{text: 'QueryWrapper', link: '/zh/base/querywrapper'}, {text: 'QueryWrapper', link: '/zh/base/querywrapper'},
{text: 'Db + Row', link: '/zh/base/db-row'}, {text: 'Db + Row', link: '/zh/base/db-row'},
@ -119,7 +119,7 @@ export default defineConfig({
(function() { (function() {
var hm = document.createElement("script"); var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?3f50d5fbe3bf955411748b5616b24a24"; hm.src = "https://hm.baidu.com/hm.js?3f50d5fbe3bf955411748b5616b24a24";
var s = document.getElementsByTagName("script")[0]; var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s); s.parentNode.insertBefore(hm, s);
})(); })();
` `

View File

@ -1,12 +1,12 @@
# 一对多、多对一 # 关联查询
在 MyBatis-Flex 中,我们内置了 3 种方,帮助用户进行关联查询,比如 `一对多``一对一``多对一``多对多`等场景,他们分别是: 在 MyBatis-Flex 中,我们内置了 3 种方,帮助用户进行关联查询,比如 `一对多``一对一``多对一``多对多`等场景,他们分别是:
- Relations 注解 - 方案1Relations 注解
- Field Query - 方案2Field Query
- Join Query - 方案3Join Query
## Relations 注解 ## 方案 1Relations 注解
在 MyBatis-Flex 中,提供了 4 个 Relations 注解,他们分别是: 在 MyBatis-Flex 中,提供了 4 个 Relations 注解,他们分别是:
@ -18,11 +18,13 @@
添加了以上配置的实体类,在通过 `BaseMapper` 的方法查询数据时,需要调用 select*****WithRelations**() 方法Relations 注解才能生效。 添加了以上配置的实体类,在通过 `BaseMapper` 的方法查询数据时,需要调用 select*****WithRelations**() 方法Relations 注解才能生效。
否则 MyBatis-Flex 自动忽略 Relations 注解。 否则 MyBatis-Flex 自动忽略 Relations 注解。
BaseMapper 提供的 withRelations 方法列表,详情点击[这里](/zh/base/query.html#relations-注解查询)。
## 一对一 `@RelationOneToOne` ## 一对一 `@RelationOneToOne`
假设有一个账户,账户有身份证,账户和身份证的关系是一对一的关系,代码如下所示: 假设有一个账户,账户有身份证,账户和身份证的关系是一对一的关系,代码如下所示:
Account.java : Account.java :
```java 8 ```java 8
public class Account implements Serializable { public class Account implements Serializable {
@ -33,21 +35,21 @@ public class Account implements Serializable {
@RelationOneToOne(selfField = "id", targetField = "accountId") @RelationOneToOne(selfField = "id", targetField = "accountId")
private IDCard idCard; private IDCard idCard;
//getter setter //getter setter
} }
``` ```
IDCard.java : IDCard.java :
```java ```java
@Table(value = "tb_idcard") @Table(value = "tb_idcard")
public class IDCard implements Serializable { public class IDCard implements Serializable {
private Long accountId; private Long accountId;
private String cardNo; private String cardNo;
private String content; private String content;
//getter setter //getter setter
} }
``` ```
@ -57,7 +59,7 @@ public class IDCard implements Serializable {
- **selfField** 当前实体类的属性 - **selfField** 当前实体类的属性
- **targetField** 目标对象的关系实体类的属性 - **targetField** 目标对象的关系实体类的属性
> PS: 若 **selfField** 是主键,且当前表只有 1 个主键时,可以不填写。 > PS: 若 **selfField** 是主键,且当前表只有 1 个主键时,可以不填写。因此,以上的配置可以简化为 `@RelationOneToOne(targetField = "accountId")`
假设数据库 5 条 Account 数据,然后进行查询: 假设数据库 5 条 Account 数据,然后进行查询:
@ -71,7 +73,7 @@ System.out.println(accounts);
```sql ```sql
SELECT `id`, `user_name`, `age` FROM `tb_account` SELECT `id`, `user_name`, `age` FROM `tb_account`
SELECT `account_id`, `card_no`, `content` FROM `tb_idcard` SELECT `account_id`, `card_no`, `content` FROM `tb_idcard`
WHERE account_id IN (1, 2, 3, 4, 5) WHERE account_id IN (1, 2, 3, 4, 5)
``` ```
@ -79,10 +81,10 @@ WHERE account_id IN (1, 2, 3, 4, 5)
```txt ```txt
[ [
Account{id=1, userName='孙悟空', age=18, idCard=IDCard{accountId=1, cardNo='0001', content='内容1'}}, Account{id=1, userName='孙悟空', age=18, idCard=IDCard{accountId=1, cardNo='0001', content='内容1'}},
Account{id=2, userName='猪八戒', age=19, idCard=IDCard{accountId=2, cardNo='0002', content='内容2'}}, Account{id=2, userName='猪八戒', age=19, idCard=IDCard{accountId=2, cardNo='0002', content='内容2'}},
Account{id=3, userName='沙和尚', age=19, idCard=IDCard{accountId=3, cardNo='0003', content='内容3'}}, Account{id=3, userName='沙和尚', age=19, idCard=IDCard{accountId=3, cardNo='0003', content='内容3'}},
Account{id=4, userName='六耳猕猴', age=19, idCard=IDCard{accountId=4, cardNo='0004', content='内容4'}}, Account{id=4, userName='六耳猕猴', age=19, idCard=IDCard{accountId=4, cardNo='0004', content='内容4'}},
Account{id=5, userName='王麻子叔叔', age=19, idCard=IDCard{accountId=5, cardNo='0005', content='内容5'}} Account{id=5, userName='王麻子叔叔', age=19, idCard=IDCard{accountId=5, cardNo='0005', content='内容5'}}
] ]
``` ```
@ -103,14 +105,14 @@ public class Account implements Serializable {
@RelationOneToMany(selfField = "id", targetField = "accountId") @RelationOneToMany(selfField = "id", targetField = "accountId")
private List<Book> books; private List<Book> books;
//getter setter //getter setter
} }
``` ```
Book.java : Book.java :
```java ```java
@Table(value = "tb_book") @Table(value = "tb_book")
public class Book implements Serializable { public class Book implements Serializable {
@ -118,7 +120,7 @@ public class Book implements Serializable {
private Long id; private Long id;
private Long accountId; private Long accountId;
private String title; private String title;
//getter setter //getter setter
} }
``` ```
@ -128,7 +130,7 @@ public class Book implements Serializable {
- **selfField** 当前实体类的属性 - **selfField** 当前实体类的属性
- **targetField** 目标对象的关系实体类的属性 - **targetField** 目标对象的关系实体类的属性
> PS: 若 **selfField** 是主键,且当前表只有 1 个主键时,可以不填写。 > PS: 若 **selfField** 是主键,且当前表只有 1 个主键时,可以不填写。因此,以上的配置可以简化为 `@RelationOneToOne(targetField = "accountId")`
@ -144,7 +146,7 @@ System.out.println(accounts);
```sql ```sql
SELECT `id`, `user_name`, `age` FROM `tb_account` SELECT `id`, `user_name`, `age` FROM `tb_account`
SELECT `id`, `account_id`, `title`, `content` FROM `tb_book` SELECT `id`, `account_id`, `title`, `content` FROM `tb_book`
WHERE account_id IN (1, 2, 3, 4, 5) WHERE account_id IN (1, 2, 3, 4, 5)
``` ```
@ -154,7 +156,7 @@ WHERE account_id IN (1, 2, 3, 4, 5)
假设一个账户有很多本书籍,一本书只能归属一个账户所有;账户和书籍的关系是一对多的关系,书籍和账户的关系为多对一的关系,代码如下: 假设一个账户有很多本书籍,一本书只能归属一个账户所有;账户和书籍的关系是一对多的关系,书籍和账户的关系为多对一的关系,代码如下:
Account.java 一对多的配置: Account.java:
```java 8 ```java 8
public class Account implements Serializable { public class Account implements Serializable {
@ -163,9 +165,6 @@ public class Account implements Serializable {
private String userName; private String userName;
@RelationOneToMany(selfField = "id", targetField = "accountId")
private List<Book> books;
//getter setter //getter setter
} }
``` ```
@ -180,10 +179,10 @@ public class Book implements Serializable {
private Long id; private Long id;
private Long accountId; private Long accountId;
private String title; private String title;
@RelationManyToOne(selfField = "accountId", targetField = "id") @RelationManyToOne(selfField = "accountId", targetField = "id")
private Account account; private Account account;
//getter setter //getter setter
} }
``` ```
@ -193,7 +192,8 @@ public class Book implements Serializable {
- **selfField** 当前实体类的属性 - **selfField** 当前实体类的属性
- **targetField** 目标对象的关系实体类的属性 - **targetField** 目标对象的关系实体类的属性
> PS: 若 **targetField** 目标对象的是主键,且目标对象的表只有 1 个主键时,可以不填写。 > PS: 若 **targetField** 目标对象的是主键,且目标对象的表只有 1 个主键时,可以不填写。因此,以上的配置可以简化为
> `@RelationManyToOne(selfField = "accountId")`
@ -225,7 +225,7 @@ public class Account implements Serializable {
targetField = "id", joinTargetColumn = "role_id" targetField = "id", joinTargetColumn = "role_id"
) )
private List<Role> roles; private List<Role> roles;
//getter setter //getter setter
} }
``` ```
@ -239,13 +239,6 @@ public class Role implements Serializable {
private Long id; private Long id;
private String name; private String name;
@RelationManyToMany(
joinTable = "tb_role_mapping",
selfField = "id", joinSelfColumn = "role_id",
targetField = "id", joinTargetColumn = "account_id"
)
private List<Account> accounts;
//getter setter //getter setter
} }
``` ```
@ -259,8 +252,25 @@ public class Role implements Serializable {
- joinTargetColumn 目标表和中间表的关系字段 - joinTargetColumn 目标表和中间表的关系字段
> 注意selfField 和 targetField 配置的是类的属性名joinSelfColumn 和 joinTargetColumn 配置的是中间表的字段名。 > 注意selfField 和 targetField 配置的是类的属性名joinSelfColumn 和 joinTargetColumn 配置的是中间表的字段名。
> >
> 若 **selfField****targetField** 分别是两张关系表的主键,且表只有 1 个主键时,可以不填写。 > 若 **selfField****targetField** 分别是两张关系表的主键,且表只有 1 个主键时,可以不填写。因此,以上配置可以简化如下:
```java {7-11}
public class Account implements Serializable {
@Id(keyType = KeyType.Auto)
private Long id;
private String userName;
@RelationManyToMany(
joinTable = "tb_role_mapping", // 中间表
joinSelfColumn = "account_id",
joinTargetColumn = "role_id"
)
private List<Role> roles;
//getter setter
}
```
## 父子关系查询 ## 父子关系查询
@ -270,7 +280,7 @@ public class Role implements Serializable {
CREATE TABLE `tb_menu` CREATE TABLE `tb_menu`
( (
`id` INTEGER auto_increment, `id` INTEGER auto_increment,
`parent_id` INTEGER, `parent_id` INTEGER,
`name` VARCHAR(100) `name` VARCHAR(100)
); );
``` ```
@ -369,7 +379,7 @@ JSON 输出内容如下:
## Field Query ## 方案 2Field Query
以下是文章的 `多对多` 示例,一篇文章可能归属于多个分类,一个分类可能有多篇文章,需要用到中间表 `article_category_mapping` 以下是文章的 `多对多` 示例,一篇文章可能归属于多个分类,一个分类可能有多篇文章,需要用到中间表 `article_category_mapping`
@ -417,7 +427,7 @@ List<Article> articles = mapper.selectListByQuery(queryWrapper
select * from tb_article where id >= 100; select * from tb_article where id >= 100;
-- 以上 SQL 得到结果后,再执行查询分类的 SQL如下 -- 以上 SQL 得到结果后,再执行查询分类的 SQL如下
select * from tb_category where id in select * from tb_category where id in
(select category_id from article_category_mapping where article_id = 100); (select category_id from article_category_mapping where article_id = 100);
select * from tb_category where id in select * from tb_category where id in
@ -469,7 +479,7 @@ List<Article> articles = mapper.selectListByQuery(query
这些不仅仅只适用于 `一对多``一对一``多对一``多对多`等场景。任何 `Article` 对象里的属性,需要二次查询赋值的,都是可以通过这种方式进行,比如一些统计的场景。 这些不仅仅只适用于 `一对多``一对一``多对一``多对多`等场景。任何 `Article` 对象里的属性,需要二次查询赋值的,都是可以通过这种方式进行,比如一些统计的场景。
## Join Query ## 方案 3Join Query
Join Query 是通过 QueryWrapper 构建 `Left Join` 等方式进行查询,其原理是 MyBatis-Flex 自动构建了 MyBatis 的 `<resultMap>` Join Query 是通过 QueryWrapper 构建 `Left Join` 等方式进行查询,其原理是 MyBatis-Flex 自动构建了 MyBatis 的 `<resultMap>`
,我们只需要关注 MyBatis-Flex 的 SQL 构建即可。 ,我们只需要关注 MyBatis-Flex 的 SQL 构建即可。