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

io.github.jinghui70.rainbow.dbaccess.cnd.Cnd Maven / Gradle / Ivy

There is a newer version: 5.2.1
Show newest version
package io.github.jinghui70.rainbow.dbaccess.cnd;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import io.github.jinghui70.rainbow.dbaccess.GeneralSql;
import io.github.jinghui70.rainbow.dbaccess.NamedSql;
import io.github.jinghui70.rainbow.dbaccess.Range;
import io.github.jinghui70.rainbow.dbaccess.Sql;

import java.util.Collection;
import java.util.Map;

import static io.github.jinghui70.rainbow.dbaccess.DbaUtil.enumCheck;

/**
 * 描述一个查询条件的对象,条件的三要素:字段名、比较符、条件值
 */
public class Cnd {

    public static final String IN = " in ";
    public static final String NOT_IN = " not in ";
    public static final String LIKE = " like ";
    public static final String NOT_LIKE = " not like ";

    public static final String WHERE = " WHERE ";
    public static final String AND = " AND ";
    public static final String OR = " OR ";

    protected String field;

    private Op op;

    private Object value;

    protected Cnd() {
    }

    public Cnd(String field, Object value) {
        this(field, Op.EQ, value);
    }

    @Deprecated
    public Cnd(String field, String opStr, Object value) {
        this.field = field;
        this.op = Enum.valueOf(Op.class, opStr.toLowerCase());
        this.value = value;
    }

    public Cnd(String field, Op op, Object value) {
        this.field = field;
        this.op = op;
        switch (op) {
            case LIKE:
            case NOT_LIKE:
                this.value = StrUtil.format("%{}%", value);
                break;
            case LIKE_LEFT:
            case NOT_LIKE_LEFT:
                this.value = "%" + value;
                break;
            case LIKE_RIGHT:
            case NOT_LIKE_RIGHT:
                this.value = value + "%";
                break;
            default:
                this.value = value;
        }
    }


    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public void toSql(GeneralSql sql) {
        sql.append(field);
        if (value instanceof Sql) {
            sql.append(op == Op.EQ ? Op.IN.str() : op.str())
                    .append("(").append((Sql) value).append(")");
            return;
        }
        switch (op) {
            case EQ:
                if (value == null)
                    sql.append(" is null");
                else if (ArrayUtil.isArray(value) || value instanceof Collection) {
                    inSql(sql);
                } else if (!rangeSql(sql))
                    sql.append("=?").addParam(enumCheck(value));
                break;
            case NE:
                if (value == null)
                    sql.append(" is not null");
                else
                    sql.append("!=?").addParam(enumCheck(value));
                break;
            case LIKE:
            case NOT_LIKE:
                sql.append(op).append("?").addParam(value.toString());
                break;
            case IN:
                inSql(sql);
                break;
            case NOT_IN:
                notInSql(sql);
                break;
            default:
                sql.append(op.str()).append("?").addParam(enumCheck(value));
                break;
        }
    }

    private boolean rangeSql(GeneralSql sql) {
        Range range = paramToRange();
        if (range == null)
            return false;
        range.regular();
        if (range.singleValue())
            sql.append("=?").addParam(enumCheck(range.getFrom()));
        else if (range.getFrom() != null) {
            if (range.getTo() == null) {
                sql.append(">=?").addParam(enumCheck(range.getFrom()));
            } else {
                sql.append(StrUtil.SPACE).append("between ? and ?").addParam(enumCheck(range.getFrom()), enumCheck(range.getTo()));
            }
        } else {
            sql.append("<=?").addParam(enumCheck(range.getTo()));
        }
        return true;
    }

    public void toNamedSql(NamedSql sql) {
        switch (op) {
            case EQ:
                Assert.notNull(value, "condition value should not be null");
                if (!rangeNamedSql(sql)) {
                    sql.append(field).append("=:").append(field).setParam(field, value);
                }
                break;
            case IN:
            case NOT_IN:
                throw new RuntimeException("Named Sql does not support in operator");
            default:
                sql.append(field).append(op).append(":").append(field).setParam(field, value);
                break;
        }
    }

    private Range paramToRange() {
        if (value instanceof Map) {
            return BeanUtil.toBeanIgnoreCase(value, Range.class, false);
        } else if (value instanceof Range) {
            return (Range) value;
        } else
            return null;
    }

    private boolean rangeNamedSql(NamedSql sql) {
        Range range = paramToRange();
        if (range == null)
            return false;
        range.regular();
        sql.append(field).append(" between :").append(field).append(" and :").append(field).append("_T")
                .setParam(field, range.getFrom()).setParam(field + "_T", range.getTo());
        return true;
    }

    private void inSql(GeneralSql sql) {
        Object[] arr = valueToArray();
        if (arr.length == 1) {
            sql.append("=?").addParam(enumCheck(arr[0]));
        } else
            sql.append(Cnd.IN).append("(").repeat("?", arr.length).append(")")
                    .addParam(enumCheck(arr));
    }

    private void notInSql(GeneralSql sql) {
        Object[] arr = valueToArray();
        if (arr.length == 1) {
            sql.append("!=?").addParam(enumCheck(arr[0]));
        } else
            sql.append(Cnd.NOT_IN).append("(").repeat("?", arr.length).append(")")
                    .addParam(enumCheck(arr));
    }

    public Object[] valueToArray() {
        Assert.notNull(value);
        if (value instanceof Collection) {
            return ((Collection) value).toArray();
        } else if (ArrayUtil.isArray(value))
            return (Object[]) value;
        throw new RuntimeException("condition value is not a list or array");
    }

    @Override
    public String toString() {
        return "{" + field + " " + op + " " + value + "}";
    }
}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy