完美的 jpa 多表 原生sql 分页查询[通俗易懂]

多表分页查询,强烈推荐原生sql一般需要两个方法,一个查条数,一个查当前页数据Page使用spring的page类@Query(value=””+””+”select”+”a.id,”+”a.title,”+”a.article…

大家好,又见面了,我是你们的朋友全栈君。

多表分页查询,强烈推荐原生sql

一般需要两个方法,一个查条数,一个查当前页数据



    @Query(value = "" +
            "" +
            " select " +
            "a.id," +
            "a.title," +
            "a.article_abstract," +
            "a.author_id," +
            "a.like_count ," +
            "a.read_count," +
            "a.tags," +
            "a.create_time," +
            "a.update_time," +
            "a.type," +
            "a.`status` " +
            " from re_article_category rac " +
            "" +
            " left join " +
            " article a " +
            "" +
            " on a.id=rac.article_id " +
            "" +
            " where rac.category_id= :catId" +
            " and a.status = :status limit :start,:size",nativeQuery = true)
    List<Object[]> pageByCatId(@Param("catId") Integer catId,@Param("status")String status,@Param("start")long start, @Param("size")int size);

   @Query(value = "select" +
           " count(a.id)" +
           " from re_article_category rac" +
           "" +
           " left join " +
           " article a" +
           "" +
           " on a.id=rac.article_id" +
           "" +
           " where rac.category_id= :catId" +
           " and a.status= :status",nativeQuery = true)
    Integer countByCat(@Param("catId") Integer catId,@Param("status") String status);

service 层转换:

    //根据分类获取所有文章
    @Override
    public Result getPageByCatId(Integer catId, Integer limit, Integer pageNo) { 
   

  PageRequest pageRequest = PageRequest.of(pageNo, limit);//借助计算起始位置
        int total=blogDao.countByCat(catId,BLOG_STATUS_NORMAL);// 计算数据总条数
        List<Object[]> records=blogDao.pageByCatId(catId,BLOG_STATUS_NORMAL,pageRequest.getOffset(),pageRequest.getPageSize());// 获取分页数据
        Page<Object[]> page =new Page<>(records,limit,pageNo,total);
           page.transferFromSqlList(BlogModel.class);// 转换分页数据到具体的java bean
        return Result.success(page);


    }
}

Page.java(自定义工具)


package com.blog.demo.common.util;
import com.google.common.collect.Lists;
import org.springframework.data.domain.PageImpl;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** * 与具体ORM实现无关的分页参数及查询结果封装. * * * @param <T> Page中记录的类型. * * @author eagler006 email:eagler006@hotmail.com * @version 1.2 */
public class Page<T> { 

//-- 分页参数 --//
protected int pageNo = 1;
protected int pageSize = 15;
protected int first =-1; //此处添加主要是为了方便分库分表时计算各表步进取值,当大于0时说明getFirst()函数不从pageNo计算获得
protected boolean autoCount = true;
protected String sort="id";
protected String dir= "ASC";
//-- 返回结果 --//
protected List result = Lists.newArrayList();
protected long totalCount = -1;
//-- 构造函数 --//
public Page() { 

}
public Page(List<Object[]> data,int size,int pageNo,int totalCount){ 

setPageNo(pageNo);
setPageSize(size);
setTotalCount(totalCount);
setResult(data);
}
public Page(int pageSize) { 

this.pageSize = pageSize;
}
public void transferFromSqlList(Class clazz){ 

List tResult = Lists.newArrayList();
ArrayList<Object> objArr;
for (Object objItem : result){ 

try { 

objArr = new ArrayList<Object>(Arrays.asList((Object[]) objItem));
Constructor<T> constructor = clazz.getDeclaredConstructor(objArr.getClass());
tResult.add(constructor.newInstance(objArr));
} catch (Exception e){ 

e.printStackTrace();
}
}
this.result = tResult;
}
public void copyPropertiesFromAnother(Page<?> page){ 

this.pageNo = page.getPageNo();
this.pageSize = page.getPageSize();
this.first = page.getFirst();
this.autoCount = page.isAutoCount();
this.sort = page.getSort();
this.dir = page.getDir();
this.totalCount = page.getTotalCount();
}
//-- 访问查询参数函数 --//
/** * 获得当前页的页号,序号从1开始,默认为1. */
public int getPageNo() { 

return pageNo;
}
/** * 设置当前页的页号,序号从1开始,低于1时自动调整为1. */
public void setPageNo(final int pageNo) { 

this.pageNo = pageNo;
if (pageNo < 1) { 

this.pageNo = 1;
}
}
public Page<T> pageNo(final int thePageNo) { 

setPageNo(thePageNo);
return this;
}
/** * 获得每页的记录数量,默认为1. */
public int getPageSize() { 

return pageSize;
}
/** * 设置每页的记录数量,低于1时自动调整为1. */
public void setPageSize(final int pageSize) { 

this.pageSize = pageSize;
if (pageSize < 1) { 

this.pageSize = 1;
}
}
public Page<T> pageSize(final int thePageSize) { 

setPageSize(thePageSize);
return this;
}
/** * @return the sort */
public String getSort() { 

return sort;
}
/** * @param sort the sort to set */
public void setSort(String sort) { 

this.sort = sort;
}
/** * @return the dir */
public String getDir() { 

return dir;
}
/** * @param dir the dir to set */
public void setDir(String dir) { 

this.dir = dir;
}
/** * 根据pageNo和pageSize计算当前页第一条记录在总结果集中的位置,序号从1开始. */
public int getFirst() { 

if(this.first>0)
return first;
return ((pageNo - 1) * pageSize) + 1;
}
/** * @param first the first to set */
public void setFirst(int first) { 

this.first = first;
}
/** * 查询对象时是否自动另外执行count查询获取总记录数, 默认为false. */
public boolean isAutoCount() { 

return autoCount;
}
/** * 查询对象时是否自动另外执行count查询获取总记录数. */
public void setAutoCount(final boolean autoCount) { 

this.autoCount = autoCount;
}
public Page<T> autoCount(final boolean theAutoCount) { 

setAutoCount(theAutoCount);
return this;
}
//-- 访问查询结果函数 --//
/** * 取得页内的记录列表. */
public List getResult() { 

return result;
}
/** * 设置页内的记录列表. */
public void setResult(final List result) { 

this.result = result;
}
/** * 取得总记录数, 默认值为-1. */
public long getTotalCount() { 

return totalCount;
}
/** * 设置总记录数. */
public void setTotalCount(final long totalCount) { 

this.totalCount = totalCount;
}
/** * 根据pageSize与totalCount计算总页数, 默认值为-1. */
public long getTotalPages() { 

if (totalCount < 0) { 

return -1;
}
long count = totalCount / pageSize;
if (totalCount % pageSize > 0) { 

count++;
}
return count;
}
/** * 是否还有下一页. */
public boolean isHasNext() { 

return (pageNo + 1 <= getTotalPages());
}
/** * 取得下页的页号, 序号从1开始. * 当前页为尾页时仍返回尾页序号. */
public int getNextPage() { 

if (isHasNext()) { 

return pageNo + 1;
} else { 

return pageNo;
}
}
/** * 是否还有上一页. */
public boolean isHasPre() { 

return (pageNo - 1 >= 1);
}
/** * 取得上页的页号, 序号从1开始. * 当前页为首页时返回首页序号. */
public int getPrePage() { 

if (isHasPre()) { 

return pageNo - 1;
} else { 

return pageNo;
}
}
}

效果:

{
"code": 0,
"msg": "success",
"data": {
"pageNo": 1,
"pageSize": 10,
"first": 1,
"autoCount": true,
"sort": "id",
"dir": "ASC",
"result": [
{
"id": 73,
"title": "标题",
"content": null,
"articleAbstract": "这是简介,请勿惊讶?",
"tags": "string",
"type": "1",
"readCount": null,
"likeCount": 1,
"status": "0",
"createTime": "2019-06-06T04:32:01.000+0000",
"updateTime": "2019-06-06T04:32:01.000+0000",
"categoryId": null
},
{
"id": 107,
"title": "正式文章",
"content": null,
"articleAbstract": "发布一篇文章",
"tags": "string",
"type": "0",
"readCount": 0,
"likeCount": 1,
"status": "0",
"createTime": "2019-06-06T10:32:11.000+0000",
"updateTime": "2019-06-06T10:32:11.000+0000",
"categoryId": null
}
],
"totalCount": 2,
"prePage": 1,
"hasNext": false,
"nextPage": 1,
"hasPre": false,
"totalPages": 1
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/129755.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 合宙Air720U&724U&722U Lua 固件更新说明

    合宙Air720U&724U&722U Lua 固件更新说明Lua固件更新说明如下:首推1.3基线,不支持1.2基线空中升级到1.3基线版本目录名称1.3底层core下载地址1.2底层core下载地址上层软件下载地址1.3底层core固件更新说明1.2底层core固件更新说明上层脚本更新说明空间说明Luat二次开发使用的Flash空间有两部分:脚本区和文件系统区脚本区:通过Luatools烧写的所有文件,都存放在此区域非TTS版本为720KB,TTS版本为426KB;如果烧录时,超过此限制,Luatools会报错不同版本的core可能会有差异,以

  • httprunner(4)录制生成测试用例[通俗易懂]

    httprunner(4)录制生成测试用例[通俗易懂]前言写用例之前,我们应该熟悉API的详细信息。建议使用抓包工具Charles或AnyProxy进行抓包。har2case我们先来了解一下另一个项目har2case他的工作原理就是将当前主流的抓

  • 一些非常有价值的资料网站有哪些_比较有价值的网站

    一些非常有价值的资料网站有哪些_比较有价值的网站最近在搜集资料的时候,发现了很多好的资料网站,不忍独享,陆续整理出来,贴这里。我先有一个贴一个,等到攒到足够多的时候,我再重新进行整理:电影类:IMDb:http://www.imdb.com/(美国著名互联网电影资料库(InternetMovieDatabase,简称IMDb)是一个关于电影演员、电影、电视节目、电视明星、电子游戏和电影制作的在线数据库。亚马逊公司旗下网站)烂番茄…

  • about bapi「建议收藏」

    about bapi「建议收藏」1BAPI的优点bapi是面向对象的设计;bapi是固定的,一般不能修改;bapi可以被sap内部部件和非sap程序使用;bapi的成功和错误信息始终通过RETURN返回;bapi可以被许多开发平台使用;2何时该考虑使用BAPI设计程序用VB/JAVA?C++等语言编写非SAPGUI程序访问和处理sap数据;SAP不同部件之间通讯;与…

  • c语言ioctl函数_min函数用法

    c语言ioctl函数_min函数用法ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下: intioctl(intfd,indcmd,…);    其中fd是用户程序打开设备时使用open函数返回的文件标示符,cmd是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,这个参数的…

    2022年10月18日
  • 部署环境什么意思_离线部署net

    部署环境什么意思_离线部署netNeokylin-Server离线环境部署Minio+keepalived集群Neokylin-Server离线环境部署Minio+keepalived集群一、说明二、部署过程:1.切换root账号或所有语句加sudo;2.关闭6个节点防火墙(或打开端口);3.设置所有节点;4.时间同步;5.3个节点创建目录与文件;6.添加权限;7.启动minio服务;8.n1-n3部署keepalived;Neokylin-Server离线环境部署Minio+keepalived集群一、说明背景:N

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号