# 无SQL查询条件构建

后端经常需要根据前端传递的搜索条件来构建查询,@BindQuery查询条件绑定就是自动构建这一过程的。 用户可自定义相关实体的查询DTO类,添加相应的BindQuery注解,diboot将自动构建QueryWrapper并查询。 对于字段条件跨表的查询将自动按需构建LEFT JOIN(无该字段条件时不JOIN,以提升性能),让无需手写SQL覆盖更多场景。

# 使用方式

# 1. Entity/DTO中定义查询方式

示例代码:

public class UserDTO {
    // 无@BindQuery注解默认会映射为=条件;主表的相等条件无需加注解
    private Long gender;
    
    // 有注解,映射为注解指定条件
    @BindQuery(comparison = Comparison.LIKE)
    private String realname;
    
    // join其他表(查询条件绑定字段)
    @BindQuery(comparison = Comparison.STARTSWITH, entity=Organization.class, field="name", condition="this.org_id=id")
    private String orgName;
    
    // 多注解,多个条件 or 连接 (since v2.4.0)
    @BindQuery(comparison = Comparison.LIKE, field="realname")
    @BindQuery(comparison = Comparison.STARTSWITH, entity=Organization.class, field="name", condition="this.org_id=id")
    private String name;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 2. 调用QueryBuilder自动构建QueryWrapper

构建方式有:

# 方式1. controller中调用super.buildQueryWrapperBy*(entityOrDto) 进行构建
    QueryWrapper<User> queryWrapper = super.buildQueryWrapperByDTOParams(userDto);
1

该方式基于url非空参数取值构建: url参数示例: /list?gender=M&realname=张 将构建为 queryWrapper.eq("gender", "M").like("realname", "张")

    QueryWrapper<User> queryWrapper = super.buildQueryWrapperByDTO(userDto);
1

该方式基于dto对象中的非空值字段构建

# 方式2. 直接调用 QueryBuilder.toQueryWrapper(entityOrDto) 进行构建
    QueryWrapper<User> queryWrapper = QueryBuilder.toQueryWrapper(userDto);
1

该方式基于dto对象非空值字段构建

# 方式3. 明确构建为QueryBuilder.toDynamicJoinQueryWrapper 进行构建
    QueryBuilder.toDynamicJoinQueryWrapper(dto).xxx
1

该方式支持链式追加查询调用

# 3. 支持动态Join的查询条件绑定与结果绑定

动态查询的调用方式有以下两种:

# 方式1. 通过调用BaseService.getEntityList接口
// 调用join关联查询绑定
List<User> list = xxService.getEntityList(queryWrapper);
1
2

# 方式2. 通过Binder调用joinQueryList查询

// 调用join关联查询绑定
List<User> list = Binder.joinQueryList(queryWrapper, User.class);
1
2
# 方式3. 通过DynamicJoinQueryWrapper链式调用查询
QueryBuilder.toDynamicJoinQueryWrapper(dto).queryList(User.class);
1

绑定调用将自动按需(有从表的查询字段时才Join)构建类似如下动态SQL并绑定结果:

  • 无跨表字段的查询:

SELECT self.* FROM user self WHERE self.gender=? AND self.is_deleted=0

  • 有跨表字段的查询:

SELECT self.* FROM user self LEFT OUTER JOIN organization r1 ON self.org_id=r1.id AND r1.is_deleted=0 WHERE self.gender=? AND (r1.name LIKE ?) AND self.is_deleted=0

基于最佳性能最少Join的原则,无SQL查询条件构建仅查询主表数据。 如果需要绑定返回其他关联对象,可再调用Binder关联数据绑定实现。