mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
feat: 新增 一对多、多对一 查询功能
This commit is contained in:
parent
12a4efd121
commit
138a805ae7
@ -61,6 +61,7 @@ export default defineConfig({
|
||||
{text: '增、删、改', link: '/zh/base/add-delete-update'},
|
||||
{text: '查询和分页', link: '/zh/base/query'},
|
||||
{text: '批量操作', link: '/zh/base/batch'},
|
||||
{text: '一对多、多对一', link: '/zh/base/field-query'},
|
||||
{text: 'QueryWrapper', link: '/zh/base/querywrapper'},
|
||||
{text: 'Db + Row', link: '/zh/base/db-row'},
|
||||
{text: 'IService', link: '/zh/base/service'},
|
||||
|
||||
88
docs/zh/base/field-query.md
Normal file
88
docs/zh/base/field-query.md
Normal file
@ -0,0 +1,88 @@
|
||||
# 一对多、多对一
|
||||
|
||||
在很多场景下,我们可能会用到 `一对多`、`一对一`、`多对一`等场景的关联查询,MyBatis-Flex 内置了相关的方法,用于支持此类场景。
|
||||
|
||||
## 代码示例
|
||||
|
||||
以下是文章的示例,一篇文章可能归属于多个分类。
|
||||
|
||||
```java
|
||||
public class Article {
|
||||
private Long id;
|
||||
private String title;
|
||||
private String content;
|
||||
|
||||
//文章的归属分类,可能是 1 个或者多个
|
||||
private List<Category> categories;
|
||||
|
||||
//getter setter
|
||||
}
|
||||
```
|
||||
|
||||
查询代码如下:
|
||||
|
||||
```java {10-13}
|
||||
QueryWrapper queryWrapper = QueryWrapper.create()
|
||||
.select().form(ARTICLE)
|
||||
.where(ARTICLE.id.ge(100));
|
||||
|
||||
List<Article> articles = mapper.selectListByQuery(queryWrapper, fieldQueryBuilder -> {
|
||||
fieldQueryBuilder
|
||||
.field(Article::getCategories) // 或者 .field("categories")
|
||||
.type(Category.class) //非集合,可以不指定 type
|
||||
.queryWrapper(article -> QueryWrapper.create()
|
||||
.select().from(CATEGORY)
|
||||
.where(CATEGORY.id.in(
|
||||
select("category_id").from("article_category_mapping")
|
||||
.where("article_id = ?", article.getId())
|
||||
)
|
||||
));
|
||||
});
|
||||
```
|
||||
|
||||
通过以上代码可以看出,`Article.categories` 字段的结果,来源于 `queryWrapper()` 方法构建的 `QueryWrapper`。
|
||||
|
||||
其原理是:MyBatis-Flex 的内部逻辑是先查询出 `Article` 的数据,然后再根据 `Article` 构建出新的 SQL,查询分类,并赋值给 `Article.categories`,
|
||||
假设 `Article` 有 10 条数据,那么最终会进行 11 次数据库查询。
|
||||
|
||||
查询的 SQL 大概如下:
|
||||
|
||||
```sql
|
||||
select * from tb_article where id >= 100;
|
||||
|
||||
-- 以上 SQL 得到结果后,再执行查询分类的 SQL,如下:
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 100);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 101);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 102);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 103);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 104);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 105);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 106);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 107);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 108);
|
||||
|
||||
select * from tb_category where id in
|
||||
(select category_id from article_category_mapping where article_id = 109);
|
||||
```
|
||||
|
||||
## 其他场景
|
||||
|
||||
通过以上内容看出,`Article` 的任何属性,都是可以通过传入 `FieldQueryBuilder` 来构建 `QueryWrapper` 进行再次查询,
|
||||
这些不仅仅只适用于 `一对多`、`一对一`、`多对一`等场景。任何 `Article` 对象里的属性,需要二次查询赋值的,都是可以通过这种方式进行。
|
||||
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.core.field;
|
||||
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class FieldQuery implements Serializable {
|
||||
|
||||
private String field;
|
||||
private Class<?> mappingType;
|
||||
private QueryWrapper queryWrapper;
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void setField(String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public Class<?> getMappingType() {
|
||||
return mappingType;
|
||||
}
|
||||
|
||||
public void setMappingType(Class<?> mappingType) {
|
||||
this.mappingType = mappingType;
|
||||
}
|
||||
|
||||
public QueryWrapper getQueryWrapper() {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public void setQueryWrapper(QueryWrapper queryWrapper) {
|
||||
this.queryWrapper = queryWrapper;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.core.field;
|
||||
|
||||
import com.mybatisflex.core.util.LambdaGetter;
|
||||
import com.mybatisflex.core.util.LambdaUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class FieldQueryBuilder<T> implements Serializable {
|
||||
|
||||
private T entity;
|
||||
private FieldQuery fieldQuery = new FieldQuery();
|
||||
|
||||
public FieldQueryBuilder(T entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public FieldQueryBuilder<T> field(String field){
|
||||
fieldQuery.setField(field);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldQueryBuilder<T> field(LambdaGetter<T> fn){
|
||||
return field(LambdaUtil.getFieldName(fn));
|
||||
}
|
||||
|
||||
public FieldQueryBuilder<T> type(Class<?> mappingType){
|
||||
fieldQuery.setMappingType(mappingType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldQueryBuilder<T> queryWrapper(QueryBuilder<T> fun){
|
||||
fieldQuery.setQueryWrapper(fun.build(entity));
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldQuery build() {
|
||||
return fieldQuery;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.core.field;
|
||||
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
|
||||
public interface QueryBuilder<T> {
|
||||
QueryWrapper build(T entity);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user