webFlux MySQL r2dbc 分页工具

webFlux MySQL R2dbc架包

 
            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;
    }


你可能感兴趣的:(SpringCloud,webflux,mysql,java,spring,webflux)