完美的 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
  }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java文件上传详解

    Java文件上传详解Java文件上传详解文件上传和下载准备工作使用类介绍代码编写文件上传和下载在Web应用中,文件上传和下载功能是非常常用的功能,这篇博客就来讲一下JavaWeb中的文件上传和下载功能的实现。准备工作对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的。一般选择采用apache的开源工具common-fileupload这个文件上传组件。common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。首先下载最新的jar包https://mvnr

    2022年5月14日
    38
  • C++学习——类和对象

    C++学习——类和对象一、类和对象基本知识:1、类的访问控制有哪些?公有成员:以关键字public指明。私有成员:以关键字private指明。保护成员:以关键字protected指明。2、拷贝构造函数的作用是什么?用一个已经存在的对象初始化本类的新对象。3、友元函数和友元类的作用是什么?友元提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间进行 数据共享的机制。对于一个类,可以利用关键字fri…

    2022年8月18日
    3
  • origin画图记录[通俗易懂]

    origin画图记录[通俗易懂]origin画图记录折线图折线图origin存放数据的Book其实和excel的sheet很相似,画图的操作也有一定的相似性,只是origin比excel的功能更加强大。首先打开安装好的origin软件,其界面如下图所示:画线状图时,直接选中需要画图的数据,然后选择plot—Line—Line,即可画出对应的折线图,但是此时画出的折线图巨丑,重点时后续对它的美化。对绘制图形的美化以及一些常用功能:这个手掌的图形主要是用于移动、缩放图形中白色画板,效果如下:对坐标轴(刻度、

    2022年9月21日
    1
  • Spring Boot 无侵入式 实现API接口统一JSON格式返回

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 作者:小魏小魏我们去那里呀 blog.csdn.net/qq_34347620/article/details/10…

    2021年6月24日
    106
  • 数据库泄露,QQ密码,原来是这样「建议收藏」

    数据库泄露,QQ密码,原来是这样「建议收藏」近期大批数据库被暴,何解呢?参考相关帖子,加上本人的一点见解,有如下结论其实也不是什么结论,纯粹就是什么呢,嗯。。。。“一点都不意外,这在我们圈里流传很久了。”中国鹰派联盟网的创立者、鹰派代表万涛如此评价近期多家网站用户信息遭泄露一事。万涛曾参与组织了2001年中美黑客大战。万涛告诉早报记者,这些用户信息在业内已经是公开的,只是最近有好事者将其公布在网络上。他表

    2022年9月18日
    1
  • java获取服务器文件路径,干货满满!

    java获取服务器文件路径,干货满满!一、SpringCloud微服务概念定义提起微服务,不得不提SpringCloud全家桶系列,SpringCloud是一个服务治理平台,是若干个框架的集合,提供了全套的分布式系统解决方案。包含了:服务注册与发现、配置中心、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列等等。SpringCloud通过SpringBoot风格的封装,屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、容易部署的分布式系统开发工具包。开发者可以快速的启动服务或构建应用、同时能够

    2022年7月11日
    43

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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