• 什么是分页?如何使用分页?


    分页分为逻辑分页和物理分页两种也称之为真假分页;

    🎒1.逻辑分页(假分页)

    逻辑分页:逻辑分页依赖于代码。(例:Mybatis自带的分页插件就是逻辑分页)
    同时逻辑分页是先查询出所有的数据,再根据代码块的所需(例:你需要拿到第几页,每页几条的数据)筛选出合适的数据进行分页。


    通过SQL将所有数据全部查询出来,然后根据游标进行筛选,只是显示出来部分而已。
    好处是所有数据库都统一,坏处就是效率低。

    📚2.物理分页(真分页)

    物理分页:物理分页依赖于数据库。(更侧重于sql语句)
    例:MySQL数据库提供的分页关键字"limit",程序员只需要编写带有关键字的SQL语句,数据库返回的数据就是分页结果。


    物理分页就是数据库本身提供了分页方式,如MySQL的limit,oracle的rownum 。
    好处是效率高,不好的地方就是不同数据库有不同的搞法。

    🏃3.两者对比

    概念简单点讲:
    逻辑分页就是半自动化的一个分页步骤(因为需要传递相关参数,所以是半自动化的);
    物理分页就是手写SQL语句实现的分页。

    1.数据库方面

    物理分页是手写SQL语句,故每一次分页都需要访问数据库;逻辑分页是将全部数据查询出来后再进行的分页,只需访问一次数据库。所以说,物理分页对于数据库造成的负担大。

    2.服务器方面

    逻辑分页一次性将所有的数据读取至内存中,占用了较大的内存空间;物理分页每次只读取所需的数据,占用内存比较小。

    3.实时性

    逻辑分页一次性将数据全部查询出来,如果数据库中的数据发生了改变,逻辑分页就不能够获取最新数据(不能自动更新数据),可能导致脏数据的出现,实时性较低
    物理分页每一次分页都需要从数据库中进行查询,这样能够获取数据库中数据的最新状态,实时性较高。

    👯4.逻辑分页代码实现;

    导入pom的依赖;

    
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    
    
    <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
    <dependency><!--导入分页插件-->
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.2.3</version>
    </dependency>
    
    
    
    
    注意版本依赖不然会使循环 报错 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    核心代码
    在这里插入图片描述
    核心代码展示说明:

    
     //开启分页 ,pageNum 页数    pageSize  每页几条数据 切记查询全部的方法是和 PageHelper.startPage(pageNum,pageSize); 必须在一起否者会导致报错;返回对象的话可以使用  return pageInfo.getList();
     
            PageHelper.startPage(pageNum,pageSize);
            List<Student> students = studentmapper.queryAllByPage();
            PageInfo<Student> pageInfo = new PageInfo<>(students);
            return pageInfo;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    完整demo:

    引入pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.5.7</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.huyangfeng</groupId>
        <artifactId>springboot-student-crud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-student-crud</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
        </properties>
     
        <dependencies>
            <!--JDBC-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <!--<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>-->
            <!--thymeleaf-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <!--web-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--mybatis整合springboot-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.1</version>
            </dependency>
            <!--<dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            </dependency>-->
            <!--mysql连接驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <!--lombok:偷懒神器-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
     
            <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
            <dependency><!--导入分页插件-->
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.3.0</version>
            </dependency>
     
     
        </dependencies>
     
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                            </exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
     
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    实体类:
    Dao接口
    在这里插入图片描述
    数据库 mapper.xml
    查询全部的代码
    在这里插入图片描述

    核心代码:

    ServiceImpl

    package com.xc.service.serviceImpl;
     
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import com.xc.mapper.Studentmapper;
    import com.xc.pojo.Student;
    import com.xc.service.StudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
     
    import java.util.List;
     
    
    @Service
    public class StudentServiceImpl implements StudentService {
     
        @Autowired
        private Studentmapper studentmapper;
     
        @Override
        public PageInfo<Student> queryAllByPage(Integer pageNum, Integer pageSize) {
            //开启分页
            PageHelper.startPage(pageNum,pageSize);
            List<Student> students = studentmapper.queryAllByPage();
            PageInfo<Student> pageInfo = new PageInfo<>(students);
            return pageInfo;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    控制台Controller

    package com.xc.controller;
     
    import com.github.pagehelper.PageInfo;
    import com.xc.pojo.Student;
    import com.xc.service.StudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
     
    
    @Controller
    public class StudentController {
     
        @Autowired
        private StudentService studentService;
     
        @RequestMapping("/list")
        public String queryAllByPage(@RequestParam(value = "pageNum",required = false,defaultValue = "1")Integer pageNum,
                                     @RequestParam(value = "pageSize",required = false,defaultValue = "5")Integer pageSize,
                                     Model model){
            PageInfo<Student> studentPageInfo = studentService.queryAllByPage(pageNum, pageSize);
            model.addAttribute("studentPageInfo",studentPageInfo);
            return "list";
        }
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    👯4.1逻辑分页代码实现(第二种自定义分页);

    controller 控制台

    /**
    	 *
    	 * @param
    	 * @param
    	 * @return
    	 * 查询table全部页面
    	 */
    //指定k,v 和默认值(defaultValue )
    	@RequestMapping("/selectAllDb")
    	@ResponseBody
    	public MsgContext selectallDb(@RequestParam(value = "pageNum",name = "pageNum" ,required = false,defaultValue = "1")Integer pageNum,
                @RequestParam(value = "pageSize",name = "pageSize",required = false,defaultValue = "9")Integer pageSize
    ) {
    		MsgContext mc = new MsgContext();
    		MyPageInfo<BizDsJdbc> bizDsJdbcVOS = dsService.selectallDb(pageNum,pageSize);
    		mc.addResult("data", bizDsJdbcVOS);
    		return mc;
    
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    接口server

     /**
         * 查询展示字段
         * @return
         */
        MyPageInfo<BizDsJdbc> selectallDb(Integer pageNum,Integer pageSize);
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实现 impl

       /**
        *查看展示信息
        * @return
        */
       @Override
       public MyPageInfo<BizDsJdbc> selectallDb(Integer pageNum,Integer pageSize) {
    	   //自己的查询全部的代码
    	   List<BizDsJdbc> bizDsJdbc1 = dsJdbcMapper.selectallDb();
    	   MyPageInfo<BizDsJdbc> myPageInfo = new MyPageInfo<>(bizDsJdbc1, pageNum, pageSize);
    	   
           return myPageInfo;
       }
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    核心类
    我们边开始引用@Data无效我单独加了get/set 你们按照自己需求来;

    package com.aostar.ida.business.datasources.vo;
    
    import java.io.Serializable;
    
    import lombok.Data;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    
    @Data
    
    public class MyPageInfo <T> implements Serializable{
    	
    	private static final long serialVersionUID = 1L;
        //当前页
        private Integer pageNum;
        //每页的数量
        private Integer pageSize;
        //当前页的数量
        private int size;
        //当前页面第一个元素在数据库中的行号
        private int startRow;
        //当前页面最后一个元素在数据库中的行号
        private int endRow;
        //总记录数
        private int total;
        //总页数
        private int pages;
        //结果集
        private List<T> list;
        //前一页
        private int prePage;
        //下一页
        private int nextPage;
        //是否为第一页
        private boolean isFirstPage = false;
        //是否为最后一页
        private boolean isLastPage = false;
        //是否有前一页
        private boolean hasPreviousPage = false;
        //是否有下一页
        private boolean hasNextPage = false;
        //导航页码数
        private int navigatePages;
        //所有导航页号
        private int[] navigatepageNums;
        //导航条上的第一页
        private int navigateFirstPage;
        //导航条上的最后一页
        private int navigateLastPage;
    
        
        public Integer getPageNum() {
            return pageNum;
        }
    
        public void setPageNum(Integer pageNum) {
            this.pageNum = pageNum;
        }
    
        public Integer getPageSize() {
            return pageSize;
        }
    
        public void setPageSize(Integer pageSize) {
            this.pageSize = pageSize;
        }
    
        public int getSize() {
            return size;
        }
    
        public void setSize(int size) {
            this.size = size;
        }
    
        public int getStartRow() {
            return startRow;
        }
    
        public void setStartRow(int startRow) {
            this.startRow = startRow;
        }
    
        public int getEndRow() {
            return endRow;
        }
    
        public void setEndRow(int endRow) {
            this.endRow = endRow;
        }
    
        public int getTotal() {
            return total;
        }
    
        public void setTotal(int total) {
            this.total = total;
        }
    
        public int getPages() {
            return pages;
        }
    
        public void setPages(int pages) {
            this.pages = pages;
        }
    
        public List<T> getList() {
            return list;
        }
    
        public void setList(List<T> list) {
            this.list = list;
        }
    
        public int getPrePage() {
            return prePage;
        }
    
        public void setPrePage(int prePage) {
            this.prePage = prePage;
        }
    
        public int getNextPage() {
            return nextPage;
        }
    
        public void setNextPage(int nextPage) {
            this.nextPage = nextPage;
        }
    
        public boolean isFirstPage() {
            return isFirstPage;
        }
    
        public void setFirstPage(boolean firstPage) {
            isFirstPage = firstPage;
        }
    
        public boolean isLastPage() {
            return isLastPage;
        }
    
        public void setLastPage(boolean lastPage) {
            isLastPage = lastPage;
        }
    
        public boolean isHasPreviousPage() {
            return hasPreviousPage;
        }
    
        public void setHasPreviousPage(boolean hasPreviousPage) {
            this.hasPreviousPage = hasPreviousPage;
        }
    
        public boolean isHasNextPage() {
            return hasNextPage;
        }
    
        public void setHasNextPage(boolean hasNextPage) {
            this.hasNextPage = hasNextPage;
        }
    
        public int getNavigatePages() {
            return navigatePages;
        }
    
        public void setNavigatePages(int navigatePages) {
            this.navigatePages = navigatePages;
        }
    
        public int[] getNavigatepageNums() {
            return navigatepageNums;
        }
    
        public void setNavigatepageNums(int[] navigatepageNums) {
            this.navigatepageNums = navigatepageNums;
        }
    
        public int getNavigateFirstPage() {
            return navigateFirstPage;
        }
    
        public void setNavigateFirstPage(int navigateFirstPage) {
            this.navigateFirstPage = navigateFirstPage;
        }
    
        public int getNavigateLastPage() {
            return navigateLastPage;
        }
    
        public void setNavigateLastPage(int navigateLastPage) {
            this.navigateLastPage = navigateLastPage;
        }
        
        /**
         * 对list集合进行分页
         * @param list 需要分页的集合
         * @param pageNum 当前页
         * @param pageSize 每页的数量
         */
        public MyPageInfo(List<T> list,Integer pageNum,Integer pageSize) {
            this(list, 8, pageNum, pageSize);
        }
    
    
        /**
         * 对list集合进行分页
         * @param list 需要分页的集合
         * @param navigatePages  导航页码数
         * @param pageNum 当前页
         * @param pageSize 每页的数量
         */
        public MyPageInfo(List<T> list, int navigatePages,int pageNum,int pageSize) {
    
            if (list instanceof Collection) {
                // 总记录数
                this.total = list.size();
                // 为了跟pageHelper一致,当pageNum<1时,按第一页处理
                int yourPageNum = pageNum;
                pageNum= pageNum<1 ? 1:pageNum;
                // 当前页码
                this.pageNum = pageNum;
                // 每页显示的记录数
                this.pageSize = pageSize;
                // 总页码数
                this.pages = (int)Math.ceil(this.total*1.0/this.pageSize);
                // 导航条页码数
                this.navigatePages = navigatePages;
                // 开始行号
                this.startRow = this.pageNum * this.pageSize - (this.pageSize - 1);
                // 结束行号
                this.endRow = this.pageNum * this.pageSize;
                // 当结束行号>总行数,结束行号=0
                if(this.endRow > this.total){
    
                    if(this.startRow > this.total){
                        this.endRow = 0;
                        this.startRow = 0;
                    }else {
                        this.endRow =this.total;
                    }
    
                }
                //计算导航页
                calcNavigatepageNums();
                //计算前后页,第一页,最后一页
                calcPage();
                //判断页面边界
                judgePageBoudary();
                // 当pageNum超过最大页数,则size=0,list为空
                if(this.pageNum > this.pages){
                    this.size = 0;
                    this.list = Collections.EMPTY_LIST;
                }else {
                    this.list = list.subList(startRow - 1,endRow);
                    this.size = this.list.size();
                }
                this.pageNum = yourPageNum;
            }
        }
    
        /**
         * 计算导航页
         */
        private void calcNavigatepageNums() {
            //当总页数小于或等于导航页码数时
            if (pages <= navigatePages) {
                navigatepageNums = new int[pages];
                for (int i = 0; i < pages; i++) {
                    navigatepageNums[i] = i + 1;
                }
            } else { //当总页数大于导航页码数时
                navigatepageNums = new int[navigatePages];
                int startNum = pageNum - navigatePages / 2;
                int endNum = pageNum + navigatePages / 2;
    
                if (startNum < 1) {
                    startNum = 1;
                    //(最前navigatePages页
                    for (int i = 0; i < navigatePages; i++) {
                        navigatepageNums[i] = startNum++;
                    }
                } else if (endNum > pages) {
                    endNum = pages;
                    //最后navigatePages页
                    for (int i = navigatePages - 1; i >= 0; i--) {
                        navigatepageNums[i] = endNum--;
                    }
                } else {
                    //所有中间页
                    for (int i = 0; i < navigatePages; i++) {
                        navigatepageNums[i] = startNum++;
                    }
                }
            }
        }
    
        /**
         * 计算前后页,第一页,最后一页
         */
        private void calcPage() {
            if (navigatepageNums != null && navigatepageNums.length > 0) {
                navigateFirstPage = navigatepageNums[0];
                navigateLastPage = navigatepageNums[navigatepageNums.length - 1];
                if (pageNum > 1) {
                    prePage = pageNum - 1;
                }
                if (pageNum < pages) {
                    nextPage = pageNum + 1;
                }
            }
        }
    
        /**
         * 判定页面边界
         */
        private void judgePageBoudary() {
            isFirstPage = pageNum == 1;
            isLastPage = pageNum == pages;
            hasPreviousPage = pageNum > 1;
            hasNextPage = pageNum < pages;
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328

    👯4.物理分页代码实现;

    1. LIMIT用法

    LIMIT出现在查询语句的最后,可以使用一个参数或两个参数来限制取出的数据。其中第一个参数代表偏移量:offset(可选参数),第二个参数代表取出的数据条数:rows。

    单参数用法
    当指定一个参数时,默认省略了偏移量,即偏移量为0,从第一行数据开始取,一共取rows条。

    /* 查询前5条数据 */
    SELECT * FROM Student LIMIT 5;
    双参数用法
    当指定两个参数时,需要注意偏移量的取值是从0开始的,此时可以有两种写法:
    
    • 1
    • 2
    • 3
    • 4
    /* 查询第1-10条数据 */
    SELECT * FROM Student LIMIT 0,10;
    /* 查询第11-20条数据 */
    SELECT * FROM Student LIMIT 10 OFFSET 10;
    
    • 1
    • 2
    • 3
    • 4

    2. 分页公式

    总页数计算
    在进行分页之前,我们需要先根据数据总量来得出总页数,这需要用到COUNT函数和向上取整函数CEIL,SQL如下:

    /* 获得数据总条数 */
    SELECT COUNT(*) FROM Student;
    /* 假设每页显示10条,则直接进行除法运算,然后向上取整 */
    SELECT CEIL(COUNT(*) / 10) AS pageTotal FROM Student;
    
    • 1
    • 2
    • 3
    • 4

    核心信息
    当前页:pageNumber
    每页数据量:pageSize
    在实际操作中,我们能够得到的信息有当前所在页以及每页的数据量,同时要注意一下是否超出了最大页数。以每页10条为例,则前三页的数据应为:

    第1页:第1~10条,SQL写法:LIMIT 0,10
    第2页:第11~20条,SQL写法:LIMIT 10,10
    第3页:第21~30条,SQL写法:LIMIT 20,10

    据此我们可以总结出,LIMIT所需要的两个参数计算公式如下:

    offset:(pageNumber - 1) * pageSize
    rows:pageSize

    扩展:8种MySQL分页方法总结

    方法1: 直接使用数据库提供的SQL语句

    语句样式: MySQL中,可用如下方法: 
    SELECT * FROM 表名称 LIMIT M,N。
    
    • 1
    • 2

    适应场景: 适用于数据量较少的情况(元组百/千级)。

    原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3)。Limit限制的是从结果集的M位置处取出N条输出,其余抛弃。

    方法2: 建立主键或唯一索引, 利用索引(假设每页10条)

    —语句样式: MySQL中,可用如下方法:
    代码如下:

    SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) LIMIT M
    
    • 1

    适应场景: 适用于数据量多的情况(元组数上万)。

    —原因: 索引扫描,速度会很快。有朋友提出因为数据查询出来并不是按照pk_id排序的,所以会有漏掉数据的情况,只能方法3。

    方法3: 基于索引再排序

    —语句样式: MySQL中,可用如下方法: 
    SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M。
    
    • 1
    • 2

    适应场景: 适用于数据量多的情况(元组数上万). 最好ORDER BY后的列对象是主键或唯一所以,使得ORDERBY操作能利用索引被消除但结果集是稳定的(稳定的含义,参见方法1)。

    原因: 索引扫描,速度会很快. 但MySQL的排序操作,只有ASC没有DESC(DESC是假的,未来会做真正的DESC,期待)。

    方法4: 基于索引使用prepare

    (第一个问号表示pageNum,第二个?表示每页元组数)

    —语句样式: MySQL中,可用如下方法:

    代码如下:

    PREPARE stmt_name FROM SELECT * FROM 表名称 WHERE id_pk > (*) ORDER BY id_pk
    ASC LIMIT M
    
    • 1
    • 2

    适应场景: 大数据量。

    原因: 索引扫描,速度会很快. prepare语句又比一般的查询语句快点。

    方法5:利用MySQL支持ORDER操作可以利用索引快速定位部分元组,避免全表扫描

    比如: 读第1000到1019行元组(pk是主键/唯一键)。

    代码如下:

    SELECT * FROM your_table WHERE pk>=1000 ORDER BY pk ASC LIMIT 0,20

    方法6: 利用"子查询/连接+索引"快速定位元组的位置,然后再读取元组. 道理同方法5

    如(id是主键/唯一键,蓝色字体时变量):

    利用子查询示例:

    代码如下:

    SELECT* FROMyour_table WHEREid <=
    (SELECTid FROMyour_table ORDER
    BYid descLIMIT (p a g e − 1 ) ∗ page-1)*page−1)∗pagesize ORDERBYid desc
    LIMIT $pagesize
    
    • 1
    • 2
    • 3
    • 4

    利用连接示例:

    代码如下:

    SELECT* FROMyour_table ASt1
    JOIN(SELECTid FROMyour_table ORDERBY
    id descLIMIT (p a g e − 1 ) ∗ page-1)*page−1)∗pagesize ASt2
    WHERE
    t1.id <= t2.id ORDERBYt1.id descLIMIT $pagesize;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方法7: 存储过程类(最好融合上述方法5/6)
    语句样式: 不再给出

    适应场景: 大数据量. 作者推荐的方法

    原因: 把操作封装在服务器,相对更快一些。

    方法8: 反面方法
    网上有人写使用 SQL_CALC_FOUND_ROWS。 没有道理,勿模仿 。

    基本上,可以推广到所有数据库,道理是一样的。但方法5未必能推广到其他数据库,推广的前提是,其他数据库支持ORDER BY操作可以利用索引直接完成排序。


    💼 扩展:Java使用注解实现服务端分页组件

    使用一下组件实现通过注解自动服务端分页查询

    我们在正常的使用的过程中如果没有太多的业务限制的条件得到情况下我们可以使用mybatis的注解来实现我们的分页的一个展示的情况:

    Mybatis-Plus
    PageHelper
    SpringBoot AOP
    
    • 1
    • 2
    • 3

    使用方法:在controller需要服务端分页的查询接口中使用 @Pagination 标注即可, 如下代码示例:


    @Pagination
    返回的值是
    Result****

    @RestController
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        private IUserService userService;
    
        /**
         * 列出所有用户
         * @return
         */
        @Pagination  
        @GetMapping("/list")
        public Result list(UserQueryReq query) {
            List<User> userList = userService.LisAll();
            return Result.ok(userList);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Demo 目录结构:

    在这里插入图片描述

    在这里插入图片描述
    这样就可以 进行访问了;
    此文来自此处;

  • 相关阅读:
    数字驱动的品牌重塑战略对您公司的重要意义
    解决拦截器抛出异常处理类的500状态码Html默认格式响应 !
    科学计算库 —— Matplotlib
    ByteTrack阅读思考笔记
    港联证券:a股b股区别?
    【IPython的使用技巧】
    Azure OpenAI 服务
    『力扣每日一题16』:存在重复元素
    if-else:if判断语句和执行语句之间相差1个时钟周期吗?并行执行吗?有优先级吗?
    Ubuntu install vncserver
  • 原文地址:https://blog.csdn.net/qq_42055933/article/details/126943866