责任链设计模式 动态绑定demo

package com.meritdata.cloud.multianalysis.customizesearch.handler;

import com.meritdata.cloud.base.entity.QOrganization;
import com.meritdata.cloud.multianalysis.common.enums.*;
import com.meritdata.cloud.multianalysis.common.exception.HandleServiceException;
import com.meritdata.cloud.multianalysis.customizesearch.dto.CustomizeSearchParamDto;
import com.meritdata.cloud.multianalysis.entity.DataSet;
import com.meritdata.cloud.multianalysis.entity.QDataSet;
import com.meritdata.cloud.multianalysis.properties.MultianalyProperties;
import com.meritdata.cloud.utils.MD5;
import com.meritdata.cloud.utils.SessionUtils;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @Author sunyt
 * @Date 2022/6/24 20:00
 * @Description
 */
@Service
@Slf4j
public class CheckSqlHandler extends SqlHandler {

    private final Integer orderId = 1;


    @Autowired
    private JPAQueryFactory jpaQueryFactory;

    @Autowired
    private SessionUtils sessionUtils;

    @Autowired
    private MultianalyProperties multianalyProperties;

    @Override
    public void draw(StringBuilder sqlBuilder, CustomizeSearchParamDto.Table table) {
        if(StringUtils.isBlank(sqlBuilder)) {
            List<CustomizeSearchParamDto.Code> codes = table.getCodes();
            String tableName = "";
            sqlBuilder.append("SELECT ");
            sqlBuilder.append(String.join(",", getColumn(table)));
            sqlBuilder.append(" FROM ");
            if (table.getCode().contains(",")) {
                //拼接多个join on 关联关系
                StringBuilder sb = getJoinSql(table, sqlBuilder);
                sqlBuilder.append(sb);
            } else {
                tableName = getTableName(codes, table.getCode());
                sqlBuilder.append(tableName);
            }
            sqlBuilder.append(this.getFilters(table));
        }else{
            getNext().draw(sqlBuilder,table);
        }
    }

    @Override
    public Integer getOrder() {
        return orderId;
    }

    /**
     * 获取多个关联查询sql
     *
     * @param table
     * @param sqlBuilder
     * @return
     */

    private StringBuilder getJoinSql(CustomizeSearchParamDto.Table table, StringBuilder sqlBuilder) {
        String tableName = null;
        List<CustomizeSearchParamDto.Code> codes = table.getCodes();
        CustomizeSearchParamDto.Join join = table.getJoin();
        String leftTable = join.getLeftTable();
        tableName = getTableName(codes, leftTable);
        sqlBuilder.append(tableName);
        StringBuilder sb = new StringBuilder();
        for (CustomizeSearchParamDto.Relations relation : join.getRelations()) {
            CustomizeSearchParamDto.On on = relation.getOn();
            String relationKey = RelationsEnum.getByName(relation.getRelation()).getValue();
            tableName = getTableName(codes, relation.getRightTable());
            sb.append(relationKey).append(tableName).append(" on ");
            List<CustomizeSearchParamDto.RelationOfOn> relationOfOn = on.getRelation();
            //拼接单个join on  后面可能存在的多个条件
            getConditionOfOn(sb, relationOfOn);
        }
        return sb;
    }

    private String getTableName(List<CustomizeSearchParamDto.Code> codes, String name) {
        String tableName = name;
        if (!CollectionUtils.isEmpty(codes)) {
            QDataSet qDataSet = QDataSet.dataSet;
            Optional<CustomizeSearchParamDto.Code> first = codes.stream().filter(s -> s.getTableName().equals(name)).findFirst();
            CustomizeSearchParamDto.Code code = new CustomizeSearchParamDto.Code();
            if (first.isPresent()) {
                code = first.get();
            }
            if ("SQL".equals(code.getType())) {
                DataSet dataSet = jpaQueryFactory.selectFrom(qDataSet).where(qDataSet.id.eq(code.getModelId())).fetchFirst();
                tableName = " (" + dataSet.getCheckSql() + ") " + code.getTableName();
            }
        }
        return tableName;
    }

    /**
     * 获取单个关联查询的多个查询条件
     *
     * @param sb
     * @param relationOfOn
     */
    private void getConditionOfOn(StringBuilder sb, List<CustomizeSearchParamDto.RelationOfOn> relationOfOn) {
        List<String> relationOfOnList = new ArrayList<>();
        for (CustomizeSearchParamDto.RelationOfOn ofOn : relationOfOn) {
            StringBuilder sbOfOn = new StringBuilder(" ");
            CustomizeSearchParamDto.Column left = ofOn.getLeft();
            String leftFinallyName = getConcat(left.getTableName(), left.getCode());
            CustomizeSearchParamDto.Column right = ofOn.getRight();
            String rightFinallyName = getConcat(right.getTableName(), right.getCode());
            String relationOFOn = ofOn.getRelation();
            SearchLogicalTypeEnum logicalTypeEnum = SearchLogicalTypeEnum.getByCode(relationOFOn);
            String format = String.format(logicalTypeEnum.getSymbol(), rightFinallyName);
            sbOfOn.append(leftFinallyName).append(format.replace(":", ""));
            relationOfOnList.add(sbOfOn.toString());
        }
        sb.append(String.join(" and ", relationOfOnList));
    }

    /**
     * @return
     */
    private StringBuilder getAuth(Map<String, Object> sqlParams, StringBuilder sqlBuilder) {
        if (StringUtils.isBlank(multianalyProperties.getColumn())) {
            return null;
        }
        Boolean rule = multianalyProperties.getRule();
        if (Boolean.TRUE.equals(rule)) {
            sqlParams.put("dLevelCode", sessionUtils.getOrgDlevelCode());
            sqlBuilder.append(" WHERE ").append(multianalyProperties.getColumn()).append(" LIKE :dLevelCode '%'");
        } else {
            QOrganization qOrganization = QOrganization.organization;
            List<String> ids = jpaQueryFactory.select(qOrganization.id).from(qOrganization).where(qOrganization.parentId.eq(sessionUtils.getDeptId())).fetch();
            List<String> deptIds = new ArrayList<>();
            if (ids != null && ids.size() > 0) {
                deptIds.addAll(ids);
                getAuthDeptId(ids, deptIds);
            }
            deptIds.add(sessionUtils.getDeptId());
            sqlParams.put("deptIds", deptIds);
            sqlBuilder.append(" WHERE ").append(multianalyProperties.getColumn()).append(" IN (:deptIds)");
        }
        return sqlBuilder;
    }

    /**
     * 查询该部门下的所有部门
     *
     * @param id
     * @param deptIds
     */
    private void getAuthDeptId(List<String> id, List<String> deptIds) {
        QOrganization qOrganization = QOrganization.organization;
        List<String> ids = jpaQueryFactory.select(qOrganization.id).from(qOrganization).where(qOrganization.parentId.in(id)).fetch();
        if (ids != null && ids.isEmpty()) {
            deptIds.addAll(ids);
            getAuthDeptId(ids, deptIds);
        }

    }


    /**
     * @param table
     * @return
     */
    private List<String> getColumn(CustomizeSearchParamDto.Table table) {
        if (CollectionUtils.isEmpty(table.getColumns())) {
            throw new HandleServiceException("参数错误: 没有选择列");
        }

        List<String> columnList = new ArrayList<>();
        for (CustomizeSearchParamDto.Column column : table.getColumns()) {
            String columnName = null;
            if (StringUtils.isNotBlank(column.getType())) {
                AggregationType type = AggregationType.getByCode(column.getType());
                columnName = AggregationType.getSql(type, getConcat(column.getTableName(), column.getCode()), column.getAlias());
            } else if (StringUtils.isNotBlank(column.getCode())) {
                columnName = getConcat(column.getTableName(), column.getCode()).toUpperCase();

            }
            // 列名不为空  且 没有重复
            if (StringUtils.isNotBlank(columnName) && !columnList.contains(columnName)) {
                if (StringUtils.isNotEmpty(column.getAlias())) {
                    //聚合字段处理
                    if (!columnName.contains("AS")) {
                        columnName = columnName.concat(" as ").concat(column.getAlias());
                    }
                }
                columnList.add(columnName);
            }

        }

        // 如果列为空,则可能是 指标数据,此处查询指标数据
        if (CollectionUtils.isEmpty(columnList) || StringUtils.isNotBlank(table.getCode()) && table.getCode().contains(".")) {
            String tableCode = table.getCode();
            columnList = this.getIndicatorTableAndColumn(tableCode, table);
        }

        if (CollectionUtils.isEmpty(columnList)) {
            throw new HandleServiceException("参数错误: 列为空或者列无效");
        }

        return columnList;
    }

    private String getConcat(String tableName, String column) {
        return tableName.concat(".").concat(column);
    }

    /**
     * @param table
     * @return
     */
    private List<String> getGroupBy(CustomizeSearchParamDto.Table table) {
        List<String> groupbyList = new ArrayList<>();
        if (CollectionUtils.isEmpty(table.getColumns())) {
            return groupbyList;
        }

        for (CustomizeSearchParamDto.Column column : table.getColumns()) {
            if (StringUtils.isBlank(column.getType()) && StringUtils.isNotBlank((column.getCode()))) {
                groupbyList.add(getConcat(column.getTableName(), column.getCode()));
            }
        }

        return groupbyList;
    }

    private List<String> getOrderBy(CustomizeSearchParamDto.Table table) {
        List<String> orderByList = new ArrayList<>();
        if (CollectionUtils.isEmpty(table.getColumns())) {
            return orderByList;
        }

        for (CustomizeSearchParamDto.Column column : table.getColumns()) {
            if (StringUtils.isNotBlank(column.getOrder())) {
                OrderTypeEnum orderTypeEnum = OrderTypeEnum.getByName(column.getOrder());

                if (DataApplyTypeEnum.CROSS.getCode().equals(table.getType())) {
                    String orderCol = AggregationType.getAlias(column.getType(), column.getAlias()).concat(orderTypeEnum.getSql());
                    orderByList.add(orderCol.toUpperCase());
                } else {
                    orderByList.add(getConcat(column.getTableName(), column.getCode()).concat(orderTypeEnum.getSql()));
                }
            }
        }
        return orderByList;
    }

    /**
     * @param indName
     */
    private List<String> getIndicatorTableAndColumn(String indName, CustomizeSearchParamDto.Table table) {
//        List<Indicator> indicatorList = indicatorService.findIndicatorByName(this.getSuffix(indName, "\\."));
//        if (CollectionUtils.isEmpty(indicatorList)) {
//            return Collections.emptyList();
//        }
//
//        // 只取出第一条
//        Indicator indicator = indicatorList.get(0);
//
//        if (StringUtils.isNotBlank(indicator.getTabId())) {
//            MetaTable metaTable = metaTableService.getMetaTableById(indicator.getTabId());
//            table.setOriginalCode(metaTable.getTableName());
//        }
//
//        List<String> columnList = new ArrayList<>();
//        if (StringUtils.isNotBlank(indicator.getColId())) {
//            MetaColumn metaColumn = metaColumnService.getMetaColumnById(indicator.getColId());
//            columnList.add(metaColumn.getColName());
//        }

//        return columnList;
        return  null;
    }

    private String getSuffix(String str, String character) {
        if (StringUtils.isBlank(str)) {
            return str;
        }

        String[] strArray = str.split(character);

        return strArray[strArray.length - 1];
    }

    /**
     * 封装查询条件
     *
     * @param table
     * @return
     */
    private StringBuilder getFilters(CustomizeSearchParamDto.Table table) {
        StringBuilder sqlBuilder = new StringBuilder();
        Map<String, Object> sqlParams = new LinkedHashMap<>();
        StringBuilder auth = this.getAuth(sqlParams, sqlBuilder);
        table.setSqlParams(sqlParams);
        if (CollectionUtils.isEmpty(table.getFilter())) {
            return sqlBuilder;
        }


        String sql;
        for (CustomizeSearchParamDto.Filter filter : table.getFilter()) {
            sql = this.getFilter(filter, sqlParams);
            if (StringUtils.isNotBlank(sql)) {
                if (sqlBuilder.length() > 0) {
                    sqlBuilder.append(" AND ");
                }
                sqlBuilder.append(sql);
            }
        }
        table.setSqlParams(sqlParams);
        // 将sql执行的参数保存到查询参数对象中
        if (auth == null) {
            sqlBuilder.insert(0, " WHERE ");
        }

        return sqlBuilder;
    }

    /**
     * 解析一个条件
     *
     * @param filter
     * @return
     */
    private String getFilter(CustomizeSearchParamDto.Filter filter, Map<String, Object> sqlParams) {
        if (filter == null) {
            return null;
        }

        // 获取字段
        String field = filter.getField();
        // 获取逻辑关系符
        String logical = filter.getLogicalType();
        // 获取值类型
        String valType = filter.getValType();
        // 获取值
        String keywords = filter.getKeywords();
        //
        // 获取值
        String tableName = filter.getTableName();

        SearchLogicalTypeEnum logicalTypeEnum = SearchLogicalTypeEnum.getByCode(logical);
        SearchValTypeEnum valTypeEnum = SearchValTypeEnum.getByCode(valType);


        // 转换参数 以及封装 sql片段
        Map<String, Object> condition = this.getCondition(field, logicalTypeEnum, valTypeEnum, keywords, tableName);
        // 获取参数类型 STRING ARRAY RANGE
        SearchValTypeEnum typeEnum = SearchValTypeEnum.getByCode(String.valueOf(condition.get("type")));
        Object value = condition.get("value");
        switch (typeEnum) {
            case ARRAY:
                List<Object> arrayValueList = (List<Object>) value;
                sqlParams.put(getNamed(field), arrayValueList);
                break;
            case RANGE:
                List<Object> rangeValueList = (List<Object>) value;
                if (CollectionUtils.isEmpty(rangeValueList)) {
                    throw new RuntimeException("Sql params[RANG] error, Need 2 parameters, found 0.");
                } else if (rangeValueList.size() == 1) {
                    sqlParams.put(getNamed(field.concat("_START")), rangeValueList.get(0));
                    sqlParams.put(getNamed(field.concat("_END")), rangeValueList.get(0));
                } else if (rangeValueList.size() >= 2) {
                    sqlParams.put(getNamed(field.concat("_START")), rangeValueList.get(0));
                    sqlParams.put(getNamed(field.concat("_END")), rangeValueList.get(1));
                }
                break;
            case STRING:
            default:
                sqlParams.put(getNamed(field), value);
        }

        return String.valueOf(condition.get("sql"));
    }

    /**
     * 获取其中一个condition条件
     *
     * @param field
     * @param logicType
     * @param valType
     * @param keywords
     * @return 返回的Map中包含:<br>
     * 1) sql: 有:field 占位符的sql条件
     * 2) type: STRING, ARRAY, RANGE
     * 3)value: 值 包含 单个值, N个值的数组, 两个值的数组
     */
    private Map<String, Object> getCondition(String field, SearchLogicalTypeEnum logicType, SearchValTypeEnum valType, String keywords, String tableName) {
        // 返回的结果集
        Map<String, Object> result = new HashMap<>();

        StringBuilder conditionBuilder = new StringBuilder();
        conditionBuilder.append(getConcat(tableName, field));
        conditionBuilder.append(" ");

        Object value = this.getValue(valType, keywords);
        String type = SearchValTypeEnum.STRING.getCode();
        Object[] params;
        switch (logicType) {
            case ISNULL:
                conditionBuilder.append(SearchLogicalTypeEnum.ISNULL.getSymbol());
                break;
            case ISNOTNULL:
                conditionBuilder.append(SearchLogicalTypeEnum.ISNOTNULL.getSymbol());
                break;
            case NOTEQUALS:
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.NOTEQUALS.getSymbol(), getNamed(field)));
                break;
            case LIKE:
                value = "%".concat(String.valueOf(value)).concat("%");
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.LIKE.getSymbol(), getNamed(field)));
                break;
            case NOTLIKE:
                value = "%".concat(String.valueOf(value)).concat("%");
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.NOTLIKE.getSymbol(), getNamed(field)));
                break;
            case IN:
                type = SearchValTypeEnum.ARRAY.getCode();
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.IN.getSymbol(), getNamed(field)));
                break;
            case NOTIN:
                type = SearchValTypeEnum.ARRAY.getCode();
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.NOTIN.getSymbol(), getNamed(field)));
                break;
            case BETWEEN:
                type = SearchValTypeEnum.RANGE.getCode();
                params = new Object[]{getNamed(field.concat("_START")), getNamed(field.concat("_END"))};
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.BETWEEN.getSymbol(), params));
                break;
            case GT:
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.GT.getSymbol(), getNamed(field)));
                break;
            case GTE:
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.GTE.getSymbol(), getNamed(field)));
                break;
            case LT:
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.LT.getSymbol(), getNamed(field)));
                break;
            case LTE:
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.LTE.getSymbol(), getNamed(field)));
                break;
            case EQUALS:
            default:
                conditionBuilder.append(String.format(SearchLogicalTypeEnum.EQUALS.getSymbol(), getNamed(field)));
        }

        result.put("sql", conditionBuilder.toString());
        result.put("type", type);
        result.put("value", value);

        return result;
    }

    /**
     * 值转换
     *
     * @param valType
     * @param keywords
     * @return
     */
    private Object getValue(SearchValTypeEnum valType, String keywords) {
        Object result;
        if (keywords == null) {
            return null;
        }
        switch (valType) {
            case NUMBER:
            case DOUBLE:
                result = getDouble(keywords);
                break;
            case FLOAT:
                result = getFloat(keywords);
                break;
            case INTEGER:
                result = getInteger(keywords);
                break;
            case DATE:
            case ARRAY:
            case RANGE:
                result = Arrays.asList(keywords.split(","));
                break;
            case STRING:
            default:
                result = keywords;
        }

        return result;
    }

    private static Object getInteger(String keywords) {
        try {
            if (StringUtils.isNotBlank(keywords) && keywords.contains(",")) {
                return Arrays.asList(keywords.split(","));
            } else {
                return Integer.parseInt(keywords);
            }
        } catch (Exception e) {
            log.error("Parse error.", e);
            throw new HandleServiceException("参数格式不正确, 需要整数, 实际: " + keywords);
        }
    }

    private static Object getFloat(String keywords) {
        try {
            if (StringUtils.isNotBlank(keywords) && keywords.contains(",")) {
                return Arrays.asList(keywords.split(","));
            } else {
                return Float.parseFloat(keywords);
            }
        } catch (Exception e) {
            log.error("Parse error.", e);
            throw new HandleServiceException("参数格式不正确, 需要小数, 实际: " + keywords);
        }
    }

    private static Object getDouble(String keywords) {
        try {
            if (StringUtils.isNotBlank(keywords) && keywords.contains(",")) {
                return Arrays.asList(keywords.split(","));
            } else {
                return Double.parseDouble(keywords);
            }
        } catch (Exception e) {
            log.error("Parse error.", e);
            throw new HandleServiceException("参数格式不正确, 需要数字, 实际: " + keywords);
        }
    }

    /**
     * 使用MD5 处理占位符,避免中文字段
     *
     * @param str
     * @return
     */
    private static String getNamed(String str) {
        return "P_".concat(MD5.get(str));
    }

    /**
     * 获取查询 sql
     *
     * @param table
     * @return
     */
    private String getSql(CustomizeSearchParamDto.Table table) {
        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append(table.getSql());
        if (StringUtils.isNotBlank(table.getPageSql())) {
            sqlBuilder.append(table.getPageSql());
        }
        return sqlBuilder.toString();
    }

    /**
     * 获取count sql
     *
     * @param table
     * @return
     */
    private String getCountSql(CustomizeSearchParamDto.Table table) {
        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("SELECT COUNT(1) CNT FROM (");
        sqlBuilder.append(table.getSql());
        sqlBuilder.append(") AS CONT");

        return sqlBuilder.toString();
    }





    /**
     * 获取左侧维度的数据集合  单行数据
     *
     * @param row
     * @param dimSize
     * @return
     */
    private static List<String> getDimDataList(Object[] row, int dimSize) {
        List<String> dimData = new ArrayList<>();
        for (int i = 0; i < dimSize; i++) {
            dimData.add(Objects.isNull(row[i]) ? null : String.valueOf(row[i]));
        }
        return dimData;
    }


}

package com.meritdata.cloud.multianalysis.customizesearch.handler;

import com.meritdata.cloud.multianalysis.common.enums.DataApplyTypeEnum;
import com.meritdata.cloud.multianalysis.customizesearch.dto.CustomizeSearchParamDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

// 分组
@Slf4j
@Service
public class GroupBySqlHandler extends SqlHandler {

    private final Integer orderId = 2;

    @Override
    public void draw(StringBuilder sqlBuilder, CustomizeSearchParamDto.Table table) {
        if (DataApplyTypeEnum.CROSS.getCode().equals(table.getType())) {
//            // 获取group sql片段
            List<String> groupby = this.getGroupBy(table);
            if (!CollectionUtils.isEmpty(groupby)) {
                sqlBuilder.append(" GROUP BY ");
                sqlBuilder.append(String.join(",", groupby));
            }
        }else{
            getNext().draw(sqlBuilder,table);
        }

    }

    @Override
    public Integer getOrder() {
        return orderId;
    }


    /**
     * @param table
     * @return
     */
    private List<String> getGroupBy(CustomizeSearchParamDto.Table table) {
        List<String> groupbyList = new ArrayList<>();
        if (CollectionUtils.isEmpty(table.getColumns())) {
            return groupbyList;
        }

        for (CustomizeSearchParamDto.Column column : table.getColumns()) {
            if (StringUtils.isBlank(column.getType()) && StringUtils.isNotBlank((column.getCode()))) {
                groupbyList.add(getConcat(column.getTableName(), column.getCode()));
            }
        }

        return groupbyList;
    }

    private String getConcat(String tableName, String column) {
        return tableName.concat(".").concat(column);
    }


}


package com.meritdata.cloud.multianalysis.customizesearch.handler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author sunyt
 * @Date 2022/6/24 19:41
 * @Description
 */
@Component
public class HandlerChain {
    @Autowired
    private ApplicationContext applicationContext;

    private SqlHandler sqlHandler;

    public SqlHandler getHandler() {
        return sqlHandler;
    }

    @PostConstruct
    public void afterPropertiesSet() {
        Map<String, SqlHandler> beansOfTypeMap = applicationContext.getBeansOfType(SqlHandler.class);
        if (beansOfTypeMap == null || beansOfTypeMap.size() == 0) {
            return;
        }
        List<SqlHandler> sqlHandlers = beansOfTypeMap.values().stream()
                .sorted((s1, s2) -> s1.getOrder().compareTo(s2.getOrder()))
                .collect(Collectors.toList());
        for (int i = 1; i < sqlHandlers.size(); i++) {
            //当前处理器
            SqlHandler sqlHandler = sqlHandlers.get(i - 1);
            //下一个处理器
            SqlHandler nextHandler = sqlHandlers.get(i);
            //将处理器串成链表
            sqlHandler.setNext(nextHandler);
        }
        this.sqlHandler = sqlHandlers.get(0);


    }

}

package com.meritdata.cloud.multianalysis.customizesearch.handler;

import com.meritdata.cloud.multianalysis.customizesearch.dto.CustomizeSearchParamDto;

/**
 * Handler: 抽象处理者
 */
public abstract class SqlHandler {

    // 持有后继责任对象
    protected SqlHandler next;

    public abstract void draw(StringBuilder sqlBuilder,CustomizeSearchParamDto.Table table);


    public SqlHandler getNext() {
        return next;
    }
    public void setNext(SqlHandler next) {
        this.next = next;
    }
    public abstract Integer getOrder();
}

orderId是为了排序 或者文件时候用了几种方法都没法处理成我们自己想要的加载顺序,故此加载完毕后根据orderId 再排序
// 调用如下

StringBuilder sqlBuilder = new StringBuilder();
SqlHandler handler = handlerChain.getHandler();
handler.draw(sqlBuilder,table);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值