深入理解 QueryDSL 的 BooleanBuilder:构建复杂逻辑表达式

深入理解 QueryDSL 的 BooleanBuilder:构建复杂逻辑表达式


在 Java 的查询构建库 QueryDSL 中, BooleanBuilder 是一个非常有用的工具类。它允许开发者通过链式调用轻松地构建复杂的布尔逻辑表达式。本文将详细介绍 BooleanBuilder 的各种方法,并通过代码示例展示如何使用这些方法。

一、方法介绍

1. 构造方法

默认构造方法

BooleanBuilder() 是一个无参构造方法,用于初始化一个空的 BooleanBuilder 实例。

BooleanBuilder builder = new BooleanBuilder();

带初始值的构造方法

BooleanBuilder(Predicate initial) 使用一个初始的 Predicate 对象来构造 BooleanBuilder 实例。

Predicate initialPredicate = QEntity.entity.field.eq("value");
BooleanBuilder builder = new BooleanBuilder(initialPredicate);

2. 逻辑运算方法

and 方法

BooleanBuilder and(@Nullable Predicate right) 用于将当前谓词与 right 谓词进行逻辑“与”操作。

Predicate predicate1 = QEntity.entity.field1.eq("value1");
Predicate predicate2 = QEntity.entity.field2.eq("value2");
BooleanBuilder builder = new BooleanBuilder(predicate1);
builder.and(predicate2);
// 结果为:field1 = "value1" AND field2 = "value2"

andAnyOf 方法

BooleanBuilder andAnyOf(Predicate... args) 将当前谓词与多个谓词中的任意一个进行逻辑“与”操作。

Predicate predicate3 = QEntity.entity.field3.eq("value3");
Predicate predicate4 = QEntity.entity.field4.eq("value4");
builder.andAnyOf(predicate3, predicate4);
// 结果为:field1 = "value1" AND field2 = "value2" AND (field3 = "value3" OR field4 = "value4")

andNot 方法

BooleanBuilder andNot(Predicate right) 将当前谓词与 right 谓词的“非”进行逻辑“与”操作。

Predicate predicate5 = QEntity.entity.field5.eq("value5");
builder.andNot(predicate5);
// 结果为:field1 = "value1" AND field2 = "value2" AND NOT field5 = "value5"

or 方法

BooleanBuilder or(@Nullable Predicate right) 将当前谓词与 right 谓词进行逻辑“或”操作。

Predicate predicate6 = QEntity.entity.field6.eq("value6");
builder.or(predicate6);
// 结果为:(field1 = "value1" AND field2 = "value2") OR field6 = "value6"

orAllOf 方法

BooleanBuilder orAllOf(Predicate... args) 将当前谓词与多个谓词中的所有进行逻辑“或”操作。

Predicate predicate7 = QEntity.entity.field7.eq("value7");
Predicate predicate8 = QEntity.entity.field8.eq("value8");
builder.orAllOf(predicate7, predicate8);
// 结果为:(field1 = "value1" AND field2 = "value2") OR (field7 = "value7" AND field8 = "value8")

orNot 方法

BooleanBuilder orNot(Predicate right) 将当前谓词与 right 谓词的“非”进行逻辑“或”操作。

Predicate predicate9 = QEntity.entity.field9.eq("value9");
builder.orNot(predicate9);
// 结果为:(field1 = "value1" AND field2 = "value2") OR NOT field9 = "value9"

not 方法

BooleanBuilder not() 对当前谓词进行逻辑“非”操作。

builder.not();
// 结果为:NOT (field1 = "value1" AND field2 = "value2")

3. 其他方法

accept 方法

<R, C> R accept(Visitor<R, C> v, C context) 接受一个访问者对象,用于处理当前谓词。

Visitor<String, Void> visitor = new MyVisitor();
String result = builder.accept(visitor, null);

clone 方法

BooleanBuilder clone() throws CloneNotSupportedException 克隆当前 BooleanBuilder 实例。

BooleanBuilder clonedBuilder = builder.clone();

equals 和 hashCode 方法

boolean equals(Object o)int hashCode() 用于判断当前对象与另一个对象是否相等,并返回当前谓词的哈希码。

getValue 方法

@Nullable Predicate getValue() 获取当前的谓词值。

Predicate currentPredicate = builder.getValue();

hasValue 方法

boolean hasValue() 判断当前谓词是否有值。

boolean hasValue = builder.hasValue();

getType 方法

Class<? extends Boolean> getType() 返回布尔类型的类对象。

Class<? extends Boolean> type = builder.getType();

toString 方法

String toString() 返回当前谓词的字符串表示形式。

String predicateString = builder.toString();

二、案例

为了更好地理解 BooleanBuilder 的使用,我们将通过几个完整的案例来展示如何在实际应用中利用这个类构建复杂的查询条件。

案例 1:用户筛选

假设我们有一个用户表 User,我们希望根据多个可选条件来筛选用户,例如用户名、年龄范围和是否激活。

import com.querydsl.core.BooleanBuilder;
import com.querydsl.sql.SQLQueryFactory;
import java.util.List;

public class UserFilter {

    private final SQLQueryFactory queryFactory;

    public UserFilter(SQLQueryFactory queryFactory) {
        this.queryFactory = queryFactory;
    }

    /**
     * 根据用户名、年龄范围和激活状态筛选用户
     * 
     * @param username 用户名
     * @param minAge 最小年龄
     * @param maxAge 最大年龄
     * @param isActive 是否激活
     * @return 满足条件的用户列表
     */
    public List<User> filterUsers(String username, Integer minAge, Integer maxAge, Boolean isActive) {
        QUser qUser = QUser.user;

        // 初始化 BooleanBuilder
        BooleanBuilder builder = new BooleanBuilder();

        // 根据用户名构建条件
        if (username != null) {
            builder.and(qUser.username.eq(username));
        }

        // 根据最小年龄构建条件
        if (minAge != null) {
            builder.and(qUser.age.goe(minAge));
        }

        // 根据最大年龄构建条件
        if (maxAge != null) {
            builder.and(qUser.age.loe(maxAge));
        }

        // 根据激活状态构建条件
        if (isActive != null) {
            builder.and(qUser.isActive.eq(isActive));
        }

        // 执行查询并返回结果
        return queryFactory.selectFrom(qUser)
                           .where(builder)
                           .fetch();
    }
}

案例 2:产品搜索

假设我们有一个产品表 Product,我们希望根据名称、价格区间和类别来进行搜索。

import com.querydsl.core.BooleanBuilder;
import com.querydsl.sql.SQLQueryFactory;
import java.util.List;

public class ProductSearch {

    private final SQLQueryFactory queryFactory;

    public ProductSearch(SQLQueryFactory queryFactory) {
        this.queryFactory = queryFactory;
    }

    /**
     * 根据名称、价格区间和类别搜索产品
     * 
     * @param name 产品名称
     * @param minPrice 最低价格
     * @param maxPrice 最高价格
     * @param category 产品类别
     * @return 满足条件的产品列表
     */
    public List<Product> searchProducts(String name, Double minPrice, Double maxPrice, String category) {
        QProduct qProduct = QProduct.product;

        // 初始化 BooleanBuilder
        BooleanBuilder builder = new BooleanBuilder();

        // 根据名称构建条件
        if (name != null) {
            builder.and(qProduct.name.containsIgnoreCase(name));
        }

        // 根据最低价格构建条件
        if (minPrice != null) {
            builder.and(qProduct.price.goe(minPrice));
        }

        // 根据最高价格构建条件
        if (maxPrice != null) {
            builder.and(qProduct.price.loe(maxPrice));
        }

        // 根据类别构建条件
        if (category != null) {
            builder.and(qProduct.category.eq(category));
        }

        // 执行查询并返回结果
        return queryFactory.selectFrom(qProduct)
                           .where(builder)
                           .fetch();
    }
}

案例 3:订单查询

假设我们有一个订单表 Order,我们想根据客户ID、订单状态和日期范围来查询订单。

import com.querydsl.core.BooleanBuilder;
import com.querydsl.sql.SQLQueryFactory;
import java.time.LocalDate;
import java.util.List;

public class OrderQuery {

    private final SQLQueryFactory queryFactory;

    public OrderQuery(SQLQueryFactory queryFactory) {
        this.queryFactory = queryFactory;
    }

    /**
     * 根据客户ID、订单状态和日期范围查询订单
     * 
     * @param customerId 客户ID
     * @param status 订单状态
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 满足条件的订单列表
     */
    public List<Order> queryOrders(Long customerId, String status, LocalDate startDate, LocalDate endDate) {
        QOrder qOrder = QOrder.order;

        // 初始化 BooleanBuilder
        BooleanBuilder builder = new BooleanBuilder();

        // 根据客户ID构建条件
        if (customerId != null) {
            builder.and(qOrder.customerId.eq(customerId));
        }

        // 根据订单状态构建条件
        if (status != null) {
            builder.and(qOrder.status.eq(status));
        }

        // 根据开始日期构建条件
        if (startDate != null) {
            builder.and(qOrder.orderDate.goe(startDate));
        }

        // 根据结束日期构建条件
        if (endDate != null) {
            builder.and(qOrder.orderDate.loe(endDate));
        }

        // 执行查询并返回结果
        return queryFactory.selectFrom(qOrder)
                           .where(builder)
                           .fetch();
    }
}

三、总结

BooleanBuilder 提供了一种灵活且方便的方式来构建复杂的逻辑条件表达式。通过链式调用,开发者可以轻松地组合多个条件,从而生成复杂的查询逻辑。在实际应用中,它常用于构建动态查询条件,根据不同的业务需求生成相应的 SQL 语句。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值