跳到主要内容

动态筛选

基本用法

  • Java API使用链式方式构建DSL,为了不打断链式代码书写,使用whereIf方法按条件添加where条件。

  • Kotlin API使用lambda构建DSL,动态查询无需专用API支持。

public List<Book> findBooks(@Nullable String name) {

BookTable table = Tables.BOOK_TABLE;

return sqlClient
.createQuery(table)
.whereIf(
name != null && !name.isEmpty(),
table.name().eq(name)
)
.orderBy(table.name().asc(), table.edition().desc())
.select(table)
.execute();
}
  • 调用findBooks(null),生成的SQL为

    select
    tb_1_.ID,
    tb_1_.NAME,
    tb_1_.EDITION,
    tb_1_.PRICE,
    tb_1_.STORE_ID
    from BOOK tb_1_
    order by
    tb_1_.NAME asc,
    tb_1_.EDITION desc
  • 调用findBooks("SQL in Action"),生成的SQL为

    select
    tb_1_.ID,
    tb_1_.NAME,
    tb_1_.EDITION,
    tb_1_.PRICE,
    tb_1_.STORE_ID
    from BOOK tb_1_
    where
    tb_1_.NAME = ? /* SQL in Action */
    order by
    tb_1_.NAME asc,
    tb_1_.EDITION desc

Java开发人员注意事项

Java开发人员请注意,上面的的代码

.whereIf(
name != null && !name.isEmpty(),
table.name().eq(name)
)

即便name为null,whereIf的条件并不成立,第二个参数table.name().eq(name)也会被执行,这是几乎所有编程语言的特性。

对于这里eq *(或ne)*而言,参数为null不会导致问题。因为eq(null)会被自动改成isNull(), ne(null)会被自动改成isNotNull()

但是,对于其他大部分条件表达式而言,用null构建会导致异常。

提示

不用担心,如果你不小心犯了错误,异常信息非常完善,足够引导你采用即将介绍的正确的编程方式。

以大于或等于操作而言ge,可以如此添加动态查询条件

.whereIf(
minPrice != null,
() -> table.price().ge(minPrice)
)

这里,使用lambda表达式延迟表达式的构建时机即可。只有当条件满足时,才会构建表达式。

对于kotlin而言,不存在这个问题,无任何注意事项。

让我们来看一个更完整的例子

public List<Book> findBooks(
@Nullable String name,
@Nullable BigDecimal minPrice,
@Nullable BigDecimal maxPrice
) {

BookTable table = Tables.BOOK_TABLE;

return sqlClient
.createQuery(table)
.whereIf(
name != null && !name.isEmpty(),
table.name().eq(name)
)
.whereIf(
minPrice != null,
() -> table.price().ge(minPrice)
)
.whereIf(
maxPrice != null,
() -> table.price().le(maxPrice)
)
.orderBy(table.name().asc(), table.edition().desc())
.select(table)
.execute();
}

多表操作

到目前为止,动态查询是基于单表的。

考虑一种更复杂的场景,如果某些动态查询条件针对其他表而非当前表 (即,需要先join到其他表,再对join得到的表添加动态where条件),该如何实现呢?

这个问题没有被任何SQL访问的上层方案优雅解决,属于领域空白,而Jimmer完美解决了这个难题*(Jimmer立项的根本原因)*

下一篇文档中,我们将会系统性讨论这个问题。

提示

下一篇文档中,你会发现Jimmer SQL DSL的独到之处,获得一个行业内无任何方案支持的强大能力。