DataSource增加可group by的queryColumnMap系列方法,缓存EntityCache部分未实现

This commit is contained in:
Redkale
2020-01-11 13:32:31 +08:00
parent fa833d9224
commit 6aa3949d05
9 changed files with 536 additions and 35 deletions

View File

@@ -0,0 +1,83 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.source;
import java.io.Serializable;
/**
* 与ColumnNodeValue 组合,用于复杂的字段表达式 。
* String 视为 字段名
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.0.0
*/
public class ColumnFuncNode implements ColumnNode {
protected FilterFunc func;
protected Serializable value;//类型只能是String、ColumnNodeValue
public ColumnFuncNode() {
}
public ColumnFuncNode(FilterFunc func, Serializable node) {
if (!(node instanceof String) && !(node instanceof ColumnNodeValue)) throw new IllegalArgumentException("value must be String or ColumnNodeValue");
this.func = func;
this.value = node;
}
public static ColumnFuncNode create(FilterFunc func, Serializable node) {
return new ColumnFuncNode(func, node);
}
public static ColumnFuncNode avg(Serializable node) {
return new ColumnFuncNode(FilterFunc.AVG, node);
}
public static ColumnFuncNode count(Serializable node) {
return new ColumnFuncNode(FilterFunc.COUNT, node);
}
public static ColumnFuncNode distinctCount(Serializable node) {
return new ColumnFuncNode(FilterFunc.DISTINCTCOUNT, node);
}
public static ColumnFuncNode max(Serializable node) {
return new ColumnFuncNode(FilterFunc.MAX, node);
}
public static ColumnFuncNode min(Serializable node) {
return new ColumnFuncNode(FilterFunc.MIN, node);
}
public static ColumnFuncNode sum(Serializable node) {
return new ColumnFuncNode(FilterFunc.SUM, node);
}
public FilterFunc getFunc() {
return func;
}
public void setFunc(FilterFunc func) {
this.func = func;
}
public Serializable getValue() {
return value;
}
public void setValue(Serializable value) {
this.value = value;
}
@Override
public String toString() {
return "{\"func\":\"" + func + "\", \"value\":" + ((value instanceof CharSequence) ? ("\"" + value + "\"") : value) + "}";
}
}

View File

@@ -0,0 +1,21 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.source;
import java.io.Serializable;
/**
* ColumnFuncNode与ColumnNodeValue 的接口
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.0.0
*/
public interface ColumnNode extends Serializable {
}

View File

@@ -13,21 +13,33 @@ import static org.redkale.source.ColumnExpress.*;
* String 视为 字段名
* Number 视为 数值
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.0.0
*/
public class ColumnNodeValue implements Serializable {
public class ColumnNodeValue implements ColumnNode {
private Serializable left;//类型只能是String、Number、ColumnNodeValue
protected Serializable left;//类型只能是String、Number、ColumnNodeValue
private ColumnExpress express; //不能是MOV
protected ColumnExpress express; //不能是MOV
private Serializable right;//类型只能是String、Number、ColumnNodeValue
protected Serializable right;//类型只能是String、Number、ColumnNodeValue
public ColumnNodeValue() {
}
public ColumnNodeValue(Serializable left, ColumnExpress express, Serializable right) {
if (express == null || express == ColumnExpress.MOV) throw new IllegalArgumentException("express cannot be null or MOV");
if (express == null || express == ColumnExpress.MOV) {
throw new IllegalArgumentException("express cannot be null or MOV");
}
if (!(left instanceof String) && !(left instanceof Number) && !(left instanceof ColumnNodeValue) && !(left instanceof ColumnFuncNode)) {
throw new IllegalArgumentException("left value must be String, Number, ColumnFuncNode or ColumnNodeValue");
}
if (!(right instanceof String) && !(right instanceof Number) && !(right instanceof ColumnNodeValue) && !(right instanceof ColumnFuncNode)) {
throw new IllegalArgumentException("right value must be String, Number, ColumnFuncNode or ColumnNodeValue");
}
this.left = left;
this.express = express;
this.right = right;
@@ -72,7 +84,7 @@ public class ColumnNodeValue implements Serializable {
public ColumnNodeValue dec(Serializable right) {
return any(DEC, right);
}
public ColumnNodeValue mul(Serializable right) {
return any(MUL, right);
}

View File

@@ -421,6 +421,42 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
}
}
@Override
protected <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapDB(EntityInfo<T> info, String sql, final ColumnNode[] funcNodes, final String[] groupByColumns) {
Connection conn = null;
Map rs = new LinkedHashMap<>();
try {
conn = readPool.poll();
//conn.setReadOnly(true);
final Statement stmt = conn.createStatement();
ResultSet set = stmt.executeQuery(sql);
ResultSetMetaData rsd = set.getMetaData();
boolean smallint = rsd == null ? false : rsd.getColumnType(1) == Types.SMALLINT;
while (set.next()) {
int index = 0;
Serializable[] keys = new Serializable[groupByColumns.length];
for (int i = 0; i < keys.length; i++) {
keys[i] = (Serializable) ((smallint && index == 0) ? set.getShort(++index) : set.getObject(++index));
}
Number[] vals = new Number[funcNodes.length];
for (int i = 0; i < vals.length; i++) {
vals[i] = (Number) set.getObject(++index);
}
rs.put(keys, vals);
}
set.close();
stmt.close();
return CompletableFuture.completedFuture(rs);
} catch (SQLException e) {
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(rs);
CompletableFuture future = new CompletableFuture();
future.completeExceptionally(e);
return future;//return CompletableFuture.failedFuture(e);
} finally {
if (conn != null) readPool.offerConnection(conn);
}
}
@Override
protected <T> CompletableFuture<T> findDB(EntityInfo<T> info, String sql, boolean onlypk, SelectColumn selects) {
Connection conn = null;

View File

@@ -128,6 +128,11 @@ public class DataMemorySource extends DataSqlSource<Void> {
return CompletableFuture.completedFuture(null);
}
@Override
protected <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapDB(final EntityInfo<T> info, final String sql, final ColumnNode[] funcNodes, final String[] groupByColumns) {
return CompletableFuture.completedFuture(null);
}
@Override
protected <T> CompletableFuture<T> findDB(EntityInfo<T> info, String sql, boolean onlypk, SelectColumn selects) {
return CompletableFuture.completedFuture(null);

View File

@@ -702,7 +702,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回null <br>
* 等价SQL: SELECT FUNC{column} FROM {table} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.COUNT, null) 等价于: SELECT COUNT(*) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.COUNT, null) 等价于: SELECT COUNT(*) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -715,7 +715,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回null <br>
* 等价SQL: SELECT FUNC{column} FROM {table} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.COUNT, null) 等价于: SELECT COUNT(*) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.COUNT, null) 等价于: SELECT COUNT(*) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -728,7 +728,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回null <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter bean} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.COUNT, null, (FilterBean)null) 等价于: SELECT COUNT(*) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.COUNT, null, (FilterBean)null) 等价于: SELECT COUNT(*) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -742,7 +742,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回null <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter bean} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.COUNT, null, (FilterBean)null) 等价于: SELECT COUNT(*) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.COUNT, null, (FilterBean)null) 等价于: SELECT COUNT(*) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -756,7 +756,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回null <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter node} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -770,7 +770,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回null <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter node} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -784,7 +784,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回默认值 <br>
* 等价SQL: SELECT FUNC{column} FROM {table} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime") 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime") 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -798,7 +798,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回默认值 <br>
* 等价SQL: SELECT FUNC{column} FROM {table} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime") 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime") 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -812,7 +812,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回默认值 <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter bean} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -827,7 +827,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回默认值 <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter bean} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -842,7 +842,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回默认值 <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter node} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -857,7 +857,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果, 无结果返回默认值 <br>
* 等价SQL: SELECT FUNC{column} FROM {table} WHERE {filter node} <br>
* 如 getNumberResultAsync(Record.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberResultAsync(User.class, FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param entityClass Entity类
* @param func 聚合函数
@@ -872,7 +872,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果Map <br>
* 等价SQL: SELECT FUNC1{column1}, FUNC2{column2}, &#183;&#183;&#183; FROM {table} <br>
* 如 getNumberMapAsync(Record.class, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberMapAsync(User.class, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param <N> Number
* @param entityClass Entity类
@@ -885,7 +885,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果Map <br>
* 等价SQL: SELECT FUNC1{column1}, FUNC2{column2}, &#183;&#183;&#183; FROM {table} <br>
* 如 getNumberMapAsync(Record.class, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberMapAsync(User.class, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param <N> Number
* @param entityClass Entity类
@@ -898,7 +898,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果Map <br>
* 等价SQL: SELECT FUNC1{column1}, FUNC2{column2}, &#183;&#183;&#183; FROM {table} WHERE {filter bean} <br>
* 如 getNumberMapAsync(Record.class, (FilterBean)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberMapAsync(User.class, (FilterBean)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param <N> Number
* @param entityClass Entity类
@@ -912,7 +912,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果Map <br>
* 等价SQL: SELECT FUNC1{column1}, FUNC2{column2}, &#183;&#183;&#183; FROM {table} WHERE {filter bean} <br>
* 如 getNumberMapAsync(Record.class, (FilterBean)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberMapAsync(User.class, (FilterBean)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param <N> Number
* @param entityClass Entity类
@@ -926,7 +926,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果Map <br>
* 等价SQL: SELECT FUNC1{column1}, FUNC2{column2}, &#183;&#183;&#183; FROM {table} WHERE {filter node} <br>
* 如 getNumberMapAsync(Record.class, (FilterNode)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberMapAsync(User.class, (FilterNode)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param <N> Number
* @param entityClass Entity类
@@ -940,7 +940,7 @@ public interface DataSource {
/**
* 获取符合过滤条件记录的聚合结果Map <br>
* 等价SQL: SELECT FUNC1{column1}, FUNC2{column2}, &#183;&#183;&#183; FROM {table} WHERE {filter node} <br>
* 如 getNumberMapAsync(Record.class, (FilterNode)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
* 如 getNumberMapAsync(User.class, (FilterNode)null, new FilterFuncColumn(FilterFunc.MAX, "createtime")) 等价于: SELECT MAX(createtime) FROM {table} <br>
*
* @param <N> Number
* @param entityClass Entity类
@@ -954,7 +954,7 @@ public interface DataSource {
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT keyColumn, FUNC{funcColumn} FROM {table} GROUP BY {keyColumn} <br>
* 如 queryColumnMapAsync(Record.class, "name", FilterFunc.MAX, "createtime") 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
* 如 queryColumnMapAsync(User.class, "name", FilterFunc.MAX, "createtime") 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
@@ -971,7 +971,7 @@ public interface DataSource {
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT keyColumn, FUNC{funcColumn} FROM {table} GROUP BY {keyColumn} <br>
* 如 queryColumnMapAsync(Record.class, "name", FilterFunc.MAX, "createtime") 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
* 如 queryColumnMapAsync(User.class, "name", FilterFunc.MAX, "createtime") 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
@@ -988,7 +988,7 @@ public interface DataSource {
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT keyColumn, FUNC{funcColumn} FROM {table} WHERE {filter bean} GROUP BY {keyColumn} <br>
* 如 queryColumnMapAsync(Record.class, "name", FilterFunc.MAX, "createtime", (FilterBean)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
* 如 queryColumnMapAsync(User.class, "name", FilterFunc.MAX, "createtime", (FilterBean)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
@@ -1006,7 +1006,7 @@ public interface DataSource {
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT keyColumn, FUNC{funcColumn} FROM {table} WHERE {filter bean} GROUP BY {keyColumn} <br>
* 如 queryColumnMapAsync(Record.class, "name", FilterFunc.MAX, "createtime", (FilterBean)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
* 如 queryColumnMapAsync(User.class, "name", FilterFunc.MAX, "createtime", (FilterBean)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
@@ -1024,7 +1024,7 @@ public interface DataSource {
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT keyColumn, FUNC{funcColumn} FROM {table} WHERE {filter node} GROUP BY {keyColumn} <br>
* 如 queryColumnMapAsync(Record.class, "name", FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
* 如 queryColumnMapAsync(User.class, "name", FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
@@ -1042,7 +1042,7 @@ public interface DataSource {
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT keyColumn, FUNC{funcColumn} FROM {table} WHERE {filter node} GROUP BY {keyColumn} <br>
* 如 queryColumnMapAsync(Record.class, "name", FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
* 如 queryColumnMapAsync(User.class, "name", FilterFunc.MAX, "createtime", (FilterNode)null) 等价于: SELECT name, MAX(createtime) FROM user GROUP BY name<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
@@ -1057,6 +1057,218 @@ public interface DataSource {
*/
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N>> queryColumnMapAsync(final Class<T> entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterNode node);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE GROUP BY {col1} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), "targetid")
* 等价于: SELECT targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumn GROUP BY字段
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> Map<K, N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} GROUP BY {col1} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), "targetid")
* 等价于: SELECT targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumn GROUP BY字段
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter bean} GROUP BY {col1} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), "targetid", (FilterBean)null)
* 等价于: SELECT targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumn GROUP BY字段
* @param bean 过滤条件
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> Map<K, N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterBean bean);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter bean} GROUP BY {col1} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), "targetid", (FilterBean)null)
* 等价于: SELECT targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumn GROUP BY字段
* @param bean 过滤条件
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterBean bean);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter node} GROUP BY {col1} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), "targetid", (FilterNode)null)
* 等价于: SELECT targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumn GROUP BY字段
* @param node 过滤条件
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> Map<K, N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterNode node);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter node} GROUP BY {col1} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), "targetid", (FilterNode)null)
* 等价于: SELECT targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumn GROUP BY字段
* @param node 过滤条件
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterNode node);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, col2, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} GROUP BY {col1}, {col2} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), Utility.ofArray("fromid", "targetid"))
* 等价于: SELECT fromid, targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY fromid, targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumns GROUP BY字段
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> Map<K[], N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, col2, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} GROUP BY {col1}, {col2} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), Utility.ofArray("fromid", "targetid"))
* 等价于: SELECT fromid, targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY fromid, targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumns GROUP BY字段
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, col2, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter bean} GROUP BY {col1}, {col2} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), Utility.ofArray("fromid", "targetid"), (FilterBean)null)
* 等价于: SELECT fromid, targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY fromid, targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumns GROUP BY字段
* @param bean 过滤条件
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> Map<K[], N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterBean bean);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, col2, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter bean} GROUP BY {col1}, {col2} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), Utility.ofArray("fromid", "targetid"), (FilterBean)null)
* 等价于: SELECT fromid, targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY fromid, targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumns GROUP BY字段
* @param bean 过滤条件
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterBean bean);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, col2, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter node} GROUP BY {col1}, {col2} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), Utility.ofArray("fromid", "targetid"), (FilterNode)null)
* 等价于: SELECT fromid, targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY fromid, targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumns GROUP BY字段
* @param node 过滤条件
*
* @return 聚合结果Map
*/
public <T, K extends Serializable, N extends Number> Map<K[], N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterNode node);
/**
* 查询符合过滤条件记录的GROUP BY聚合结果Map <br>
* 等价SQL: SELECT col1, col2, FUNC{funcColumn1}, FUNC{funcColumn2} FROM {table} WHERE {filter node} GROUP BY {col1}, {col2} <br>
* 如 queryColumnMapAsync(OrderRecord.class, Utility.ofArray(ColumnNodeValue.div(ColumnFuncNode.sum("money"), 100), ColumnFuncNode.avg(ColumnNodeValue.dec("money", 20)))), Utility.ofArray("fromid", "targetid"), (FilterNode)null)
* 等价于: SELECT fromid, targetid, SUM(money) / 100, AVG(money - 20) FROM orderrecord GROUP BY fromid, targetid<br>
*
* @param <T> Entity泛型
* @param <K> Key字段的数据类型
* @param <N> Number
* @param entityClass Entity类
* @param funcNodes ColumnNode[]
* @param groupByColumns GROUP BY字段
* @param node 过滤条件
*
* @return 聚合结果Map CompletableFuture
*/
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterNode node);
//-----------------------findAsync----------------------------
/**
* 获取指定主键值的单个记录, 返回null表示不存在值 <br>

View File

@@ -157,6 +157,9 @@ public abstract class DataSqlSource<DBChannel> extends AbstractService implement
//查询Map数据
protected abstract <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N>> queryColumnMapDB(final EntityInfo<T> info, final String sql, final String keyColumn);
//查询Map数据
protected abstract <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapDB(final EntityInfo<T> info, final String sql, final ColumnNode[] funcNodes, final String[] groupByColumns);
//查询单条记录
protected abstract <T> CompletableFuture<T> findDB(final EntityInfo<T> info, final String sql, final boolean onlypk, final SelectColumn selects);
@@ -1532,6 +1535,118 @@ public abstract class DataSqlSource<DBChannel> extends AbstractService implement
return queryColumnMapDB(info, sql, keyColumn);
}
@Override
public <T, K extends Serializable, N extends Number> Map<K, N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn) {
return queryColumnMap(entityClass, funcNodes, groupByColumn, (FilterNode) null);
}
@Override
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn) {
return queryColumnMapAsync(entityClass, funcNodes, groupByColumn, (FilterNode) null);
}
@Override
public <T, K extends Serializable, N extends Number> Map<K, N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterBean bean) {
return queryColumnMap(entityClass, funcNodes, groupByColumn, FilterNodeBean.createFilterNode(bean));
}
@Override
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterBean bean) {
return queryColumnMapAsync(entityClass, funcNodes, groupByColumn, FilterNodeBean.createFilterNode(bean));
}
@Override
public <T, K extends Serializable, N extends Number> Map<K, N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterNode node) {
Map<K[], N[]> map = queryColumnMap(entityClass, funcNodes, Utility.ofArray(groupByColumn), node);
final Map<K, N[]> rs = new LinkedHashMap<>();
map.forEach((keys, values) -> rs.put(keys[0], values));
return rs;
}
@Override
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String groupByColumn, final FilterNode node) {
CompletableFuture<Map<K[], N[]>> future = queryColumnMapAsync(entityClass, funcNodes, Utility.ofArray(groupByColumn), node);
return future.thenApply(map -> {
final Map<K, N[]> rs = new LinkedHashMap<>();
map.forEach((keys, values) -> rs.put(keys[0], values));
return rs;
});
}
@Override
public <T, K extends Serializable, N extends Number> Map<K[], N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns) {
return queryColumnMap(entityClass, funcNodes, groupByColumns, (FilterNode) null);
}
@Override
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns) {
return queryColumnMapAsync(entityClass, funcNodes, groupByColumns, (FilterNode) null);
}
@Override
public <T, K extends Serializable, N extends Number> Map<K[], N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterBean bean) {
return queryColumnMap(entityClass, funcNodes, groupByColumns, FilterNodeBean.createFilterNode(bean));
}
@Override
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterBean bean) {
return queryColumnMapAsync(entityClass, funcNodes, groupByColumns, FilterNodeBean.createFilterNode(bean));
}
@Override
public <T, K extends Serializable, N extends Number> Map<K[], N[]> queryColumnMap(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterNode node) {
final EntityInfo info = loadEntityInfo(entityClass);
final EntityCache cache = info.getCache();
if (cache != null && (isOnlyCache(info) || cache.isFullLoaded())) {
if (node == null || node.isCacheUseable(this)) {
return cache.queryColumnMap(funcNodes, groupByColumns, node);
}
}
return (Map) queryColumnMapCompose(info, funcNodes, groupByColumns, node).join();
}
@Override
public <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapAsync(final Class<T> entityClass, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterNode node) {
final EntityInfo info = loadEntityInfo(entityClass);
final EntityCache cache = info.getCache();
if (cache != null && (isOnlyCache(info) || cache.isFullLoaded())) {
if (node == null || node.isCacheUseable(this)) {
return CompletableFuture.completedFuture(cache.queryColumnMap(funcNodes, groupByColumns, node));
}
}
if (isAsync()) return queryColumnMapCompose(info, funcNodes, groupByColumns, node);
return CompletableFuture.supplyAsync(() -> (Map) queryColumnMapCompose(info, funcNodes, groupByColumns, node).join(), getExecutor());
}
protected <T, K extends Serializable, N extends Number> CompletableFuture<Map<K[], N[]>> queryColumnMapCompose(final EntityInfo<T> info, final ColumnNode[] funcNodes, final String[] groupByColumns, final FilterNode node) {
final StringBuilder groupBySqlColumns = new StringBuilder();
if (groupByColumns != null && groupByColumns.length > 0) {
for (int i = 0; i < groupByColumns.length; i++) {
if (groupBySqlColumns.length() > 0) groupBySqlColumns.append(", ");
groupBySqlColumns.append(info.getSQLColumn("a", groupByColumns[i]));
}
}
final StringBuilder funcSqlColumns = new StringBuilder();
for (int i = 0; i < funcNodes.length; i++) {
if (funcSqlColumns.length() > 0) funcSqlColumns.append(", ");
if (funcNodes[i] instanceof ColumnFuncNode) {
funcSqlColumns.append(info.formatSQLValue((Attribute) null, "a", (ColumnFuncNode) funcNodes[i], sqlFormatter));
} else {
funcSqlColumns.append(info.formatSQLValue((Attribute) null, "a", (ColumnNodeValue) funcNodes[i], sqlFormatter));
}
}
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
final Set<String> haset = new HashSet<>();
final CharSequence join = node == null ? null : node.createSQLJoin(this, false, joinTabalis, haset, info);
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis);
String sql = "SELECT ";
if (groupBySqlColumns.length() > 0) sql += groupBySqlColumns + ", ";
sql += funcSqlColumns + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
if (groupBySqlColumns.length() > 0) sql += " GROUP BY " + groupBySqlColumns;
if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " querycolumnmap sql=" + sql);
return queryColumnMapDB(info, sql, funcNodes, groupByColumns);
}
//----------------------------- findCompose -----------------------------
/**
* 根据主键获取对象

View File

@@ -310,6 +310,10 @@ public final class EntityCache<T> {
return rs;
}
public Map<Serializable[], Number[]> queryColumnMap(final ColumnNode[] funcNodes, final String[] groupByColumns, FilterNode node) {
throw new UnsupportedOperationException("Not supported yet.");
}
public <V> Number getNumberResult(final FilterFunc func, final Number defResult, final String column, final FilterNode node) {
final Attribute<T, Serializable> attr = column == null ? null : info.getAttribute(column);
final Predicate<T> filter = node == null ? null : node.createPredicate(this);

View File

@@ -974,7 +974,8 @@ public final class EntityInfo<T> {
if (cv == null) return null;
Object val = cv.getValue();
//ColumnNodeValue时 cv.getExpress() == ColumnExpress.MOV 只用于updateColumn
if (val instanceof ColumnNodeValue) return formatSQLValue(attr, (ColumnNodeValue) val, formatter);
if (val instanceof ColumnNodeValue) return formatSQLValue(attr, null, (ColumnNodeValue) val, formatter);
if (val instanceof ColumnFuncNode) return formatSQLValue(attr, null, (ColumnFuncNode) val, formatter);
switch (cv.getExpress()) {
case INC:
return new StringBuilder().append(sqlColumn).append(" + ").append(val);
@@ -1000,18 +1001,30 @@ public final class EntityInfo<T> {
return formatter == null ? formatToString(val) : formatter.apply(this, val);
}
protected CharSequence formatSQLValue(Attribute<T, Serializable> attr, final ColumnNodeValue node, BiFunction<EntityInfo, Object, CharSequence> formatter) {
protected CharSequence formatSQLValue(Attribute<T, Serializable> attr, String tabalis, final ColumnFuncNode node, BiFunction<EntityInfo, Object, CharSequence> formatter) {
if (node.getValue() instanceof ColumnNodeValue) {
return node.getFunc().getColumn(formatSQLValue(attr, tabalis, (ColumnNodeValue) node.getValue(), formatter).toString());
} else {
return node.getFunc().getColumn(this.getSQLColumn(tabalis, String.valueOf(node.getValue())));
}
}
protected CharSequence formatSQLValue(Attribute<T, Serializable> attr, String tabalis, final ColumnNodeValue node, BiFunction<EntityInfo, Object, CharSequence> formatter) {
Serializable left = node.getLeft();
if (left instanceof CharSequence) {
left = this.getSQLColumn(null, left.toString());
left = this.getSQLColumn(tabalis, left.toString());
} else if (left instanceof ColumnNodeValue) {
left = "(" + formatSQLValue(attr, (ColumnNodeValue) left, formatter) + ")";
left = "(" + formatSQLValue(attr, tabalis, (ColumnNodeValue) left, formatter) + ")";
} else if (left instanceof ColumnFuncNode) {
left = "(" + formatSQLValue(attr, tabalis, (ColumnFuncNode) left, formatter) + ")";
}
Serializable right = node.getRight();
if (right instanceof CharSequence) {
right = this.getSQLColumn(null, right.toString());
} else if (left instanceof ColumnNodeValue) {
right = "(" + formatSQLValue(attr, (ColumnNodeValue) right, formatter) + ")";
right = "(" + formatSQLValue(attr, tabalis, (ColumnNodeValue) right, formatter) + ")";
} else if (left instanceof ColumnFuncNode) {
right = "(" + formatSQLValue(attr, tabalis, (ColumnFuncNode) right, formatter) + ")";
}
switch (node.getExpress()) {
case INC: