org.springframework.boot
spring-boot-starter-data-r2dbc
org.springframework
spring-jdbc
com.github.jasync-sql
jasync-r2dbc-mysql
2.0.7
runtime
MonoFluxException 为一个自定义的异常类
import com.kittlen.comm.PageBean;
import com.kittlen.exception.MonoFluxException;
import com.kittlen.comm.entity.ResultWrapper;
import com.kittlen.comm.page.PageParam;
import io.r2dbc.spi.Row;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Query;
import org.springframework.r2dbc.core.PreparedOperation;
import org.springframework.r2dbc.core.RowsFetchSpec;
import org.springframework.r2dbc.core.binding.BindTarget;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.function.Function;
/**
* 分页查询工具
*
* @author kittlen
* @version 1.0
* @date 2023/02/06 11:18
*/
@Component
public class SQLSelectUtil {
@Autowired
R2dbcEntityTemplate r2dbcEntityTemplate;
public <T> Flux<T> baseSearchNotSort(Query baseQuery, Class<T> entityClass) {
return r2dbcEntityTemplate.select(baseQuery, entityClass);
}
public <T> Flux<T> baseSearchDefSor(Query baseQuery, Class<T> entityClass, Sort sort) {
Query query = baseQuery.sort(sort != null ? sort : Sort.by(Sort.Order.desc("update_time")));
return r2dbcEntityTemplate.select(query, entityClass);
}
/**
* 基础的分页查询
*
* @param baseQuery
* @param pageParam
* @param entityClass
* @param
* @return
*/
public <T> Mono<ResultWrapper<PageBean<T>>> baseSearch(Query baseQuery, PageParam pageParam, Class<T> entityClass) {
return baseSearch(baseQuery, pageParam, entityClass, null);
}
/**
* 基础的分页查询
*
* @param baseQuery
* @param pageParam
* @param entityClass
* @param
* @param sort 排序情况
* @return
*/
public <T> Mono<ResultWrapper<PageBean<T>>> baseSearch(Query baseQuery, PageParam pageParam, Class<T> entityClass, Sort sort) {
return baseMonoSearch(baseQuery, pageParam, entityClass, sort)
.switchIfEmpty(Mono.error(MonoFluxException.create("查询失败")))
.map(ResultWrapper::ok);
}
/**
* 基础的分页查询
*
* @param baseQuery
* @param pageParam
* @param entityClass
* @param
* @return
*/
public <T> Mono<PageBean<T>> baseMonoSearch(Query baseQuery, PageParam pageParam, Class<T> entityClass) {
return baseMonoSearch(baseQuery, pageParam, entityClass, null);
}
public <T> Mono<PageBean<T>> baseMonoSearch(Query baseQuery, PageParam pageParam, Class<T> entityClass, Sort sort) {
int skip = (pageParam.getPageNum() - 1) * pageParam.getNumPerPage();
int limit = pageParam.getNumPerPage();
Query pageQuery = baseQuery.offset(skip).limit(limit).sort(sort != null ? sort : Sort.by(Sort.Order.desc("update_time")));
Mono<Long> countMono = r2dbcEntityTemplate.count(baseQuery, entityClass);
return countMono.switchIfEmpty(Mono.just(0L)).flatMap(count -> {
if (count <= 0) {
PageBean<T> data = new PageBean(pageParam, 0, (List<T>) ListUtils.EMPTY_LIST);
return Mono.just(data);
}
Flux<T> selectFlux = r2dbcEntityTemplate.select(pageQuery, entityClass);
return selectFlux
.buffer()
.single((List<T>) ListUtils.EMPTY_LIST)
.map(list -> {
PageBean<T> pageBean = new PageBean(pageParam, count.intValue(), list);
return pageBean;
});
});
}
/**
* 基础的分页查询
*
* @param pageParam
* @param entityClass
* @param
* @return
*/
public <T> Mono<PageBean<T>> baseMonoSearch(String sql, PageParam pageParam, Class<T> entityClass) {
sql = sql.replaceAll("\\s{2,}", " ").replace(" FROM", " from").replace("ORDER BY", "order by").replace("GROUP BY", "group by").trim();
String newSQL;
if (sql.lastIndexOf(";") == sql.length() - 1) {
newSQL = sql.substring(0, sql.length() - 1);
} else {
newSQL = sql;
}
String pageSql = "select count(1)" + sql.substring(sql.indexOf(" from"));
int skip = (pageParam.getPageNum() - 1) * pageParam.getNumPerPage();
int limit = pageParam.getNumPerPage();
StringBuilder sb = new StringBuilder(newSQL);
newSQL = sb.append(" limit ").append(skip).append(" , ").append(limit).toString();
RowsFetchSpec<Long> countQuery = r2dbcEntityTemplate.query(new BasePreparedOperation(pageSql), (row) -> row.get(0, Long.class));
RowsFetchSpec<T> query = r2dbcEntityTemplate.query(new BasePreparedOperation(newSQL), entityClass);
return countQuery.first().switchIfEmpty(Mono.just(0L)).flatMap(count -> {
if (count <= 0) {
PageBean<T> data = new PageBean(pageParam, 0, (List<T>) ListUtils.EMPTY_LIST);
return Mono.just(data);
} else {
return query.all().buffer().single((List<T>) ListUtils.EMPTY_LIST)
.map(lt -> {
PageBean<T> pageBean = new PageBean(pageParam, count.intValue(), lt);
return pageBean;
});
}
});
}
/**
* 基础的分页查询
*
* @param pageParam
* @param entityClass
* @param
* @return
*/
public <T> Mono<PageBean<T>> baseMonoSearch(String baseSql, String pageSql, PageParam pageParam, Class<T> entityClass) {
baseSql = baseSql.replaceAll("\\s{2,}", " ").replace(" FROM", " from").replace("ORDER BY", "order by").replace("GROUP BY", "group by").trim();
String newSQL;
if (baseSql.lastIndexOf(";") == baseSql.length() - 1) {
newSQL = baseSql.substring(0, baseSql.length() - 1);
} else {
newSQL = baseSql;
}
int skip = (pageParam.getPageNum() - 1) * pageParam.getNumPerPage();
int limit = pageParam.getNumPerPage();
StringBuilder sb = new StringBuilder(newSQL);
newSQL = sb.append(" limit ").append(skip).append(" , ").append(limit).toString();
RowsFetchSpec<Long> countQuery = r2dbcEntityTemplate.query(new BasePreparedOperation(pageSql), (row) -> row.get(0, Long.class));
RowsFetchSpec<T> query = r2dbcEntityTemplate.query(new BasePreparedOperation(newSQL), entityClass);
return countQuery.first().switchIfEmpty(Mono.just(0L)).flatMap(count -> {
if (count <= 0) {
PageBean<T> data = new PageBean(pageParam, 0, (List<T>) ListUtils.EMPTY_LIST);
return Mono.just(data);
} else {
return query.all().buffer().single((List<T>) ListUtils.EMPTY_LIST)
.map(lt -> {
PageBean<T> pageBean = new PageBean(pageParam, count.intValue(), lt);
return pageBean;
});
}
});
}
/**
* 基础的分页查询
*
* @param pageParam
* @param rowTFunction
* @param
* @return
*/
public <T> Mono<PageBean<T>> baseMonoSearch(String sql, PageParam pageParam, Function<Row, T> rowTFunction) {
sql = sql.replaceAll("\\s{2,}", " ").replace(" FROM", " from").replace("ORDER BY", "order by").replace("GROUP BY", "group by").trim();
String newSQL;
if (sql.lastIndexOf(";") == sql.length() - 1) {
newSQL = sql.substring(0, sql.length() - 1);
} else {
newSQL = sql;
}
String pageSql = "select count(1)" + sql.substring(sql.indexOf(" from"));
int skip = (pageParam.getPageNum() - 1) * pageParam.getNumPerPage();
int limit = pageParam.getNumPerPage();
StringBuilder sb = new StringBuilder(newSQL);
newSQL = sb.append(" limit ").append(skip).append(" , ").append(limit).toString();
RowsFetchSpec<Long> countQuery = r2dbcEntityTemplate.query(new BasePreparedOperation(pageSql), (row) -> row.get(0, Long.class));
RowsFetchSpec<T> query = r2dbcEntityTemplate.query(new BasePreparedOperation(newSQL), rowTFunction);
return countQuery.first().switchIfEmpty(Mono.just(0L)).flatMap(count -> {
if (count <= 0) {
PageBean<T> data = new PageBean(pageParam, 0, (List<T>) ListUtils.EMPTY_LIST);
return Mono.just(data);
} else {
return query.all().buffer().single((List<T>) ListUtils.EMPTY_LIST)
.map(lt -> {
PageBean<T> pageBean = new PageBean(pageParam, count.intValue(), lt);
return pageBean;
});
}
});
}
/**
* 基础的分页查询
*
* @param baseSql
* @param pageSql
* @param pageParam
* @param rowTFunction
* @param
* @return
*/
public <T> Mono<PageBean<T>> baseMonoSearch(String baseSql, String pageSql, PageParam pageParam, Function<Row, T> rowTFunction) {
baseSql = baseSql.replaceAll("\\s{2,}", " ").replace(" FROM", " from").replace("ORDER BY", "order by").replace("GROUP BY", "group by").trim();
String newSQL;
if (baseSql.lastIndexOf(";") == baseSql.length() - 1) {
newSQL = baseSql.substring(0, baseSql.length() - 1);
} else {
newSQL = baseSql;
}
int skip = (pageParam.getPageNum() - 1) * pageParam.getNumPerPage();
int limit = pageParam.getNumPerPage();
StringBuilder sb = new StringBuilder(newSQL);
newSQL = sb.append(" limit ").append(skip).append(" , ").append(limit).toString();
RowsFetchSpec<Long> countQuery = r2dbcEntityTemplate.query(new BasePreparedOperation(pageSql), (row) -> row.get(0, Long.class));
RowsFetchSpec<T> query = r2dbcEntityTemplate.query(new BasePreparedOperation(newSQL), rowTFunction);
return countQuery.first().switchIfEmpty(Mono.just(0L)).flatMap(count -> {
if (count <= 0) {
PageBean<T> data = new PageBean(pageParam, 0, (List<T>) ListUtils.EMPTY_LIST);
return Mono.just(data);
} else {
return query.all().buffer().single((List<T>) ListUtils.EMPTY_LIST)
.map(lt -> {
PageBean<T> pageBean = new PageBean(pageParam, count.intValue(), lt);
return pageBean;
});
}
});
}
/**
* 基础的查询
*
* @param sql
* @param entityClass
* @param
* @return
*/
public <T> Flux<T> baseMonoSearch(String sql, Class<T> entityClass) {
return r2dbcEntityTemplate.query(new BasePreparedOperation(sql), entityClass).all();
}
/**
* 基础的查询
*
* @param sql
* @param rowTFunction
* @param
* @return
*/
public <T> Flux<T> baseMonoSearch(String sql, Function<Row, T> rowTFunction) {
return r2dbcEntityTemplate.query(new BasePreparedOperation(sql), rowTFunction).all();
}
@Getter
@Setter
public static class BasePreparedOperation implements PreparedOperation {
private String sql;
public BasePreparedOperation(String sql) {
this.sql = sql;
}
@Override
public Object getSource() {
return null;
}
@Override
public void bindTo(BindTarget target) {
}
@Override
public String toQuery() {
return sql;
}
}
}
import com.kittlen.comm.page.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author kittlen
* @version 1.0
* @date 2022/11/30 17:37
*/
@Getter
@Setter
@ApiModel("分页返回值")
public class PageBean<T> implements Serializable {
@ApiModelProperty("当前页")
private int currentPage;
@ApiModelProperty("每页条数")
private int numPerPage;
@ApiModelProperty("总条数")
private int totalCount;
@ApiModelProperty("返回的数据")
private List<T> recordList;
@ApiModelProperty("总页数")
private int pageCount;
@ApiModelProperty("开始分页的数据index")
private int beginPageIndex;
@ApiModelProperty("结束分页的数据index")
private int endPageIndex;
@ApiModelProperty("结果映射")
private Map<String, Object> countResultMap;
@ApiModelProperty("es查询的滚动id")
private String scrollId;
public PageBean(PageBean pageBean) {
this(pageBean.getCurrentPage(), pageBean.getNumPerPage(), pageBean.getTotalCount(), new ArrayList<>());
}
public PageBean(PageBean pageBean, List<T> recordList) {
this(pageBean.getCurrentPage(), pageBean.getNumPerPage(), pageBean.getTotalCount(), recordList);
}
public PageBean() {
}
public PageBean(PageParam pageParam, int totalCount, List<T> recordList) {
this(pageParam.getPageNum(), pageParam.getNumPerPage(), totalCount, recordList);
}
/**
* @param currentPage 当前页
* @param numPerPage 每页条数
* @param totalCount 总条数
* @param recordList 数据
*/
public PageBean(int currentPage, int numPerPage, int totalCount, List<T> recordList) {
this.currentPage = currentPage;
this.numPerPage = numPerPage;
this.totalCount = totalCount;
this.recordList = recordList;
this.pageCount = (totalCount + numPerPage - 1) / numPerPage;
if (this.pageCount <= 10) {
this.beginPageIndex = 1;
this.endPageIndex = this.pageCount;
} else {
this.beginPageIndex = currentPage - 4;
this.endPageIndex = currentPage + 5;
if (this.beginPageIndex < 1) {
this.beginPageIndex = 1;
this.endPageIndex = 10;
}
if (this.endPageIndex > this.pageCount) {
this.endPageIndex = this.pageCount;
this.beginPageIndex = this.pageCount - 10 + 1;
}
}
}
public PageBean(int currentPage, int numPerPage, int totalCount, List<T> recordList, Map<String, Object> countResultMap) {
this.currentPage = currentPage;
this.numPerPage = numPerPage;
this.totalCount = totalCount;
this.recordList = recordList;
this.countResultMap = countResultMap;
this.pageCount = (totalCount + numPerPage - 1) / numPerPage;
if (this.pageCount <= 10) {
this.beginPageIndex = 1;
this.endPageIndex = this.pageCount;
} else {
this.beginPageIndex = currentPage - 4;
this.endPageIndex = currentPage + 5;
if (this.beginPageIndex < 1) {
this.beginPageIndex = 1;
this.endPageIndex = 10;
}
if (this.endPageIndex > this.pageCount) {
this.endPageIndex = this.pageCount;
this.beginPageIndex = this.pageCount - 10 + 1;
}
}
}
}
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@ApiModel("分页参数")
public class PageParam implements Serializable {
@ApiModelProperty("当前页")
private int pageNum;
@ApiModelProperty("每页条数")
private int numPerPage;
public PageParam() {
this.pageNum = 1;
this.numPerPage = 10;
}
public PageParam(int pageNum, int numPerPage) {
this.pageNum = pageNum;
this.numPerPage = numPerPage;
}
}
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
public class ResultWrapper<T> implements Serializable {
public static final int RESULT_OK = 200; //成功
public static final String RESULT_OK_MSG = "操作成功";
public static final int RESULT_ERROR = 500; //失败
public static final String RESULT_ERROR_MSG = "操作失败";
private int code;//编码
private T data;//数据
private long count;//计数
private String msg;//提示消息
public ResultWrapper() {
this.code = RESULT_OK;
this.msg = RESULT_OK_MSG;
}
public ResultWrapper(T data, long count, String msg) {
this(RESULT_OK, count, data, msg);
}
public ResultWrapper(int code, long count, T data, String msg) {
this.code = code;
this.count = count;
this.data = data;
this.msg = msg;
}
public ResultWrapper(T data, String msg) {
this(RESULT_OK, 0, data, msg);
}
public ResultWrapper(String msg) {
this(RESULT_OK, 0, null, msg);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public long getCount() {
return count;
}
public void setCount(long count) {
this.count = count;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public static <T> ResultWrapper<T> ok() {
return new ResultWrapper<T>();
}
public static <T> ResultWrapper<T> ok(T data) {
return new ResultWrapper<T>(data, RESULT_OK_MSG);
}
public static <T> ResultWrapper<T> ok(T data, String message) {
return new ResultWrapper<T>(data, message);
}
public static <T> ResultWrapper<T> ok(T data, String message, long count) {
return new ResultWrapper<T>(data, count, message);
}
public static <T> ResultWrapper<T> error() {
return new ResultWrapper<T>(RESULT_ERROR, 0, null, RESULT_ERROR_MSG);
}
public static <T> ResultWrapper<T> error(String message) {
return new ResultWrapper<T>(RESULT_ERROR, 0, null, message);
}
public static <T> ResultWrapper<T> error(String message, T data) {
return new ResultWrapper<T>(RESULT_ERROR, 0, data, message);
}
public static <T> ResultWrapper<T> error(T data, String message, long count) {
return new ResultWrapper<T>(RESULT_ERROR, count, data, message);
}
public static <T> ResultWrapper<T> builder(int code, long count, T data, String msg) {
return new ResultWrapper<T>(code, count, data, msg);
}
public static <T> ResultWrapper<T> builder(int code, String msg) {
return new ResultWrapper<T>(code, 0, null, msg);
}
public static <T> ResultWrapper<T> builder(String msg) {
return ok(null, msg);
}
@JsonIgnore
public boolean isSuccess() {
return this.code == RESULT_OK;
}
@JsonIgnore
public boolean isError() {
return this.code == RESULT_ERROR;
}