增加nativeQuerySheet方法
This commit is contained in:
@@ -648,7 +648,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
|
||||
if (nativeSqlParser == null) {
|
||||
throw new SourceException("not found DataNativeSqlParser instance");
|
||||
}
|
||||
return nativeSqlParser.parse(signFunc, nativeSql, params == null ? Collections.emptyMap() : params);
|
||||
return nativeSqlParser.parse(signFunc, dbtype(), nativeSql, params == null ? Collections.emptyMap() : params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3243,6 +3243,11 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
|
||||
return nativeQueryAsync(sql, consumer, handler).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper, Map<String, Object> params) {
|
||||
return nativeQuerySheetAsync(type, sql, flipper, params).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nativeUpdate(String sql, Map<String, Object> params) {
|
||||
return nativeUpdateAsync(sql, params).join();
|
||||
|
||||
@@ -2328,16 +2328,10 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
private <T> Sheet<T> executeQuerySheet(EntityInfo<T> info, boolean needTotal, Flipper flipper, SelectColumn sels,
|
||||
long s, SourceConnection conn, boolean mysqlOrPgsql, String listSql, String countSql) throws SQLException {
|
||||
final List<T> list = new ArrayList();
|
||||
if (mysqlOrPgsql) { //sql可以带limit、offset
|
||||
PreparedStatement prestmt = conn.prepareQueryStatement(listSql);
|
||||
ResultSet set = prestmt.executeQuery();
|
||||
final DataResultSet rr = createDataResultSet(info, set);
|
||||
while (set.next()) {
|
||||
list.add(getEntityValue(info, sels, rr));
|
||||
}
|
||||
set.close();
|
||||
conn.offerQueryStatement(prestmt);
|
||||
long total = list.size();
|
||||
if (mysqlOrPgsql) { //sql可以带limit、offset
|
||||
ResultSet set;
|
||||
PreparedStatement prestmt;
|
||||
long total = -1;
|
||||
if (needTotal) {
|
||||
prestmt = conn.prepareQueryStatement(countSql);
|
||||
set = prestmt.executeQuery();
|
||||
@@ -2347,6 +2341,19 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
set.close();
|
||||
conn.offerQueryStatement(prestmt);
|
||||
}
|
||||
if (total != 0) {
|
||||
prestmt = conn.prepareQueryStatement(listSql);
|
||||
set = prestmt.executeQuery();
|
||||
final DataResultSet rr = createDataResultSet(info, set);
|
||||
while (set.next()) {
|
||||
list.add(getEntityValue(info, sels, rr));
|
||||
}
|
||||
set.close();
|
||||
conn.offerQueryStatement(prestmt);
|
||||
if (!needTotal) {
|
||||
total = list.size();
|
||||
}
|
||||
}
|
||||
slowLog(s, listSql);
|
||||
return new Sheet<>(total, list);
|
||||
} else {
|
||||
@@ -2548,10 +2555,10 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
int rs;
|
||||
if (sinfo.isEmptyNamed()) {
|
||||
final Statement stmt = conn.createUpdateStatement();
|
||||
rs = stmt.executeUpdate(sinfo.nativeSql);
|
||||
rs = stmt.executeUpdate(sinfo.getNativeSql());
|
||||
conn.offerUpdateStatement(stmt);
|
||||
} else {
|
||||
final PreparedStatement prestmt = conn.prepareQueryStatement(sinfo.nativeSql);
|
||||
final PreparedStatement prestmt = conn.prepareQueryStatement(sinfo.getNativeSql());
|
||||
Map<String, Object> paramValues = sinfo.getParamValues();
|
||||
int index = 0;
|
||||
for (String n : sinfo.getParamNames()) {
|
||||
@@ -2622,7 +2629,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
final SourceConnection conn = readPool.pollConnection();
|
||||
try {
|
||||
if (logger.isLoggable(Level.FINEST)) {
|
||||
logger.finest("executeQuery sql=" + sinfo.nativeSql);
|
||||
logger.finest("executeQuery sql=" + sinfo.getNativeSql());
|
||||
}
|
||||
V rs;
|
||||
if (sinfo.isEmptyNamed()) {
|
||||
@@ -2630,12 +2637,12 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
if (consumer != null) {
|
||||
consumer.accept(conn, stmt);
|
||||
}
|
||||
ResultSet set = stmt.executeQuery(sql);
|
||||
ResultSet set = stmt.executeQuery(sinfo.getNativeSql());
|
||||
rs = handler.apply(createDataResultSet(null, set));
|
||||
set.close();
|
||||
conn.offerQueryStatement(stmt);
|
||||
} else {
|
||||
final PreparedStatement prestmt = conn.prepareQueryStatement(sinfo.nativeSql);
|
||||
final PreparedStatement prestmt = conn.prepareQueryStatement(sinfo.getNativeSql());
|
||||
Map<String, Object> paramValues = sinfo.getParamValues();
|
||||
int index = 0;
|
||||
for (String n : sinfo.getParamNames()) {
|
||||
@@ -2644,12 +2651,12 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
if (consumer != null) {
|
||||
consumer.accept(conn, prestmt);
|
||||
}
|
||||
ResultSet set = prestmt.executeQuery(sql);
|
||||
ResultSet set = prestmt.executeQuery();
|
||||
rs = handler.apply(createDataResultSet(null, set));
|
||||
set.close();
|
||||
conn.offerQueryStatement(prestmt);
|
||||
}
|
||||
slowLog(s, sql);
|
||||
slowLog(s, sinfo.getNativeSql());
|
||||
return rs;
|
||||
} catch (Exception ex) {
|
||||
throw new SourceException(ex);
|
||||
@@ -2660,6 +2667,77 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
}
|
||||
}
|
||||
|
||||
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper, Map<String, Object> params) {
|
||||
final boolean mysqlOrPgsql = "mysql".equals(dbtype()) || "postgresql".equals(dbtype());
|
||||
NativeSqlStatement sinfo = super.nativeParse(sql, params);
|
||||
final long s = System.currentTimeMillis();
|
||||
final SourceConnection conn = readPool.pollConnection();
|
||||
try {
|
||||
if (logger.isLoggable(Level.FINEST)) {
|
||||
logger.finest("executeQuery sql=" + sinfo.nativeSql);
|
||||
}
|
||||
long total = -1;
|
||||
List<V> list;
|
||||
if (sinfo.isEmptyNamed()) {
|
||||
Statement stmt = conn.createQueryStatement();
|
||||
ResultSet set = stmt.executeQuery(sinfo.getNativeCountSql());
|
||||
if (set.next()) {
|
||||
total = set.getLong(1);
|
||||
};
|
||||
set.close();
|
||||
conn.offerQueryStatement(stmt);
|
||||
} else {
|
||||
final PreparedStatement prestmt = conn.prepareQueryStatement(sinfo.getNativeCountSql());
|
||||
Map<String, Object> paramValues = sinfo.getParamValues();
|
||||
int index = 0;
|
||||
for (String n : sinfo.getParamNames()) {
|
||||
prestmt.setObject(++index, paramValues.get(n));
|
||||
}
|
||||
ResultSet set = prestmt.executeQuery();
|
||||
if (set.next()) {
|
||||
total = set.getLong(1);
|
||||
};
|
||||
set.close();
|
||||
conn.offerQueryStatement(prestmt);
|
||||
}
|
||||
slowLog(s, sinfo.getNativeCountSql());
|
||||
if (total > 0) {
|
||||
String listSql = sinfo.getNativeSql();
|
||||
if (mysqlOrPgsql) {
|
||||
listSql += (flipper == null || flipper.getLimit() < 1 ? "" : (" LIMIT " + flipper.getLimit() + " OFFSET " + flipper.getOffset()));
|
||||
}
|
||||
if (sinfo.isEmptyNamed()) {
|
||||
Statement stmt = conn.createQueryStatement();
|
||||
ResultSet set = stmt.executeQuery(listSql);
|
||||
list = EntityBuilder.getListValue(type, createDataResultSet(null, set));
|
||||
set.close();
|
||||
conn.offerQueryStatement(stmt);
|
||||
} else {
|
||||
final PreparedStatement prestmt = conn.prepareQueryStatement(listSql);
|
||||
Map<String, Object> paramValues = sinfo.getParamValues();
|
||||
int index = 0;
|
||||
for (String n : sinfo.getParamNames()) {
|
||||
prestmt.setObject(++index, paramValues.get(n));
|
||||
}
|
||||
ResultSet set = prestmt.executeQuery();
|
||||
list = EntityBuilder.getListValue(type, createDataResultSet(null, set));
|
||||
set.close();
|
||||
conn.offerQueryStatement(prestmt);
|
||||
}
|
||||
slowLog(s, listSql);
|
||||
} else {
|
||||
list = new ArrayList();
|
||||
}
|
||||
return new Sheet<>(total, list);
|
||||
} catch (Exception ex) {
|
||||
throw new SourceException(ex);
|
||||
} finally {
|
||||
if (conn != null) {
|
||||
readPool.offerConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> CompletableFuture<V> nativeQueryAsync(String sql, BiConsumer<Object, Object> consumer, Function<DataResultSet, V> handler, Map<String, Object> params) {
|
||||
return supplyAsync(() -> nativeQuery(sql, consumer, handler, params));
|
||||
@@ -2685,6 +2763,11 @@ public class DataJdbcSource extends AbstractDataSqlSource {
|
||||
return supplyAsync(() -> nativeUpdates(sqls));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> CompletableFuture<Sheet<V>> nativeQuerySheetAsync(Class<V> type, String sql, Flipper flipper, Map<String, Object> params) {
|
||||
return supplyAsync(() -> nativeQuerySheet(type, sql, flipper, params));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int directExecute(String sql) {
|
||||
return nativeUpdate(sql);
|
||||
|
||||
@@ -20,13 +20,16 @@ import org.redkale.convert.json.JsonConvert;
|
||||
*/
|
||||
public interface DataNativeSqlParser {
|
||||
|
||||
NativeSqlStatement parse(Function<Integer, String> signFunc, String nativeSql, Map<String, Object> params);
|
||||
NativeSqlStatement parse(Function<Integer, String> signFunc, String dbtype, String nativeSql, Map<String, Object> params);
|
||||
|
||||
public static class NativeSqlStatement {
|
||||
|
||||
//根据参数值集合重新生成的带?参数可执行的sql
|
||||
protected String nativeSql;
|
||||
|
||||
//根据参数值集合重新生成的带?参数可执行的计算总数sql,用于返回Sheet对象
|
||||
protected String nativeCountSql;
|
||||
|
||||
//是否包含InExpression参数名
|
||||
protected boolean existInNamed;
|
||||
|
||||
@@ -54,6 +57,14 @@ public interface DataNativeSqlParser {
|
||||
this.nativeSql = nativeSql;
|
||||
}
|
||||
|
||||
public String getNativeCountSql() {
|
||||
return nativeCountSql;
|
||||
}
|
||||
|
||||
public void setNativeCountSql(String nativeCountSql) {
|
||||
this.nativeCountSql = nativeCountSql;
|
||||
}
|
||||
|
||||
public boolean isExistInNamed() {
|
||||
return existInNamed;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.*;
|
||||
import static org.redkale.source.DataResultSet.formatColumnValue;
|
||||
import org.redkale.util.Copier;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -128,6 +128,10 @@ public interface DataSqlSource extends DataSource {
|
||||
*/
|
||||
public <V> CompletableFuture<V> nativeQueryAsync(String sql, BiConsumer<Object, Object> consumer, Function<DataResultSet, V> handler, Map<String, Object> params);
|
||||
|
||||
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper, Map<String, Object> params);
|
||||
|
||||
public <V> CompletableFuture<Sheet<V>> nativeQuerySheetAsync(Class<V> type, String sql, Flipper flipper, Map<String, Object> params);
|
||||
|
||||
//----------------------------- 无参数 -----------------------------
|
||||
default <V> V nativeQuery(String sql, Function<DataResultSet, V> handler) {
|
||||
return nativeQuery(sql, null, handler);
|
||||
@@ -138,57 +142,27 @@ public interface DataSqlSource extends DataSource {
|
||||
}
|
||||
|
||||
default <V> V nativeQueryOne(Class<V> type, String sql) {
|
||||
return nativeQuery(sql, rset -> {
|
||||
if (!rset.next()) {
|
||||
return null;
|
||||
}
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
|| (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) {
|
||||
return (V) formatColumnValue(type, rset.getObject(1));
|
||||
}
|
||||
return EntityBuilder.load(type).getObjectValue(rset);
|
||||
});
|
||||
return nativeQuery(sql, rset -> EntityBuilder.getOneValue(type, rset));
|
||||
}
|
||||
|
||||
default <V> CompletableFuture<V> nativeQueryOneAsync(Class<V> type, String sql) {
|
||||
return nativeQueryAsync(sql, rset -> {
|
||||
if (!rset.next()) {
|
||||
return null;
|
||||
}
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
|| (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) {
|
||||
return (V) formatColumnValue(type, rset.getObject(1));
|
||||
}
|
||||
return EntityBuilder.load(type).getObjectValue(rset);
|
||||
});
|
||||
return nativeQueryAsync(sql, rset -> EntityBuilder.getOneValue(type, rset));
|
||||
}
|
||||
|
||||
default <V> List<V> nativeQueryList(Class<V> type, String sql) {
|
||||
return nativeQuery(sql, rset -> {
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
|| (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) {
|
||||
List<V> list = new ArrayList<>();
|
||||
while (rset.next()) {
|
||||
list.add(rset.wasNull() ? null : (V) formatColumnValue(type, rset.getObject(1)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return EntityBuilder.load(type).getObjectList(rset);
|
||||
});
|
||||
return nativeQuery(sql, rset -> EntityBuilder.getListValue(type, rset));
|
||||
}
|
||||
|
||||
default <V> CompletableFuture<List<V>> nativeQueryListAsync(Class<V> type, String sql) {
|
||||
return nativeQueryAsync(sql, rset -> {
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
|| (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) {
|
||||
List<V> list = new ArrayList<>();
|
||||
while (rset.next()) {
|
||||
list.add(rset.wasNull() ? null : (V) formatColumnValue(type, rset.getObject(1)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return EntityBuilder.load(type).getObjectList(rset);
|
||||
});
|
||||
return nativeQueryAsync(sql, rset -> EntityBuilder.getListValue(type, rset));
|
||||
}
|
||||
|
||||
default <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper) {
|
||||
return nativeQuerySheet(type, sql, flipper, Collections.emptyMap());
|
||||
}
|
||||
|
||||
default <V> CompletableFuture<Sheet<V>> nativeQuerySheetAsync(Class<V> type, String sql, Flipper flipper) {
|
||||
return nativeQuerySheetAsync(type, sql, flipper, Collections.emptyMap());
|
||||
}
|
||||
|
||||
default <K, V> Map<K, V> nativeQueryMap(Class<K> keyType, Class<V> valType, String sql) {
|
||||
@@ -390,4 +364,13 @@ public interface DataSqlSource extends DataSource {
|
||||
default CompletableFuture<Map<Integer, String>> nativeQueryIntStrMapAsync(String sql, Serializable bean) {
|
||||
return nativeQueryMapAsync(Integer.class, String.class, sql, (Map<String, Object>) Copier.copyToMap(bean, Copier.OPTION_SKIP_NULL_VALUE));
|
||||
}
|
||||
|
||||
default <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper, Serializable bean) {
|
||||
return nativeQuerySheet(type, sql, flipper, (Map<String, Object>) Copier.copyToMap(bean, Copier.OPTION_SKIP_NULL_VALUE));
|
||||
}
|
||||
|
||||
default <V> CompletableFuture<Sheet<V>> nativeQuerySheetAsync(Class<V> type, String sql, Flipper flipper, Serializable bean) {
|
||||
return nativeQuerySheetAsync(type, sql, flipper, (Map<String, Object>) Copier.copyToMap(bean, Copier.OPTION_SKIP_NULL_VALUE));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -183,6 +183,29 @@ public class EntityBuilder<T> {
|
||||
unconstructorAttributes, attributeMap, queryAttrs.toArray(new Attribute[queryAttrs.size()]));
|
||||
}
|
||||
|
||||
public static <T> List<T> getListValue(Class<T> type, final DataResultSet rset) {
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
|| (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) {
|
||||
List<T> list = new ArrayList<>();
|
||||
while (rset.next()) {
|
||||
list.add(rset.wasNull() ? null : (T) DataResultSet.formatColumnValue(type, rset.getObject(1)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return EntityBuilder.load(type).getObjectList(rset);
|
||||
}
|
||||
|
||||
public static <T> T getOneValue(Class<T> type, final DataResultSet rset) {
|
||||
if (!rset.next()) {
|
||||
return null;
|
||||
}
|
||||
if (type == byte[].class || type == String.class || type.isPrimitive() || Number.class.isAssignableFrom(type)
|
||||
|| (!Map.class.isAssignableFrom(type) && type.getName().startsWith("java."))) {
|
||||
return (T) DataResultSet.formatColumnValue(type, rset.getObject(1));
|
||||
}
|
||||
return EntityBuilder.load(type).getObjectValue(rset);
|
||||
}
|
||||
|
||||
public List<T> getObjectList(final DataResultSet rset) {
|
||||
List<T> list = new ArrayList<>();
|
||||
List<String> sqlColumns = rset.getColumnLabels();
|
||||
|
||||
Reference in New Issue
Block a user