All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.chengyuxing.sql.dsl.clause.Where Maven / Gradle / Ivy

Go to download

Light wrapper of JDBC, support ddl, dml, query, plsql/procedure/function, transaction and manage sql file.

There is a newer version: 9.0.2
Show newest version
package com.github.chengyuxing.sql.dsl.clause;

import com.github.chengyuxing.common.tuple.Pair;
import com.github.chengyuxing.sql.dsl.clause.condition.*;
import com.github.chengyuxing.sql.dsl.types.FieldReference;
import com.github.chengyuxing.sql.dsl.types.Logic;
import com.github.chengyuxing.sql.dsl.types.Operator;
import com.github.chengyuxing.sql.utils.SqlGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;

import static com.github.chengyuxing.sql.dsl.types.StandardOperator.*;

/**
 * Where clause builder.
 *
 * @param  entity type
 */
public abstract class Where extends CriteriaBuilder {
    protected List criteria = new ArrayList<>();

    /**
     * Construct a new Where builder.
     *
     * @param clazz entity class
     */
    public Where(@NotNull Class clazz) {
        super(clazz);
    }

    /**
     * Construct a new Where builder with initial Where builder.
     *
     * @param clazz entity class
     * @param other where builder
     */
    public Where(@NotNull Class clazz, @NotNull Where other) {
        super(clazz);
        this.criteria = other.criteria;
    }

    /**
     * Returns a new Where builder.
     *
     * @return where builder
     */
    protected abstract Where newInstance();

    /**
     * Add a condition.
     *
     * @param column     column
     * @param operator   {@link com.github.chengyuxing.sql.dsl.types.StandardOperator StandardOperator} or other trusted operator
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where of(FieldReference column, @NotNull Operator operator, E value, Predicate... predicates) {
        if (operator == Logic.AND || operator == Logic.OR) {
            throw new IllegalArgumentException("logic operator '" + operator.getValue() + "' invalid at this time");
        }
        if (isConditionMatched(value, predicates)) {
            addCondition(column, operator, value);
        }
        return this;
    }

    /**
     * {@code =}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where eq(FieldReference column, E value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            if (Objects.nonNull(value)) {
                addCondition(column, EQ, value);
            } else {
                addCondition(column, IS_NULL, null);
            }
        }
        return this;
    }

    /**
     * {@code <>}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where neq(FieldReference column, E value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            if (Objects.nonNull(value)) {
                addCondition(column, NEQ, value);
            } else {
                addCondition(column, IS_NOT_NULL, null);
            }
        }
        return this;
    }

    /**
     * {@code >}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where gt(FieldReference column, E value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, GT, value);
        }
        return this;
    }

    /**
     * {@code <}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where lt(FieldReference column, E value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, LT, value);
        }
        return this;
    }

    /**
     * {@code >=}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where gte(FieldReference column, E value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, GTE, value);
        }
        return this;
    }

    /**
     * {@code <=}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where lte(FieldReference column, E value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, LTE, value);
        }
        return this;
    }

    /**
     * {@code in (...)}
     *
     * @param column     column
     * @param values     {@link Collection} or Array.
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value item type
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final > Where in(FieldReference column, V values, Predicate... predicates) {
        if (isConditionMatched(values, predicates)) {
            criteria.add(new InCondition<>(getColumnName(column), IN, values));
        }
        return this;
    }

    /**
     * {@code not in (...)}
     *
     * @param column     column
     * @param values     {@link Collection} or Array.
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value item type
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final > Where notIn(FieldReference column, V values, Predicate... predicates) {
        if (isConditionMatched(values, predicates)) {
            criteria.add(new InCondition<>(getColumnName(column), NOT_IN, values));
        }
        return this;
    }

    /**
     * {@code between} a {@code and} b
     *
     * @param column     column
     * @param a          value 1.
     * @param b          value 2.
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where between(FieldReference column, E a, E b, BiPredicate... predicates) {
        if (isConditionMatched(a, b, predicates)) {
            criteria.add(new BetweenCondition(getColumnName(column), BETWEEN, Pair.of(a, b)));
        }
        return this;
    }

    /**
     * {@code not between} a {@code and} b
     *
     * @param column     column
     * @param a          value 1.
     * @param b          value 2.
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @param         value type
     * @return where builder
     */
    @SafeVarargs
    public final  Where notBetween(FieldReference column, E a, E b, BiPredicate... predicates) {
        if (isConditionMatched(a, b, predicates)) {
            criteria.add(new BetweenCondition(getColumnName(column), NOT_BETWEEN, Pair.of(a, b)));
        }
        return this;
    }

    /**
     * {@code like '%} str {@code %'}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    @SafeVarargs
    public final Where like(FieldReference column, String value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, LIKE, "%" + value + "%");
        }
        return this;
    }

    /**
     * {@code not like '%} str {@code %'}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    @SafeVarargs
    public final Where notLike(FieldReference column, String value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, NOT_LIKE, "%" + value + "%");
        }
        return this;
    }

    /**
     * {@code like '} str {@code %'}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    @SafeVarargs
    public final Where startsWith(FieldReference column, String value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, LIKE, value + "%");
        }
        return this;
    }

    /**
     * {@code not like '} str {@code %'}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    @SafeVarargs
    public final Where notStartsWith(FieldReference column, String value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, NOT_LIKE, value + "%");
        }
        return this;
    }

    /**
     * {@code like '%} str {@code '}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    @SafeVarargs
    public final Where endsWith(FieldReference column, String value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, LIKE, "%" + value);
        }
        return this;
    }

    /**
     * {@code not like '%} str {@code '}
     *
     * @param column     column
     * @param value      value
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    @SafeVarargs
    public final Where notEndsWith(FieldReference column, String value, Predicate... predicates) {
        if (isConditionMatched(value, predicates)) {
            addCondition(column, NOT_LIKE, "%" + value);
        }
        return this;
    }

    /**
     * {@code is null}
     *
     * @param column     column
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    public Where isNull(FieldReference column, boolean... predicates) {
        if (isConditionMatched(predicates)) {
            addCondition(column, IS_NULL, null);
        }
        return this;
    }

    /**
     * {@code is not null}
     *
     * @param column     column
     * @param predicates all predicates to the true add the condition otherwise avoid the condition.
     * @return where builder
     */
    public Where isNotNull(FieldReference column, boolean... predicates) {
        if (isConditionMatched(predicates)) {
            addCondition(column, IS_NOT_NULL, null);
        }
        return this;
    }

    /**
     * And group, all condition will be concat with {@code or}, {@code and (...or...or...or...)}
* E.g. the complex nest condition: *
     * ((name = 'cyx' and age = 30) or (name = 'jack' and age = 60))
     * 
* The built struct: *
     * w -> w.and(o -> o.or(a -> a.eq(Guest::getName, "cyx")
     *                          .eq(Guest::getAge, 30))
     *                  .or(r -> r.eq(Guest::getName, "jack")
     *                          .eq(Guest::getAge, 60))
     *          )
     * 
* * @param orGroup and group * @param predicates all predicates to the true add the group otherwise avoid the group. * @return where builder * @see #or(Function, boolean...) */ public Where and(Function, Where> orGroup, boolean... predicates) { if (isConditionMatched(predicates)) { List criteriaList = orGroup.apply(newInstance()).criteria; criteria.add(new AndGroup(criteriaList)); } return this; } /** * Or group, all condition will be concat with {@code and}, {@code or (...and...ang...and...)}
* E.g. simple nest condition: *
     * {@code (age < 15 or age > 60) and name = 'cyx'}
     * 
*
     * w -> w.and(o -> o.lt(Guest::getAge, 15)
     *               .gt(Guest::getAge, 60))
     *       .eq(Guest::getName, "cyx")
     * 
* * @param andGroup or group * @param predicates all predicates to the true add the group otherwise avoid the group. * @return where builder * @see #and(Function, boolean...) */ public Where or(Function, Where> andGroup, boolean... predicates) { if (isConditionMatched(predicates)) { List criteriaList = andGroup.apply(newInstance()).criteria; criteria.add(new OrGroup(criteriaList)); } return this; } /** * Returns a where condition consisting of the where builder, check the built result currently. * * @param consumer built result consumer (sql, (name parameter sql, params)) -> _ * @return where builder */ public Where peek(BiConsumer>> consumer) { Pair> where = build(); String sql = new SqlGenerator(namedParamPrefix()).generateSql(where.getItem1(), where.getItem2()); consumer.accept(sql, where); return this; } /** * Returns where clause and params. * * @return where clause and params. */ protected @NotNull @Unmodifiable Pair> build() { Pair> where = build(new AtomicInteger(0), criteria, Logic.AND, 0); if (!where.getItem1().isEmpty()) { return Pair.of("\nwhere " + where.getItem1(), Collections.unmodifiableMap(where.getItem2())); } return where; } private void addCondition(FieldReference column, Operator operator, Object value) { criteria.add(new Condition<>(getColumnName(column), operator, value)); } private static boolean isConditionMatched(boolean... predicates) { boolean matched = true; for (boolean predicate : predicates) { if (!predicate) { matched = false; break; } } return matched; } @SafeVarargs private static boolean isConditionMatched(E value, Predicate... predicates) { boolean matched = true; for (Predicate predicate : predicates) { if (!predicate.test(value)) { matched = false; break; } } return matched; } @SafeVarargs private static boolean isConditionMatched(E a, E b, BiPredicate... predicates) { boolean matched = true; for (BiPredicate predicate : predicates) { if (!predicate.test(a, b)) { matched = false; break; } } return matched; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy