这个Java类 SQLProvider
主要用于构建和拼接SQL查询语句。以下是类的主要功能和特点的概要描述:
- 类使用StringTemplate库来构建SQL查询模板,通过填充不同的参数来生成最终的SQL语句。
- 提供了多个静态方法来生成不同类型的SQL查询语句,包括基本的查询、带排序的查询、带分页的查询以及为特定图表视图定制的查询。
- 方法接受一个
SQLMeta
对象,它包含了构建SQL查询所需的各种信息,如字段、表、排序条件、过滤条件等。 createQuerySQL
方法用于生成基础的SQL查询语句,可以指定是否需要分组、排序和去重。createQuerySQLWithLimit
方法在基础的查询语句上增加了分页的LIMIT和OFFSET子句。createQuerySQL
重载方法,可以接受一个ChartViewDTO
对象,根据图表视图的需求定制SQL查询,例如添加特定的过滤条件。createQuerySQLNoSort
方法生成不带排序的SQL查询语句,同样可以根据图表视图的需求定制。sqlLimit
方法用于在查询语句后追加LIMIT子句,用于限制返回结果的数量,支持自定义结果数量或默认为图表视图指定的数量。- 类中使用了Apache Commons Lang库中的
ObjectUtils
和StringUtils
工具类来处理对象和字符串。 - SQL语句构建过程中考虑了多种条件,包括自定义的WHERE条件、扩展的WHERE条件和WHERE条件树。
- 类的设计允许灵活地构建针对不同场景的SQL查询语句,同时保持代码的清晰和可维护性。
package io.dataease.engine.sql;
import io.dataease.engine.constant.SQLConstants;
import io.dataease.extensions.datasource.model.SQLMeta;
import io.dataease.extensions.datasource.model.SQLObj;
import io.dataease.extensions.view.dto.ChartViewDTO;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupString;
import java.util.ArrayList;
import java.util.List;
/**
* @Author Junjun
* <p>
* 将SQLMeta各个部分先构建完毕,然后在这个类中拼接
*/
public class SQLProvider {
/**
* @param sqlMeta sql作为table,首尾用'(',')'
* @param isGroup 是否聚合
* @return
*/
public static String createQuerySQLAsTmp(SQLMeta sqlMeta, boolean isGroup, boolean needOrder, boolean distinct) {
return createQuerySQL(sqlMeta, isGroup, needOrder, distinct);
}
public static String createQuerySQLWithLimit(SQLMeta sqlMeta, boolean isGroup, boolean needOrder, boolean distinct, int start, int count) {
return createQuerySQL(sqlMeta, isGroup, needOrder, distinct) " LIMIT " count " OFFSET " start;
}
public static String createQuerySQL(SQLMeta sqlMeta, boolean isGroup, boolean needOrder, boolean distinct) {
List<SQLObj> xFields = sqlMeta.getXFields();
SQLObj tableObj = sqlMeta.getTable();
List<SQLObj> xOrders = sqlMeta.getXOrders();
STGroup stg = new STGroupString(SqlTemplate.PREVIEW_SQL);
ST st_sql = stg.getInstanceOf("previewSql");
st_sql.add("isGroup", isGroup);
st_sql.add("distinct", distinct);
if (ObjectUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
String customWheres = sqlMeta.getCustomWheres();
String extWheres = sqlMeta.getExtWheres();
String whereTrees = sqlMeta.getWhereTrees();
List<String> wheres = new ArrayList<>();
if (customWheres != null) wheres.add(customWheres);
if (extWheres != null) wheres.add(extWheres);
if (whereTrees != null) wheres.add(whereTrees);
if (ObjectUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
// check datasource 是否需要排序
if (needOrder && ObjectUtils.isEmpty(xOrders)) {
if (ObjectUtils.isNotEmpty(xFields)) {
xOrders = new ArrayList<>();
SQLObj sqlObj = xFields.get(0);
SQLObj result = SQLObj.builder()
.orderField(String.format(SQLConstants.FIELD_DOT, sqlObj.getFieldAlias()))
.orderAlias(String.format(SQLConstants.FIELD_DOT, sqlObj.getFieldAlias()))
.orderDirection("ASC").build();
xOrders.add(result);
}
}
if (ObjectUtils.isNotEmpty(xOrders)) {
st_sql.add("orders", xOrders);
}
return st_sql.render();
}
public static String createQuerySQL(SQLMeta sqlMeta, boolean isGroup, boolean needOrder, ChartViewDTO view) {
STGroup stg = new STGroupString(SqlTemplate.PREVIEW_SQL);
ST st_sql = stg.getInstanceOf("previewSql");
st_sql.add("isGroup", isGroup);
SQLObj tableObj = sqlMeta.getTable();
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
List<SQLObj> xFields = sqlMeta.getXFields();
List<SQLObj> xOrders = sqlMeta.getXOrders();
if (ObjectUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
List<SQLObj> yFields = sqlMeta.getYFields();
List<String> yWheres = sqlMeta.getYWheres();
List<SQLObj> yOrders = sqlMeta.getYOrders();
if (ObjectUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields);
String customWheres = sqlMeta.getCustomWheres();
String extWheres = sqlMeta.getExtWheres();
String whereTrees = sqlMeta.getWhereTrees();
List<String> wheres = new ArrayList<>();
if (customWheres != null) wheres.add(customWheres);
if (extWheres != null) wheres.add(extWheres);
if (whereTrees != null) wheres.add(whereTrees);
if (ObjectUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
String sql = st_sql.render();
ST st = stg.getInstanceOf("previewSql");
st_sql.add("isGroup", isGroup);
SQLObj tableSQL = SQLObj.builder()
.tableName(String.format(SQLConstants.BRACKETS, sql))
.tableAlias(String.format(SQLConstants.TABLE_ALIAS_PREFIX, 1))
.build();
if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL);
List<String> aggWheres = new ArrayList<>();
if (ObjectUtils.isNotEmpty(yWheres)) aggWheres.addAll(yWheres);
if (ObjectUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres);
List<SQLObj> orders = new ArrayList<>();
if (ObjectUtils.isNotEmpty(xOrders)) orders.addAll(xOrders);
if (ObjectUtils.isNotEmpty(yOrders)) orders.addAll(yOrders);
// check datasource 是否需要排序
if (needOrder && ObjectUtils.isEmpty(orders)) {
if (ObjectUtils.isNotEmpty(xFields) || ObjectUtils.isNotEmpty(yFields)) {
SQLObj sqlObj = ObjectUtils.isNotEmpty(xFields) ? xFields.get(0) : yFields.get(0);
SQLObj result = SQLObj.builder()
.orderField(String.format(SQLConstants.FIELD_DOT, sqlObj.getFieldAlias()))
.orderAlias(String.format(SQLConstants.FIELD_DOT, sqlObj.getFieldAlias()))
.orderDirection("ASC").build();
orders.add(result);
}
}
if (ObjectUtils.isNotEmpty(orders)) st.add("orders", orders);
return sqlLimit(st.render(), view);
}
public static String createQuerySQLNoSort(SQLMeta sqlMeta, boolean isGroup, ChartViewDTO view) {
STGroup stg = new STGroupString(SqlTemplate.PREVIEW_SQL);
ST st_sql = stg.getInstanceOf("previewSql");
st_sql.add("isGroup", isGroup);
SQLObj tableObj = sqlMeta.getTable();
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
List<SQLObj> xFields = sqlMeta.getXFields();
if (ObjectUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
List<SQLObj> yFields = sqlMeta.getYFields();
List<String> yWheres = sqlMeta.getYWheres();
if (ObjectUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields);
String customWheres = sqlMeta.getCustomWheres();
String extWheres = sqlMeta.getExtWheres();
String whereTrees = sqlMeta.getWhereTrees();
List<String> wheres = new ArrayList<>();
if (customWheres != null) wheres.add(customWheres);
if (extWheres != null) wheres.add(extWheres);
if (whereTrees != null) wheres.add(whereTrees);
if (ObjectUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
String sql = st_sql.render();
ST st = stg.getInstanceOf("previewSql");
st_sql.add("isGroup", isGroup);
SQLObj tableSQL = SQLObj.builder()
.tableName(String.format(SQLConstants.BRACKETS, sql))
.tableAlias(String.format(SQLConstants.TABLE_ALIAS_PREFIX, 1))
.build();
if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL);
List<String> aggWheres = new ArrayList<>();
if (ObjectUtils.isNotEmpty(yWheres)) aggWheres.addAll(yWheres);
if (ObjectUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres);
return sqlLimit(st.render(), view);
}
public static String sqlLimit(String sql, ChartViewDTO view) {
if (StringUtils.equalsIgnoreCase(view.getType(), "table-info")) {
return sql;
}
if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) {
return sql " LIMIT " view.getResultCount() " OFFSET 0";
} else {
return sql;
}
}
}