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

cn.org.atool.fluent.mybatis.segment.SelectorBase Maven / Gradle / Ivy

There is a newer version: 1.9.9
Show newest version
package cn.org.atool.fluent.mybatis.segment;

import cn.org.atool.fluent.mybatis.If;
import cn.org.atool.fluent.mybatis.base.crud.IBaseQuery;
import cn.org.atool.fluent.mybatis.base.model.FieldMapping;
import cn.org.atool.fluent.mybatis.functions.FieldPredicate;
import cn.org.atool.fluent.mybatis.functions.IAggregate;
import cn.org.atool.fluent.mybatis.functions.IGetter;
import cn.org.atool.fluent.mybatis.segment.fragment.Column;
import cn.org.atool.fluent.mybatis.segment.fragment.IFragment;
import cn.org.atool.fluent.mybatis.segment.fragment.JoiningFrag;
import cn.org.atool.fluent.mybatis.utility.LambdaUtil;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import static cn.org.atool.fluent.mybatis.If.notBlank;
import static cn.org.atool.fluent.mybatis.utility.StrConstant.COMMA_SPACE;
import static cn.org.atool.fluent.mybatis.utility.StrConstant.COUNT_ASTERISK;
import static java.util.stream.Collectors.toList;

/**
 * BaseSelector: 查询字段构造
 *
 * @author darui.wu  2020/6/21 3:13 下午
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public abstract class SelectorBase<
    S extends SelectorBase,
    Q extends IBaseQuery
    >
    extends AggregateSegment {

    protected SelectorBase(Q query) {
        super(query);
    }

    protected SelectorBase(S origin, IAggregate aggregate) {
        super(origin, aggregate);
    }

    /**
     * 增加查询字段
     *
     * @param columns 查询字段
     * @return 查询字段选择器
     */
    public S apply(String column, String... columns) {
        this.assertColumns(columns);
        this.applyAs(column, null);
        Stream.of(columns).forEach(c -> this.applyAs(c, null));
        return super.getOrigin();
    }

    /**
     * 增加查询字段
     *
     * @param fields 查询字段(Entity属性名称)
     * @return 查询字段选择器
     */
    public S applyField(String field, String... fields) {
        this.assertColumns(fields);
        this.applyColumn(this.aggregate, this.column(field), null);
        Stream.of(fields).forEach(c -> this.applyColumn(this.aggregate, this.column(c), null));
        return super.getOrigin();
    }

    /**
     * 增加查询字段
     *
     * @param columns 查询字段
     * @return 查询字段选择器
     */
    public S apply(FieldMapping column, FieldMapping... columns) {
        this.assertColumns(columns);
        this.applyAs(column, null);
        Stream.of(columns).forEach(c -> this.applyAs(c, null));
        return super.getOrigin();
    }

    /**
     * 增加查询字段
     *
     * @param getters 查询字段
     * @return 查询字段选择器
     */
    public  S apply(IGetter getter, IGetter... getters) {
        this.assertColumns(getters);
        this.applyColumn(this.aggregate, this.column(LambdaUtil.resolveGetter(getter)), null);
        Stream.of(getters).forEach(c -> this.applyColumn(this.aggregate, this.column(LambdaUtil.resolveGetter(c)), null));
        return super.getOrigin();
    }

    /**
     * 增加带别名的查询字段
     *
     * @param column 查询字段
     * @param alias  别名, 为空时没有别名
     * @return 查询字段选择器
     */
    public S applyAs(final String column, final String alias) {
        return this.applyColumn(this.aggregate, Column.set(this.wrapper, column), alias);
    }

    /**
     * 增加带别名的查询字段
     *
     * @param getter 查询字段
     * @param alias  别名, 为空时没有别名
     * @return 查询字段选择器
     */
    public  S applyAs(final IGetter getter, final String alias) {
        return this.applyColumn(this.aggregate, this.column(LambdaUtil.resolveGetter(getter)), alias);
    }

    /**
     * 增加带别名的查询字段
     *
     * @param field 查询字段(Entity属性名)
     * @param alias 别名, 为空时没有别名
     * @return 查询字段选择器
     */
    public S applyFieldAs(final String field, final String alias) {
        return this.applyColumn(this.aggregate, this.column(field), alias);
    }

    /**
     * 增加带别名的查询字段
     *
     * @param column 查询字段
     * @param alias  别名, 为空时没有别名
     * @return 查询字段选择器
     */
    public S applyAs(final FieldMapping column, final String alias) {
        return this.applyColumn(this.aggregate, Column.set(this.wrapper, column), alias);
    }

    /**
     * 排除查询字段(按数据库字段名称), 无需end()结尾
     *
     * @param columns 要排除的查询字段
     * @return IQuery
     */
    public Q exclude(String... columns) {
        this.assertColumns(columns);
        List excludes = Arrays.asList(columns);
        IFragment seg = this.excludeSelect(excludes, true);
        this.data().select(seg);
        return (Q) super.wrapper;
    }

    /**
     * 排除查询字段(按数据库字段名称), 无需end()结尾
     *
     * @param columns 要排除的查询字段
     * @return IQuery
     */
    public Q excludeField(String... columns) {
        this.assertColumns(columns);
        List excludes = Arrays.asList(columns);
        IFragment seg = this.excludeSelect(excludes, false);
        this.data().select(seg);
        return (Q) super.wrapper;
    }

    /**
     * 排除查询字段, 无需end()结尾
     *
     * @param columns 要排除的查询字段
     * @return IQuery
     */
    public  Q exclude(IGetter... columns) {
        this.assertColumns(columns);
        List excludes = Stream.of(columns).map(LambdaUtil::resolveGetter).collect(toList());
        IFragment seg = this.excludeSelect(excludes, false);
        this.data().select(seg);
        return (Q) super.wrapper;
    }

    /**
     * 排除查询字段, 无需end()结尾
     *
     * @param columns 要排除的查询字段
     * @return IQuery
     */
    public Q exclude(FieldMapping... columns) {
        this.assertColumns(columns);
        List excludes = Stream.of(columns).map(f -> f.column).collect(toList());
        IFragment seg = this.excludeSelect(excludes, true);
        this.data().select(seg);
        return (Q) super.wrapper;
    }

    public S applyFunc(final IAggregate func, final String column, final String alias) {
        return this.applyColumn(func, Column.set(this.wrapper, column), alias);
    }

    public S applyFuncByField(final IAggregate func, final String field, final String alias) {
        return this.applyColumn(func, this.column(field), alias);
    }

    public  S applyFunc(final IAggregate func, final IGetter getter, final String alias) {
        return this.applyColumn(func, this.column(LambdaUtil.resolveGetter(getter)), alias);
    }

    public S applyFunc(final IAggregate func, final FieldMapping column, final String alias) {
        return this.applyColumn(func, Column.set(this.wrapper, column), alias);
    }

    /**
     * count(*) as alias
     *
     * @param alias 别名, 为空时没有别名
     * @return 选择器
     */
    public S count(String alias) {
        return this.applyAs(COUNT_ASTERISK, alias);
    }

    /**
     * 过滤查询的字段信息
     *
     * 

例1: 只要 java 字段名以 "test" 开头的 -> select(i -> i.getProperty().startsWith("test"))

*

例2: 要全部字段 -> select(i -> true)

*

例3: 只要字符串类型字段 -> select(i -> i.getPropertyType instance String)

* * @param predicate 过滤方式 (主键除外!) * @return 字段选择器 */ public S apply(FieldPredicate predicate) { List columns = this.wrapper.getTableMeta().filter(false, predicate); columns.forEach(this::apply); return super.getOrigin(); } /* ================= 非PUBLIC方法 ====================== */ @Override protected S apply() { return this.applyAs(this.current.column, null); } /** * 对当前字段处理,别名处理 * * @param field 字段 * @param alias 别名 * @return 选择器 */ protected S process(FieldMapping field, String alias) { this.current = field; return this.applyAs(field, alias); } private static final String AS = " AS "; /** * 排除查询的字段列表 * * @param excludes 排除查询的字段列表 * @return ignore */ private IFragment excludeSelect(List excludes, boolean byColumnName) { return m -> { JoiningFrag joining = new JoiningFrag(COMMA_SPACE); for (FieldMapping f : m.allFields()) { if (byColumnName && excludes.contains(f.column)) { continue; } else if (!byColumnName && excludes.contains(f.name)) { continue; } joining.add(Column.set(this.wrapper, f)); } return joining.get(m); }; } /** * 添加要查询的字段 * * @param aggregate 聚合函数 * @param column 字段(column name or fieldMapping) * @param alias 别名 * @return ignore */ private S applyColumn(IAggregate aggregate, IFragment column, String alias) { if (aggregate != null) { column = aggregate.aggregate(column); } if (notBlank(alias)) { this.data().getFieldAlias().add(alias); column = column.plus(AS).plus(alias); } this.data().select(column); return super.getOrigin(); } private IFragment column(String fieldName) { return m -> { FieldMapping f = m.getFieldsMap().get(fieldName); if (f == null) { throw new RuntimeException("Field[" + fieldName + "] of Entity[" + m.entityClass().getName() + "] not defined."); } else { return Column.set(this.wrapper, f).get(m); } }; } private void assertColumns(Object[] columns) { if (If.notEmpty(columns) && this.aggregate != null) { throw new RuntimeException("Aggregate functions allow only one apply column."); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy