diff --git a/src/org/redkale/source/DataJdbcSource.java b/src/org/redkale/source/DataJdbcSource.java index a88649914..65fd23f20 100644 --- a/src/org/redkale/source/DataJdbcSource.java +++ b/src/org/redkale/source/DataJdbcSource.java @@ -495,7 +495,7 @@ public class DataJdbcSource extends DataSqlSource { } @Override - protected CompletableFuture> querySheetDB(EntityInfo info, final boolean readcache, boolean needtotal, SelectColumn selects, Flipper flipper, FilterNode node) { + protected CompletableFuture> querySheetDB(EntityInfo info, final boolean readcache, boolean needtotal, final boolean distinct, SelectColumn selects, Flipper flipper, FilterNode node) { Connection conn = null; try { conn = readPool.poll(); @@ -507,7 +507,7 @@ public class DataJdbcSource extends DataSqlSource { final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis); final String dbtype = this.readPool.getDbtype(); if ("mysql".equals(dbtype) || "postgresql".equals(dbtype)) { - final String listsql = "SELECT " + info.getQueryColumns("a", selects) + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + final String listsql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getQueryColumns("a", selects) + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + createSQLOrderby(info, flipper) + (flipper == null || flipper.getLimit() < 1 ? "" : (" LIMIT " + flipper.getLimit() + " OFFSET " + flipper.getOffset())); if (readcache && info.isLoggable(logger, Level.FINEST, listsql)) { logger.finest(info.getType().getSimpleName() + " query sql=" + listsql); @@ -521,7 +521,7 @@ public class DataJdbcSource extends DataSqlSource { ps.close(); long total = list.size(); if (needtotal) { - final String countsql = "SELECT COUNT(*) FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); + final String countsql = "SELECT " + (distinct ? "DISTINCT COUNT(" + info.getQueryColumns("a", selects) + ")" : "COUNT(*)") + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); if (readcache && info.isLoggable(logger, Level.FINEST, countsql)) { logger.finest(info.getType().getSimpleName() + " query countsql=" + countsql); } @@ -533,7 +533,7 @@ public class DataJdbcSource extends DataSqlSource { } return CompletableFuture.completedFuture(new Sheet<>(total, list)); } - final String sql = "SELECT " + info.getQueryColumns("a", selects) + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + final String sql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getQueryColumns("a", selects) + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + info.createSQLOrderby(flipper); if (readcache && info.isLoggable(logger, Level.FINEST, sql)) { logger.finest(info.getType().getSimpleName() + " query sql=" + sql + (flipper == null || flipper.getLimit() < 1 ? "" : (" LIMIT " + flipper.getLimit() + " OFFSET " + flipper.getOffset()))); diff --git a/src/org/redkale/source/DataMemorySource.java b/src/org/redkale/source/DataMemorySource.java index a9e567655..13ebf2723 100644 --- a/src/org/redkale/source/DataMemorySource.java +++ b/src/org/redkale/source/DataMemorySource.java @@ -144,7 +144,7 @@ public class DataMemorySource extends DataSqlSource { } @Override - protected CompletableFuture> querySheetDB(EntityInfo info, final boolean readcache, boolean needtotal, SelectColumn selects, Flipper flipper, FilterNode node) { + protected CompletableFuture> querySheetDB(EntityInfo info, final boolean readcache, boolean needtotal, final boolean distinct, SelectColumn selects, Flipper flipper, FilterNode node) { return CompletableFuture.completedFuture(new Sheet<>()); } diff --git a/src/org/redkale/source/DataSource.java b/src/org/redkale/source/DataSource.java index df2805398..8a02d4153 100644 --- a/src/org/redkale/source/DataSource.java +++ b/src/org/redkale/source/DataSource.java @@ -1429,9 +1429,10 @@ public interface DataSource { public CompletableFuture existsAsync(final Class clazz, final FilterNode node); //-----------------------list set---------------------------- + /** * 查询符合过滤条件记录的某个字段Set集合
- * 等价SQL: SELECT {selectedColumn} FROM {table} WHERE {column} = {key}
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {column} = {key}
* * @param Entity泛型 * @param 字段类型 @@ -1442,11 +1443,11 @@ public interface DataSource { * * @return 字段值的集合 */ - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final String column, final Serializable colval); + public Set queryColumnSet(final String selectedColumn, final Class clazz, final String column, final Serializable colval); /** * 查询符合过滤条件记录的某个字段Set集合
- * 等价SQL: SELECT {selectedColumn} FROM {table} WHERE {column} = {key}
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {column} = {key}
* * @param Entity泛型 * @param 字段类型 @@ -1457,11 +1458,11 @@ public interface DataSource { * * @return 字段值的集合CompletableFuture */ - public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final String column, final Serializable colval); + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final String column, final Serializable colval); /** * 查询符合过滤条件记录的某个字段Set集合
- * 等价SQL: SELECT {selectedColumn} FROM {table} WHERE {filter bean}
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter bean}
* * @param Entity泛型 * @param 字段类型 @@ -1471,11 +1472,11 @@ public interface DataSource { * * @return 字段值的集合 */ - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final FilterBean bean); + public Set queryColumnSet(final String selectedColumn, final Class clazz, final FilterBean bean); /** * 查询符合过滤条件记录的某个字段Set集合
- * 等价SQL: SELECT {selectedColumn} FROM {table} WHERE {filter bean}
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter bean}
* * @param Entity泛型 * @param 字段类型 @@ -1485,11 +1486,11 @@ public interface DataSource { * * @return 字段值的集合CompletableFuture */ - public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterBean bean); + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterBean bean); /** * 查询符合过滤条件记录的某个字段Set集合
- * 等价SQL: SELECT {selectedColumn} FROM {table} WHERE {filter node}
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter node}
* * @param Entity泛型 * @param 字段类型 @@ -1499,11 +1500,11 @@ public interface DataSource { * * @return 字段值的集合 */ - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final FilterNode node); + public Set queryColumnSet(final String selectedColumn, final Class clazz, final FilterNode node); /** * 查询符合过滤条件记录的某个字段Set集合
- * 等价SQL: SELECT {selectedColumn} FROM {table} WHERE {filter node}
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter node}
* * @param Entity泛型 * @param 字段类型 @@ -1513,7 +1514,67 @@ public interface DataSource { * * @return 字段值的集合CompletableFuture */ - public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterNode node); + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterNode node); + + /** + * 查询符合过滤条件记录的某个字段Set集合
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter bean} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param 字段类型 + * @param selectedColumn 指定字段 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param bean 过滤条件 + * + * @return 字段值的集合 + */ + public Set queryColumnSet(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean); + + /** + * 查询符合过滤条件记录的某个字段Set集合
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter bean} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param 字段类型 + * @param selectedColumn 指定字段 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param bean 过滤条件 + * + * @return 字段值的集合CompletableFuture + */ + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean); + + /** + * 查询符合过滤条件记录的某个字段Set集合
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter node} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param 字段类型 + * @param selectedColumn 指定字段 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param node 过滤条件 + * + * @return 字段值的集合 + */ + public Set queryColumnSet(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node); + + /** + * 查询符合过滤条件记录的某个字段Set集合
+ * 等价SQL: SELECT DISTINCT {selectedColumn} FROM {table} WHERE {filter node} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param 字段类型 + * @param selectedColumn 指定字段 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param node 过滤条件 + * + * @return 字段值的集合CompletableFuture + */ + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node); /** * 查询符合过滤条件记录的某个字段List集合
@@ -1883,6 +1944,296 @@ public interface DataSource { */ public CompletableFuture> queryMapAsync(final Class clazz, final SelectColumn selects, final FilterNode node); + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {column} = {key} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param column 过滤字段名 + * @param colval 过滤字段值 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final String column, final Serializable colval); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {column} = {key} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param column 过滤字段名 + * @param colval 过滤字段值 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final String column, final Serializable colval); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter bean}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param bean 过滤条件 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final FilterBean bean); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter bean}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param bean 过滤条件 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final FilterBean bean); + + /** + * 查询记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * + * @return Entity的集合 + */ + default Set querySet(final Class clazz) { + return querySet(clazz, (FilterNode) null); + } + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter node}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param node 过滤条件 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final FilterNode node); + + /** + * 查询记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * + * @return Entity的集合CompletableFuture + */ + default CompletableFuture> querySetAsync(final Class clazz) { + return querySetAsync(clazz, (FilterNode) null); + } + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter node}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param node 过滤条件 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final FilterNode node); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter bean}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param bean 过滤条件 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final SelectColumn selects, final FilterBean bean); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter bean}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param bean 过滤条件 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final SelectColumn selects, final FilterBean bean); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter node}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param node 过滤条件 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final SelectColumn selects, final FilterNode node); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter node}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param node 过滤条件 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final SelectColumn selects, final FilterNode node); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {column} = {key} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param column 过滤字段名 + * @param colval 过滤字段值 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final Flipper flipper, final String column, final Serializable colval); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {column} = {key} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param column 过滤字段名 + * @param colval 过滤字段值 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final Flipper flipper, final String column, final Serializable colval); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter bean} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param bean 过滤条件 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final Flipper flipper, final FilterBean bean); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter bean} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param bean 过滤条件 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final Flipper flipper, final FilterBean bean); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter node} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param node 过滤条件 + * + * @return Entity的集合 + * + */ + public Set querySet(final Class clazz, final Flipper flipper, final FilterNode node); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT * FROM {table} WHERE {filter node} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param flipper 翻页对象 + * @param node 过滤条件 + * + * @return Entity的集合 + * + */ + public CompletableFuture> querySetAsync(final Class clazz, final Flipper flipper, final FilterNode node); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter bean} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param flipper 翻页对象 + * @param bean 过滤条件 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter bean} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param flipper 翻页对象 + * @param bean 过滤条件 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter node} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param flipper 翻页对象 + * @param node 过滤条件 + * + * @return Entity的集合 + */ + public Set querySet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node); + + /** + * 查询符合过滤条件记录的Set集合
+ * 等价SQL: SELECT DISTINCT {column1},{column2}, ··· FROM {table} WHERE {filter node} ORDER BY {flipper.sort} LIMIT {flipper.limit}
+ * + * @param Entity泛型 + * @param clazz Entity类 + * @param selects 指定字段 + * @param flipper 翻页对象 + * @param node 过滤条件 + * + * @return Entity的集合CompletableFuture + */ + public CompletableFuture> querySetAsync(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node); + /** * 查询符合过滤条件记录的List集合
* 等价SQL: SELECT * FROM {table} WHERE {column} = {key} ORDER BY {flipper.sort} LIMIT {flipper.limit}
diff --git a/src/org/redkale/source/DataSqlSource.java b/src/org/redkale/source/DataSqlSource.java index 2d35fd362..1c807acb3 100644 --- a/src/org/redkale/source/DataSqlSource.java +++ b/src/org/redkale/source/DataSqlSource.java @@ -65,7 +65,7 @@ public abstract class DataSqlSource extends AbstractService implement if (t != null) logger.log(Level.SEVERE, "CompletableFuture complete error", (Throwable) t); }; - protected final BiFunction fullloader = (s, t) -> ((Sheet) querySheetCompose(false, false, t, null, null, (FilterNode) null).join()).list(true); + protected final BiFunction fullloader = (s, t) -> ((Sheet) querySheetCompose(false, false, false, t, null, null, (FilterNode) null).join()).list(true); @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"}) public DataSqlSource(String unitName, URL persistxml, Properties readprop, Properties writeprop) { @@ -91,7 +91,7 @@ public abstract class DataSqlSource extends AbstractService implement } else if (s.length() == 2) { s = "0" + s; } - t.setName("Redkale-"+cname + "-Thread-" + s); + t.setName("Redkale-" + cname + "-Thread-" + s); t.setUncaughtExceptionHandler(ueh); return t; }); @@ -167,7 +167,7 @@ public abstract class DataSqlSource extends AbstractService implement protected abstract CompletableFuture existsDB(final EntityInfo info, final String sql, final boolean onlypk); //查询一页数据 - protected abstract CompletableFuture> querySheetDB(final EntityInfo info, final boolean readcache, final boolean needtotal, final SelectColumn selects, final Flipper flipper, final FilterNode node); + protected abstract CompletableFuture> querySheetDB(final EntityInfo info, final boolean readcache, final boolean needtotal, final boolean distinct, final SelectColumn selects, final Flipper flipper, final FilterNode node); protected T getEntityValue(EntityInfo info, final SelectColumn sels, final ResultSet set) throws SQLException { return info.getEntityValue(sels, set); @@ -1279,7 +1279,7 @@ public abstract class DataSqlSource extends AbstractService implement String column = info.getPrimary().field(); int c = 0; for (Serializable id : pks) { - Sheet sheet = querySheetCompose(false, true, clazz, null, FLIPPER_ONE, FilterNode.create(column, id)).join(); + Sheet sheet = querySheetCompose(false, true, false, clazz, null, FLIPPER_ONE, FilterNode.create(column, id)).join(); T value = sheet.isEmpty() ? null : sheet.list().get(0); if (value != null) c += cache.update(value); } @@ -1800,36 +1800,74 @@ public abstract class DataSqlSource extends AbstractService implement } //-----------------------list set---------------------------- + @Override - public HashSet queryColumnSet(final String selectedColumn, Class clazz, String column, Serializable colval) { - return new LinkedHashSet<>(queryColumnList(selectedColumn, clazz, null, FilterNode.create(column, colval))); + public Set queryColumnSet(final String selectedColumn, final Class clazz, final String column, final Serializable colval) { + return queryColumnSet(selectedColumn, clazz, null, FilterNode.create(column, colval)); } @Override - public CompletableFuture> queryColumnSetAsync(final String selectedColumn, Class clazz, String column, Serializable colval) { - return queryColumnListAsync(selectedColumn, clazz, null, FilterNode.create(column, colval)).thenApply((list) -> new LinkedHashSet(list)); + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final String column, final Serializable colval) { + return queryColumnSetAsync(selectedColumn, clazz, null, FilterNode.create(column, colval)); } @Override - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final FilterBean bean) { - return new LinkedHashSet<>(queryColumnList(selectedColumn, clazz, null, FilterNodeBean.createFilterNode(bean))); + public Set queryColumnSet(final String selectedColumn, final Class clazz, final FilterBean bean) { + return queryColumnSet(selectedColumn, clazz, null, FilterNodeBean.createFilterNode(bean)); } @Override - public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterBean bean) { - return queryColumnListAsync(selectedColumn, clazz, null, FilterNodeBean.createFilterNode(bean)).thenApply((list) -> new LinkedHashSet(list)); + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterBean bean) { + return queryColumnSetAsync(selectedColumn, clazz, null, FilterNodeBean.createFilterNode(bean)); } @Override - public HashSet queryColumnSet(String selectedColumn, Class clazz, FilterNode node) { - return new LinkedHashSet<>(queryColumnList(selectedColumn, clazz, null, node)); + public Set queryColumnSet(final String selectedColumn, final Class clazz, final FilterNode node) { + return queryColumnSet(selectedColumn, clazz, null, node); } @Override - public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterNode node) { - return queryColumnListAsync(selectedColumn, clazz, null, node).thenApply((list) -> new LinkedHashSet(list)); + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final FilterNode node) { + return queryColumnSetAsync(selectedColumn, clazz, null, node); } + @Override + public Set queryColumnSet(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean) { + return queryColumnSet(selectedColumn, clazz, flipper, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean) { + return queryColumnSetAsync(selectedColumn, clazz, flipper, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public Set queryColumnSet(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node) { + final Set list = querySet(clazz, SelectColumn.includes(selectedColumn), flipper, node); + final Set rs = new LinkedHashSet<>(); + if (list.isEmpty()) return rs; + final EntityInfo info = loadEntityInfo(clazz); + final Attribute selected = (Attribute) info.getAttribute(selectedColumn); + for (T t : list) { + rs.add(selected.get(t)); + } + return rs; + } + + @Override + public CompletableFuture> queryColumnSetAsync(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node) { + return querySetAsync(clazz, SelectColumn.includes(selectedColumn), flipper, node).thenApply((Set list) -> { + final Set rs = new LinkedHashSet<>(); + if (list.isEmpty()) return rs; + final EntityInfo info = loadEntityInfo(clazz); + final Attribute selected = (Attribute) info.getAttribute(selectedColumn); + for (T t : list) { + rs.add(selected.get(t)); + } + return rs; + }); + } + @Override public List queryColumnList(final String selectedColumn, final Class clazz, final String column, final Serializable colval) { return queryColumnList(selectedColumn, clazz, null, FilterNode.create(column, colval)); @@ -2121,6 +2159,145 @@ public abstract class DataSqlSource extends AbstractService implement }); } + /** + * 根据指定字段值查询对象集合 + * + * @param Entity类的泛型 + * @param clazz Entity类 + * @param column 过滤字段名 + * @param colval 过滤字段值 + * + * @return Entity对象的集合 + */ + @Override + public Set querySet(final Class clazz, final String column, final Serializable colval) { + return querySet(clazz, (SelectColumn) null, null, FilterNode.create(column, colval)); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final String column, final Serializable colval) { + return querySetAsync(clazz, (SelectColumn) null, null, FilterNode.create(column, colval)); + } + + @Override + public Set querySet(final Class clazz) { + return querySet(clazz, (SelectColumn) null, null, (FilterNode) null); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz) { + return querySetAsync(clazz, (SelectColumn) null, null, (FilterNode) null); + } + + /** + * 根据过滤对象FilterBean查询对象集合 + * + * @param Entity类的泛型 + * @param clazz Entity类 + * @param bean 过滤Bean + * + * @return Entity对象集合 + */ + @Override + public Set querySet(final Class clazz, final FilterBean bean) { + return querySet(clazz, (SelectColumn) null, null, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final FilterBean bean) { + return querySetAsync(clazz, (SelectColumn) null, null, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public Set querySet(final Class clazz, final FilterNode node) { + return querySet(clazz, (SelectColumn) null, null, node); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final FilterNode node) { + return querySetAsync(clazz, (SelectColumn) null, null, node); + } + + /** + * 根据过滤对象FilterBean查询对象集合, 对象只填充或排除SelectField指定的字段 + * + * @param Entity类的泛型 + * @param clazz Entity类 + * @param selects 收集的字段 + * @param bean 过滤Bean + * + * @return Entity对象的集合 + */ + @Override + public Set querySet(final Class clazz, final SelectColumn selects, final FilterBean bean) { + return querySet(clazz, selects, null, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, SelectColumn selects, final FilterBean bean) { + return querySetAsync(clazz, selects, null, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public Set querySet(final Class clazz, final SelectColumn selects, final FilterNode node) { + return querySet(clazz, selects, null, node); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, SelectColumn selects, final FilterNode node) { + return querySetAsync(clazz, selects, null, node); + } + + @Override + public Set querySet(final Class clazz, final Flipper flipper, final String column, final Serializable colval) { + return querySet(clazz, null, flipper, FilterNode.create(column, colval)); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final Flipper flipper, final String column, final Serializable colval) { + return querySetAsync(clazz, null, flipper, FilterNode.create(column, colval)); + } + + @Override + public Set querySet(final Class clazz, final Flipper flipper, final FilterBean bean) { + return querySet(clazz, null, flipper, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final Flipper flipper, final FilterBean bean) { + return querySetAsync(clazz, null, flipper, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public Set querySet(final Class clazz, final Flipper flipper, final FilterNode node) { + return querySet(clazz, null, flipper, node); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final Flipper flipper, final FilterNode node) { + return querySetAsync(clazz, null, flipper, node); + } + + @Override + public Set querySet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { + return querySet(clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { + return querySetAsync(clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)); + } + + @Override + public Set querySet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { + return new LinkedHashSet<>(querySheetCompose(true, false, true, clazz, selects, flipper, node).join().list(true)); + } + + @Override + public CompletableFuture> querySetAsync(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { + return querySheetCompose(true, false, true, clazz, selects, flipper, node).thenApply((rs) -> new LinkedHashSet<>(rs.list(true))); + } + /** * 根据指定字段值查询对象集合 * @@ -2252,12 +2429,12 @@ public abstract class DataSqlSource extends AbstractService implement @Override public List queryList(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return querySheetCompose(true, false, clazz, selects, flipper, node).join().list(true); + return querySheetCompose(true, false, false, clazz, selects, flipper, node).join().list(true); } @Override public CompletableFuture> queryListAsync(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return querySheetCompose(true, false, clazz, selects, flipper, node).thenApply((rs) -> rs.list(true)); + return querySheetCompose(true, false, false, clazz, selects, flipper, node).thenApply((rs) -> rs.list(true)); } //-----------------------sheet---------------------------- @@ -2314,24 +2491,24 @@ public abstract class DataSqlSource extends AbstractService implement @Override public Sheet querySheet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return querySheetCompose(true, true, clazz, selects, flipper, node).join(); + return querySheetCompose(true, true, false, clazz, selects, flipper, node).join(); } @Override public CompletableFuture> querySheetAsync(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - if (isAsync()) return querySheetCompose(true, true, clazz, selects, flipper, node); - return CompletableFuture.supplyAsync(() -> querySheetCompose(true, true, clazz, selects, flipper, node).join(), getExecutor()); + if (isAsync()) return querySheetCompose(true, true, false, clazz, selects, flipper, node); + return CompletableFuture.supplyAsync(() -> querySheetCompose(true, true, false, clazz, selects, flipper, node).join(), getExecutor()); } - protected CompletableFuture> querySheetCompose(final boolean readcache, final boolean needtotal, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { + protected CompletableFuture> querySheetCompose(final boolean readcache, final boolean needtotal, final boolean distinct, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { final EntityInfo info = loadEntityInfo(clazz); final EntityCache cache = info.getCache(); if (readcache && cache != null && cache.isFullLoaded()) { if (node == null || node.isCacheUseable(this)) { if (info.isLoggable(logger, Level.FINEST, " cache query predicate = ")) logger.finest(clazz.getSimpleName() + " cache query predicate = " + (node == null ? null : node.createPredicate(cache))); - return CompletableFuture.completedFuture(cache.querySheet(needtotal, selects, flipper, node)); + return CompletableFuture.completedFuture(cache.querySheet(needtotal, distinct, selects, flipper, node)); } } - return querySheetDB(info, readcache, needtotal, selects, flipper, node); + return querySheetDB(info, readcache, needtotal, distinct, selects, flipper, node); } } diff --git a/src/org/redkale/source/EntityCache.java b/src/org/redkale/source/EntityCache.java index 1e7f7c4fd..e5e275b92 100644 --- a/src/org/redkale/source/EntityCache.java +++ b/src/org/redkale/source/EntityCache.java @@ -395,21 +395,47 @@ public final class EntityCache { } public Sheet querySheet(final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return querySheet(true, selects, flipper, node); + return querySheet(true, false, selects, flipper, node); } - public Sheet querySheet(final boolean needtotal, final SelectColumn selects, final Flipper flipper, FilterNode node) { + protected Stream distinctStream(Stream stream, final List> keyattrs) { + if (keyattrs == null) return stream; + final Set keys = new HashSet<>(); + Predicate filter = t -> { + StringBuilder sb = new StringBuilder(); + for (Attribute attr : keyattrs) { + sb.append(attr.get(t)); + } + String key = sb.toString(); + if (keys.contains(key)) return false; + keys.add(key); + return true; + }; + return stream.filter(filter); + } + + public Sheet querySheet(final boolean needtotal, final boolean distinct, final SelectColumn selects, final Flipper flipper, FilterNode node) { final Predicate filter = node == null ? null : node.createPredicate(this); final Comparator comparator = createComparator(flipper); long total = 0; + List> keyattrs = null; + if (distinct) { + final List> attrs = new ArrayList<>(); + info.forEachAttribute((k, v) -> { + if (selects == null || selects.test(k)) attrs.add(v); + }); + keyattrs = attrs; + } if (needtotal) { Stream stream = this.list.stream(); if (filter != null) stream = stream.filter(filter); + if (distinct) stream = distinctStream(stream, keyattrs); total = stream.count(); } if (needtotal && total == 0) return new Sheet<>(); Stream stream = this.list.stream(); if (filter != null) stream = stream.filter(filter); + if (distinct) stream = distinctStream(stream, keyattrs); if (comparator != null) stream = stream.sorted(comparator); if (flipper != null && flipper.getOffset() > 0) stream = stream.skip(flipper.getOffset()); if (flipper != null && flipper.getLimit() > 0) stream = stream.limit(flipper.getLimit());