新增RowBound功能

This commit is contained in:
redkale
2024-06-07 08:43:52 +08:00
parent 1c07fcc6fa
commit ba25120dea
9 changed files with 221 additions and 96 deletions

View File

@@ -5,9 +5,6 @@
*/
package org.redkale.net.http;
import static org.redkale.util.Utility.isEmpty;
import static org.redkale.util.Utility.isNotEmpty;
import java.io.*;
import java.lang.annotation.Annotation;
import java.net.*;
@@ -22,6 +19,8 @@ import org.redkale.convert.*;
import org.redkale.convert.json.JsonConvert;
import org.redkale.net.Request;
import org.redkale.util.*;
import static org.redkale.util.Utility.isEmpty;
import static org.redkale.util.Utility.isNotEmpty;
/**
* Http请求包 与javax.servlet.http.HttpServletRequest 基本类似。 <br>
@@ -2812,6 +2811,7 @@ public class HttpRequest extends Request<HttpContext> {
*
* @return Flipper翻页对象
*/
@ClassDepends
public org.redkale.source.Flipper getFlipper() {
return getFlipper(false, 0);
}

View File

@@ -915,12 +915,12 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
}
protected DataNativeSqlStatement nativeParse(
String nativeSql, boolean countable, Flipper flipper, Map<String, Object> params) {
String nativeSql, boolean countable, RowBound round, Map<String, Object> params) {
if (nativeSqlParser == null) {
throw new SourceException("not found " + DataNativeSqlParser.class.getSimpleName() + " instance");
}
return nativeSqlParser.parse(
signFunc, dbtype(), nativeSql, countable, flipper, params == null ? Collections.emptyMap() : params);
signFunc, dbtype(), nativeSql, countable, round, params == null ? Collections.emptyMap() : params);
}
@ConvertDisabled
@@ -3909,8 +3909,8 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
}
@Override
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper, Map<String, Object> params) {
return nativeQuerySheetAsync(type, sql, flipper, params).join();
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, RowBound round, Map<String, Object> params) {
return nativeQuerySheetAsync(type, sql, round, params).join();
}
@Override

View File

@@ -2838,8 +2838,8 @@ public class DataJdbcSource extends AbstractDataSqlSource {
@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));
Class<V> type, String sql, RowBound round, Map<String, Object> params) {
return supplyAsync(() -> nativeQuerySheet(type, sql, round, params));
}
@Deprecated

View File

@@ -28,7 +28,7 @@ public interface DataNativeSqlParser {
String dbType,
String rawSql,
boolean countable,
Flipper flipper,
RowBound round,
Map<String, Object> params);
public static DataNativeSqlParser loadFirst() {

View File

@@ -32,7 +32,7 @@ public class DataNativeSqlStatement {
String dbType,
String rawSql,
boolean countable,
Flipper flipper,
RowBound round,
Map<String, Object> params) {
throw new UnsupportedOperationException("No available instances found");
}

View File

@@ -3,13 +3,12 @@
*/
package org.redkale.source;
import static org.redkale.source.DataResultSet.formatColumnValue;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.*;
import org.redkale.annotation.ClassDepends;
import static org.redkale.source.DataResultSet.formatColumnValue;
import org.redkale.util.*;
/**
@@ -131,11 +130,11 @@ public interface DataSqlSource extends DataSource {
Map<String, Object> params);
@ClassDepends
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, Flipper flipper, Map<String, Object> params);
public <V> Sheet<V> nativeQuerySheet(Class<V> type, String sql, RowBound round, Map<String, Object> params);
@ClassDepends
public <V> CompletableFuture<Sheet<V>> nativeQuerySheetAsync(
Class<V> type, String sql, Flipper flipper, Map<String, Object> params);
Class<V> type, String sql, RowBound round, Map<String, Object> params);
// ----------------------------- 无参数 -----------------------------
default <V> V nativeQuery(String sql, Function<DataResultSet, V> handler) {

View File

@@ -5,30 +5,21 @@
*/
package org.redkale.source;
import java.io.Serializable;
import java.util.Objects;
import org.redkale.annotation.Comment;
import org.redkale.convert.ConvertColumn;
/**
* 翻页对象, offset从0开始, limit必须大于0
* 翻页+排序对象, offset从0开始, limit必须大于0
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
public final class Flipper implements Serializable, Cloneable {
public final class Flipper extends RowBound {
public static int DEFAULT_LIMIT = 20;
@ConvertColumn(index = 1)
@Comment("记录行的偏移量从0开始")
private int offset = 0;
@ConvertColumn(index = 2)
@Comment("每页多少行")
private int limit = DEFAULT_LIMIT;
@ConvertColumn(index = 3)
@Comment("排序字段, 可多字段排序")
private String sort = "";
@@ -36,7 +27,7 @@ public final class Flipper implements Serializable, Cloneable {
public Flipper() {}
public Flipper(int limit) {
this.limit = limit > 0 ? limit : 0;
super(limit);
}
public Flipper(String sortColumn) {
@@ -44,27 +35,42 @@ public final class Flipper implements Serializable, Cloneable {
}
public Flipper(int limit, int offset) {
this.limit = limit > 0 ? limit : 0;
this.offset = offset < 0 ? 0 : offset;
super(limit, offset);
}
public Flipper(int limit, String sortColumn) {
this.limit = limit > 0 ? limit : 0;
super(limit);
this.sort = sortColumn;
}
public Flipper(int limit, int offset, String sortColumn) {
this.limit = limit > 0 ? limit : 0;
this.offset = offset < 0 ? 0 : offset;
super(limit, offset);
this.sort = sortColumn;
}
@Override
public Flipper limit(int limit) {
super.limit(limit);
return this;
}
@Override
public Flipper maxLimit(int maxlimit) {
super.maxLimit(maxlimit);
return this;
}
@Override
public Flipper unlimit() {
super.unlimit();
return this;
}
public Flipper copyTo(Flipper copy) {
if (copy == null) {
return copy;
}
copy.offset = this.offset;
copy.limit = this.limit;
super.copyTo(copy);
copy.sort = this.sort;
return copy;
}
@@ -73,8 +79,7 @@ public final class Flipper implements Serializable, Cloneable {
if (copy == null) {
return this;
}
this.offset = copy.offset;
this.limit = copy.limit;
super.copyFrom(copy);
this.sort = copy.sort;
return this;
}
@@ -82,10 +87,11 @@ public final class Flipper implements Serializable, Cloneable {
/**
* 翻下一页
*
* @return Flipper
* @return RowBound
*/
@Override
public Flipper next() {
this.offset = getOffset() + this.limit;
super.next();
return this;
}
@@ -95,8 +101,9 @@ public final class Flipper implements Serializable, Cloneable {
* @param current 页号, 从1开始
* @return Flipper
*/
@Override
public Flipper current(int current) {
this.offset = (current - 1) * this.limit;
super.current(current);
return this;
}
@@ -108,8 +115,9 @@ public final class Flipper implements Serializable, Cloneable {
@Override
public String toString() {
return "{offset:" + this.offset + ",limit:" + this.limit
+ ((sort == null || sort.isEmpty()) ? "" : (",sort:\"" + this.sort.replace('"', '\'') + "\"")) + "}";
return "{\"limit\":" + this.limit + ",\"offset\":" + this.offset
+ ((sort == null || sort.isEmpty()) ? "" : (",\"sort\":\"" + this.sort.replace('"', '\'') + "\""))
+ "}";
}
@Override
@@ -142,42 +150,6 @@ public final class Flipper implements Serializable, Cloneable {
return Objects.equals(this.sort, other.sort);
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public Flipper limit(int limit) {
setLimit(limit);
return this;
}
public Flipper maxLimit(int maxlimit) {
setLimit(Math.max(1, Math.min(maxlimit, limit)));
return this;
}
public Flipper unlimit() {
this.limit = 0;
return this;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset < 0 ? 0 : offset;
}
public Flipper offset(int offset) {
setOffset(offset);
return this;
}
public String getSort() {
return sort;
}

View File

@@ -0,0 +1,154 @@
/*
*/
package org.redkale.source;
import java.io.Serializable;
import org.redkale.annotation.Comment;
import org.redkale.convert.ConvertColumn;
/**
* 翻页对象, offset从0开始, limit必须大于0
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public class RowBound implements Serializable, Cloneable {
public static int DEFAULT_LIMIT = 20;
@ConvertColumn(index = 1)
@Comment("记录行的偏移量从0开始")
protected int offset = 0;
@ConvertColumn(index = 2)
@Comment("每页多少行")
protected int limit = DEFAULT_LIMIT;
public RowBound() {}
public RowBound(int limit) {
this.limit = limit > 0 ? limit : 0;
}
public RowBound(int limit, int offset) {
this.limit = limit > 0 ? limit : 0;
this.offset = offset < 0 ? 0 : offset;
}
public RowBound copyTo(RowBound copy) {
if (copy == null) {
return copy;
}
copy.offset = this.offset;
copy.limit = this.limit;
return copy;
}
public RowBound copyFrom(RowBound copy) {
if (copy == null) {
return this;
}
this.offset = copy.offset;
this.limit = copy.limit;
return this;
}
/**
* 翻下一页
*
* @return RowBound
*/
public RowBound next() {
this.offset = getOffset() + this.limit;
return this;
}
/**
* 设置当前页号页号从1开始
*
* @param current 页号, 从1开始
* @return Flipper
*/
public RowBound current(int current) {
this.offset = (current - 1) * this.limit;
return this;
}
@Override
@SuppressWarnings("CloneDoesntCallSuperClone")
public RowBound clone() {
return this.copyTo(new RowBound());
}
@Override
public String toString() {
return "{\"limit\":" + this.limit + ",\"offset\":" + this.offset + "}";
}
@Override
public int hashCode() {
int hash = 5;
hash = 37 * hash + this.offset;
hash = 37 * hash + this.limit;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RowBound other = (RowBound) obj;
return this.offset != other.offset && this.limit != other.limit;
}
public RowBound limit(int limit) {
setLimit(limit);
return this;
}
public RowBound maxLimit(int maxlimit) {
setLimit(Math.max(1, Math.min(maxlimit, limit)));
return this;
}
public RowBound unlimit() {
this.limit = 0;
return this;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset < 0 ? 0 : offset;
}
public RowBound offset(int offset) {
setOffset(offset);
return this;
}
public static boolean validLimit(RowBound flipper) {
return flipper != null && flipper.getLimit() > 0;
}
}

View File

@@ -36,7 +36,7 @@ import org.redkale.source.DataNativeSqlParser;
import org.redkale.source.DataSqlMapper;
import org.redkale.source.DataSqlSource;
import org.redkale.source.EntityBuilder;
import org.redkale.source.Flipper;
import org.redkale.source.RowBound;
import org.redkale.source.SourceException;
import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.Sheet;
@@ -122,21 +122,21 @@ public final class DataSqlMapperBuilder {
AsmMethodBean methodBean = selfMethodBeans.get(AsmMethodBoost.getMethodBeanKey(method));
List<String> fieldNames = methodBean.paramNameList(method);
Class resultClass = resultClass(method);
int flipperIndex = -1;
int roundIndex = -1;
if (resultClass.isAssignableFrom(Sheet.class)) {
Class[] pts = method.getParameterTypes();
for (int i = 0; i < pts.length; i++) {
if (pts[i] == Flipper.class) {
flipperIndex = i;
if (RowBound.class.isAssignableFrom(pts[i])) {
roundIndex = i;
break;
}
}
if (flipperIndex < 0) {
if (roundIndex < 0) {
throw new SourceException(
mapperType.getSimpleName() + "." + method.getName() + " need Flipper type parameter on @"
mapperType.getSimpleName() + "." + method.getName() + " need RowBound type parameter on @"
+ Sql.class.getSimpleName() + "(" + sql.value() + ")");
}
fieldNames.remove(flipperIndex);
fieldNames.remove(roundIndex);
}
if (!Utility.equalsElement(sqlInfo.getRootParamNames(), fieldNames)) {
throw new SourceException(mapperType.getSimpleName() + "." + method.getName()
@@ -148,13 +148,13 @@ public final class DataSqlMapperBuilder {
throw new SourceException("Update SQL must on return int method, but " + method);
}
}
items.add(new Item(method, sqlInfo, methodBean, flipperIndex));
items.add(new Item(method, sqlInfo, methodBean, roundIndex));
}
// ------------------------------------------------------------------------------
final String utilClassName = Utility.class.getName().replace('.', '/');
final String sheetDesc = Type.getDescriptor(Sheet.class);
final String flipperDesc = Type.getDescriptor(Flipper.class);
final String roundDesc = Type.getDescriptor(RowBound.class);
final String entityDesc = Type.getDescriptor(entityType);
final String sqlSourceName = DataSqlSource.class.getName().replace('.', '/');
final String sqlSourceDesc = Type.getDescriptor(DataSqlSource.class);
@@ -218,7 +218,7 @@ public final class DataSqlMapperBuilder {
Method method = item.method;
DataNativeSqlInfo sqlInfo = item.sqlInfo;
AsmMethodBean methodBean = item.methodBean;
int flipperIndex = item.flipperIndex;
int roundIndex = item.roundIndex;
Sql sql = method.getAnnotation(Sql.class);
Class resultClass = resultClass(method);
Class[] componentTypes = resultComponentType(method);
@@ -247,16 +247,16 @@ public final class DataSqlMapperBuilder {
}
// 参数sql
mv.visitLdcInsn(sql.value());
if (flipperIndex >= 0) {
mv.visitVarInsn(ALOAD, flipperIndex + 1);
if (roundIndex >= 0) {
mv.visitVarInsn(ALOAD, roundIndex + 1);
}
// 参数: params
Asms.visitInsn(mv, paramTypes.length * 2 - (flipperIndex >= 0 ? 2 : 0));
Asms.visitInsn(mv, paramTypes.length * 2 - (roundIndex >= 0 ? 2 : 0));
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
int insn = 0;
for (int i = 0; i < paramTypes.length; i++) {
insn++;
if (i != flipperIndex) {
if (i != roundIndex) {
Class pt = paramTypes[i];
// 参数名
mv.visitInsn(DUP);
@@ -293,7 +293,7 @@ public final class DataSqlMapperBuilder {
// Map: "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/Map;"
// List: "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/List;"
// Sheet:
// "(Ljava/lang/Class;Ljava/lang/String;Lorg/redkale/source/Flipper;Ljava/util/Map;)Lorg/redkale/util/Sheet;"
// "(Ljava/lang/Class;Ljava/lang/String;Lorg/redkale/source/RowRound;Ljava/util/Map;)Lorg/redkale/util/Sheet;"
// Async: "(Ljava/lang/Class;Ljava/lang/String;Ljava/util/Map;)Ljava/util/concurrent/CompletableFuture;"
if (sqlInfo.getSqlMode() == SELECT) {
String queryMethodName = "nativeQueryOne";
@@ -313,7 +313,7 @@ public final class DataSqlMapperBuilder {
} else if (resultClass.isAssignableFrom(Sheet.class)) {
oneMode = false;
queryMethodName = "nativeQuerySheet";
queryMethodDesc = "(Ljava/lang/Class;Ljava/lang/String;" + flipperDesc + "Ljava/util/Map;)"
queryMethodDesc = "(Ljava/lang/Class;Ljava/lang/String;" + roundDesc + "Ljava/util/Map;)"
+ (async ? "Ljava/util/concurrent/CompletableFuture;" : sheetDesc);
}
mv.visitMethodInsn(
@@ -453,13 +453,13 @@ public final class DataSqlMapperBuilder {
public AsmMethodBean methodBean;
public int flipperIndex = -1;
public int roundIndex = -1;
public Item(Method method, DataNativeSqlInfo sqlInfo, AsmMethodBean methodBean, int flipperIndex) {
public Item(Method method, DataNativeSqlInfo sqlInfo, AsmMethodBean methodBean, int roundIndex) {
this.method = method;
this.sqlInfo = sqlInfo;
this.methodBean = methodBean;
this.flipperIndex = flipperIndex;
this.roundIndex = roundIndex;
}
}
}