自己实现一个JPA中的分页
来源:互联网 发布:win7公用网络点不了 编辑:程序博客网 时间:2024/06/10 00:22
前言
最近有一个需求必须要使用原生SQL进行查询数据
这就带来了一个问题:没办法使用JPA直接传入Pageable对象进行分页查询
所以就需要自己实现一个类似JPA分页的功能
在查了源码之后也没有看到JPA到底是怎么实现的(如果有知道的请告诉我…)
所以自己封装了一个工具类来模拟了JPA的分页
项目github地址:https://github.com/wchstrife/JPA-MyPage
JPA中的分页
下面先让我们看一看JPA中Page是如何使用的
我们先建一个学生Student的实体(省略了构造、get、set方法)
Stuent:
@Entity@Table(name = "student")public class Student implements Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid") @Column(name = "id", columnDefinition = "varchar(64) binary") private String id; @Column(name = "name", length = 128) private String name; @Column(name = "age") private int age; @Column(name = "idcard") private String idCard; @Column(name = "school_name") private String schoolName;
controller中定义好映射的路径
@GetMapping("/get/jpaPage") public JSONObject getAllByPage(HttpServletRequest request, HttpServletResponse response, @RequestParam("page") int page, @RequestParam("size") int size){ Page<Student> studentPage = studentService.findAllStudentByPage(page, size); JSONObject jsonObject = (JSONObject) JSON.toJSON(studentPage); return jsonObject; }
访问该路径,可以看到使用JPA的分页给我们返回的数据
{ "number": 0, "last": false, "numberOfElements": 2, "size": 2, "totalPages": 3, "sort": null, "content": [ { "idCard": "41524134", "name": "王宸昊", "id": "1", "schoolName": "北京科技大学", "age": 21 }, { "idCard": "41524133", "name": "张三", "id": "2", "schoolName": "北京大学", "age": 23 } ], "first": true, "totalElements": 5}
可以看到Page返回的每一个参数包含的内容
- number : 当前为第几页
- last: 是否为最后一页
- numberOfElements: 当前页有多少条数据
- size : 每页有多少条数据
- totalPages: 总共有多少页
- content:数据的内容
- first: 是否为第一页
- totalElements : 总共有多少条数据
自己实现Page
有了上面的参数,我们就需要模仿一个一样的分页
首先让我们先根据上面的参数写一个工具类:
public class PageUtil { /** * 每页大小 */ private int size; /** * 当前页为第几页 */ private int number; /** * 是否为第一页 */ private boolean first = false; /** * 是否为最后一页 */ private boolean last = false; /** * 总共有多少页 */ private int totalPages; /** * 总共有多少条数据 */ private int totalElements; /** * 当前页一共有多少条数据 */ private int numberOfElements; /** * 数据 */ private List content = new ArrayList(); /** * 根据传入的当前多少页 * @param size * @param number * @param totalElements */ public PageUtil(int size, int number, int totalElements) { this.size = size; this.totalElements = totalElements; this.number = number < 0 ? 0 : number; this.totalPages = totalElements % size == 0 ? totalElements/size : (totalElements/size) + 1; this.first = number == 0 ? true : false; this.last = number == this.totalPages ? true : false; }
注意,这里NumberOfElements和Content这两个属性需要在添加数据的时候set进去
然后我们在service中写我们的具体逻辑
/** * 自定义分页获取所有学生 * @param page * @param size */ public PageUtil findAllStudentByMypage(int page, int size){ /*分页查询数据*/ Query query = em.createNativeQuery("SELECT * FROM student s LIMIT " + page*size + "," + size); List<Student> studentList = query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list(); /*查询总共的数据条目*/ query = em.createNativeQuery("SELECT COUNT(*) FROM student"); Object object = query.getResultList().get(0); int totalElements = Integer.parseInt(object.toString()); /*构建自定义Page对象*/ PageUtil pageUtil = new PageUtil(size, page, totalElements); pageUtil.setNumberOfElements(studentList.size()); pageUtil.setContent(studentList); return pageUtil; }
- 我们按照JPA的约定,传入的page是从0开始的,我们返回的时候第一页也是从0开始的。
- 第一条sql,使用sql中的limit关键字对数据进行分页查询,第一个参数是page*size。
- 第二条sql是查询所有的数据共有多少条,然后对这个总共有多少条进行除法等运算,就可以得到一共有多少页数据(具体的逻辑在工具类的构造方法中)
在controller中定义好路径
@GetMapping("/get/myPage") public JSONObject getAllByMyPage(HttpServletRequest request, HttpServletResponse response, @RequestParam("page") int page, @RequestParam("size") int size){ PageUtil pageUtil = studentService.findAllStudentByMypage(page, size); JSONObject jsonObject = (JSONObject) JSON.toJSON(pageUtil); return jsonObject; }
访问该路径,得到数据:
{ "number": 0, "last": false, "numberOfElements": 2, "size": 2, "totalPages": 3, "content": [ { "id_card": "41524134", "name": "王宸昊", "school_name": "北京科技大学", "id": "1", "age": 21 }, { "id_card": "41524133", "name": "张三", "school_name": "北京大学", "id": "2", "age": 23 } ], "first": true, "totalElements": 5}
可以看到content中的内容的key的值跟JPA当中的有稍微的区别
这是因为我们从数据库查出的数据的属性是按照数据库中存储的key来进行转换的
所以这里的key是数据库中的字段
要解决这个小问题可以从query 的 resultList拿出每一条数据再转为Student实体
阅读全文
0 0
- 自己实现一个JPA中的分页
- JPA实现分页
- JPA实现分页
- JPA通过DetachedCriteria实现分页
- JPA实现分页 返回总数
- JPA entityManager 实现 分页查询
- springBoot+easyui +spring data JPA 实现分页
- Spring Data JPA+kkpager实现分页功能
- SpringBoot进阶之JPA实现分页、排序
- Spring Data Jpa实现分页查询
- 自己写的一个分页
- JPA分页
- jpa 分页
- jpa 分页
- Java中的分页实现
- Spring Data Jpa 实现分页(Spring MVC+easyui)
- spring-data-jpa实现增删改查以及分页操作
- Spring Data JPA实现分页Pageable的实例代码
- 决策树
- Pict汇总
- Mybatis_day01
- jsp中request的常见使用方法
- jsp/servlet第一章tomcat
- 自己实现一个JPA中的分页
- SSL/TLS握手过程
- React Hello world
- textView设置行间距
- Linux 系统如何查看版本信息
- 计算机组成原理实验二:四位补码运算器
- 连咸鱼都能学会的Java多线程中的内存模型
- HDU-1159 Common Subsequence (线性dp 最长公共子串)
- 【QT编程】可以拍照录像的APP