Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/babyfish-ct/jimmer
Browse files Browse the repository at this point in the history
  • Loading branch information
babyfish-ct committed Jun 12, 2023
2 parents 6aff061 + 5a1505c commit b776948
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: 表连接优化

在上一篇文章中,我们提及,Jimmer不仅能根据`data-query`自动生成`count-query`,还能自动优化`count-query`

由于`count-query`只是关心数据的总行数,不在乎数据的顺序和格式。所以,原`data-query`中的某些table join可能不需要复制到`count-query`中。
由于`count-query`只关心数据的总行数,不在乎数据的顺序和格式。所以,原`data-query`中的某些table join可能不需要复制到`count-query`中。

Jimmer会自动优化`count-query`,让其从原data-query中复制尽可能少的table join。

Expand All @@ -17,17 +17,17 @@ Jimmer会自动优化`count-query`,让其从原data-query中复制尽可能少

2. 基于集合关联(一对多、多对多)的表连接,不能被优化。

集合关联会导致重复数据,进而影响影响数据行数,因此这些表连接必需复制到`count-query`,无法优化。
集合关联会导致重复数据,进而影响数据行数,因此这些表连接必需复制到`count-query`,无法优化。

3. 基于引用关联(一对一、多对一)的表连接,有可能被优化,需满足以下任何一个条件
3. 基于引用关联(一对一、多对一)的表连接,有可能被优化,需满足以下任何一个条件

- 连接类型为左外连接

- 虽然连接类型是内连接,但关联基于非null真实外键。

所谓真实外建,指数据库中存在外键约束,请参见[真假外键](../../mapping/base/foreignkey)
所谓真实外键,指数据库中存在外键约束,请参见[真假外键](../../mapping/base/foreignkey)

综上描述,要判断原data-query中某个表连接是否可以在count-query中被自动删除,需采用如下优化规则
综上描述,要判断原data-query中某个表连接是否可以在count-query中被自动删除,需采用如下优化规则

<table>
<tr>
Expand All @@ -53,7 +53,7 @@ Jimmer会自动优化`count-query`,让其从原data-query中复制尽可能少
</tr>
<tr>
<td>
关联非空,且数据库中存在外建约束
关联非空,且数据库中存在外键约束
</td>
</tr>
</table>
Expand All @@ -63,7 +63,7 @@ Jimmer会自动优化`count-query`,让其从原data-query中复制尽可能少
<Tabs groupId="language">
<TabItem value="java" label="Java">

```java
```java title=""
BookTable book = BookTable.$;
AuthorTableEx author = AuthorTableEx.$;

Expand All @@ -86,7 +86,7 @@ int rowCount = query.count();
</TabItem>
<TabItem value="kotlin" label="Kotlin">

```kotlin
```kotlin title=""
val query = sqlClient.createQuery(Book::class) {
where(
table.price.between(
Expand Down Expand Up @@ -137,7 +137,7 @@ where tb_1_.PRICE between ? and ?
<Tabs groupId="language">
<TabItem value="java" label="Java">

```java
```java title=""
BookTable book = BookTable.$;
AuthorTableEx author = AuthorTableEx.$;

Expand All @@ -160,7 +160,7 @@ int rowCount = query.count();
</TabItem>
<TabItem value="kotlin" label="Kotlin">

```kotlin
```kotlin title=""
val query = sqlClient.createQuery(Book::class) {
where(
table.price.between(
Expand All @@ -186,4 +186,4 @@ select
count(tb_1_.ID)
from BOOK as tb_1_
where tb_1_.PRICE between ? and ?
```
```
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import TabItem from '@theme/TabItem';

## Jimmer分页的特色

分页查询是Jimmer一个很有特色的的功能,能大幅提升开发效率。
分页查询是Jimmer一个很有特色的功能,能大幅提升开发效率。

分页需要执行两条SQL查询

Expand All @@ -30,23 +30,23 @@ Jimer分页的特色:开发人员只需编写`data-query`,框架自动生成

另外,`count-query`其实是可以优化的。

让我们来看一个可以优化的场景,在data-query中有存在一个JOIN,如果它同满足如下面的条件
让我们来看一个可以优化的场景,在data-query中有存在一个JOIN,如果它同时满足如下条件:

- 此JOIN操作得到的表,并没有被`where`条件使用,而是在其他不会影响记录行数的地方被使用,比如`orderBy`

- 此JOIN的方向是从子表指向父表 *(即多对一和一对一关联)*,连接结果不会出现数据重复。也就是说,此JOIN不会导致数据变多

- 此JOIN的外建是真的 *(即存在外建约束,请参见[真假外建](../../mapping/base/foreignkey))* 且非null。那么此JOIN不会导致数据变少
- 此JOIN的外键是真的 *(即存在外键约束,请参见[真假外键](../../mapping/base/foreignkey))* 且非null。那么此JOIN不会导致数据变少

则可以安全地从count-query中剔除它,达到优化目的

:::tip
Jimmer不但可以自动生成`count-query`还可以做的优化`count-query`
Jimmer不但可以自动生成`count-query`还可以做到优化`count-query`
:::

## 配合SpringBoot使用时

配合SpringBoot使用时,开发人员从`JRepository/KRepository`派生自定义的Repository接口,为自定义接口添加查询方法有两种选择
配合SpringBoot使用时,开发人员从`JRepository/KRepository`派生自定义的Repository接口,为自定义接口添加查询方法有两种选择

- 按照一定的约定声明抽象方法,交由Jimmer自动实现

Expand Down Expand Up @@ -131,15 +131,15 @@ interface BookRepository<Book, Long> : KRepository<Book, Long> {

- ❶ 调用超接口的`pager`方法创建一个辅助对象,并调用该对象的方法`execute`实现分页查询。

`execute`的参数是一个未执行的查询,该查询作为`data-query`的模板
`execute`的参数是一个未执行的查询,该查询作为`data-query`的模板

- 首先,由于`data-query`模板尚未执行,Jimmer有机会根据它自动创建`count-query`,查询出分页前的数据总行数。

- 然后,Jimmer在`data-query`模板的基础上,添加分页范围,创建真正的`data-query`,查询当前页类的数据。

- 最后,Jimmer将数据总行数和当前页类的数据组合,创建Spring Data的`Page`对象并返回。

- ❷ 由于Spring Data的`Pageabe`包含了动态排序,所以需要应用动态排序
- ❷ 由于Spring Data的`Pageabe`包含了动态排序,所以需要应用动态排序

-`select`之后并没有调用查询本身的`execute`,说明这是一个未执行的查询。

Expand Down Expand Up @@ -520,7 +520,7 @@ limit ?, ?
Jimmer在分页查询完成后启动对其他关联度对象的查询,只针对单页之内的对象。
:::

以SpringBoot模式为例,现在,让我们修改之前讨论多的`BookRepository`,让其支持对象抓取器
以SpringBoot模式为例,现在,让我们修改之前讨论过的`BookRepository`,让其支持对象抓取器

<Tabs groupId="language">
<TabItem value="java" label="Java">
Expand Down Expand Up @@ -574,7 +574,7 @@ interface BookRepository<Book, Long> : KRepository<Book, Long> {
fun findBooks(
pageable: Pageable,
// highlight-next-line
fetcher: fetcher<Book>? = null,
fetcher: Fetcher<Book>? = null,
name: String? = null,
storeName: String? = null
): Page<Book> =
Expand Down Expand Up @@ -710,4 +710,4 @@ val page = bookRepository.findBooks(
? /* 10 */, ? /* 3 */, ? /* 2 */,
? /* 1 */, ? /* 9 */
)
```
```

0 comments on commit b776948

Please sign in to comment.