用法
Jimmer分页的特色
分页查询是Jimmer一个很有特色的功能,能大幅提升开发效率。
分页需要执行两条SQL查询
-
查询满足条件的数据总行数,其结果可以计算一共有多少页,用户的页码是否越界。
信息为了便于讨论,Jimmer称这条SQL为
count-query
-
查询当前页内的所有数据,返回的数据条数不超过页面大小,并跳过之前页的所有数据。
信息为了便于讨论,Jimmer称这条SQL为
data-query
Jimmer分页的特色:开发人员只需编写data-query
,框架自动生成count-query
。
Jimmer不但可以自动生成count-query
,还可以做到优化count-query
。这个优化会在下一篇文章中讨论。
配合Spring Data使用时
配合SpringBoot使用时,开发人员从JRepository/KRepository
派生自定义的Repository接口,为自定义接口添加查询方法有两种选择:
-
按照一定的约定声明抽象方法,交由Jimmer自动实现
警告这种用法过于简单,隐藏了所有细节,不适在此讲述分页查询。
你可以查看Spring篇/SpringData风格/抽象方法以了解如何通过这种方式实现分页查询
-
直接在自定义接口中定义default方法,自己实现查询逻辑
- Java
- Kotlin
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
org.babyfish.jimmer.spring.repository.support.SpringPageFactory;
...省略其他导入...
public interface BookRepository<Book, Long> extends JRepository<Book, Long> {
BookTable table = Tables.BOOK_TABLE;
default Page<Book> findBooks(
Pageable pageable,
@Nullable String name,
@Nullable String storeName
) {
return
sql()
.createQuery(table)
.whereIf(
name != null && !name.isEmpty(),
table.name().eq(name)
)
.whereIf(
storeName != null && !storeName.isEmpty(),
table.store().name().eq(storeName)
)
.orderBy(SpringOrders.toOrders(table, pageable.getSort())) ❶
.select(table)
.fetchPage( ❷
pageable.getPageNumber(),
pageable.getPageSize()
SpringPageFactory.getInstance()
);
}
}
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
...省略其他导入...
interface BookRepository<Book, Long> : KRepository<Book, Long> {
fun findBooks(
pageable: Pageable,
name: String? = null,
storeName: String? = null
): Page<Book> =
sql
.createQuery(Book::class) {
name?.takeIf { it.isNotEmpty() }?.let {
where(table.name eq it)
}
storeName?.takeIf { it.isNotEmpty() }?.let {
where(table.store.name eq it)
}
orderBy(pageable.sort) ❶
select(table)
}
.fetchSpringPage(pageable) ❷
}
-
❶ 由于Spring Data的
Pageable
包含了动态排序,所以需要应用动态排序。 -
❷ 分页查询,返回
org.springframework.data.domain.Page<Book>
类型的对象Jimmer分页可以使用任何
Page
对象,无论是Spring Data的Page
,还是Jimmer自身的Page
,甚至第三方定义的Page
。这里,Java代码采用
SpringPageFactory.getInstance()
要求当前分页操作返回Spring Data的Page
。事实上,Kotlin代码也可以使用
SpringPageFactory.getInstance()
来时想通目的,但是,kotlin下有更便捷的扩展方法fetchSpringPage
。
如果我们执行
Page<Boo> page = bookRepository.findBooks(
PageRequest.of(
1,
5,
SortUtils.toSort("name asc, edition desc")
),
null,
null
)
SpringData中Pageable