怎么做网站架构图,做的网站乱码怎么搞,手机百度下载app,网站需要的技术一、前言
无论是自我学习中#xff0c;还是在工作中#xff0c;固然会遇到与前端搭配实现分页的功能#xff0c;发现有几种方式#xff0c;特此记录一下。
二、实现方式
2.1、分页功能直接交给前端实现
这种情况也是有的#xff0c;(根据业务场景且仅仅只能用于数据量…一、前言
无论是自我学习中还是在工作中固然会遇到与前端搭配实现分页的功能发现有几种方式特此记录一下。
二、实现方式
2.1、分页功能直接交给前端实现
这种情况也是有的(根据业务场景且仅仅只能用于数据量少的情况)。即后端不做任何数据的限制直接把全部数据返回给前端前端通过组件实现分页筛选等功能。请不要轻视该方式好处即只需要前后端交互一次。
2.2、数据库SQL的限制条件
即给搜索语句加上条件限制查询出来的数据个数。这里不同数据库可能sql语句写法不一样
mysql数据库是使用 limit n,m 从第n个开始往后取m个(注 不包括第n个数据)oracle数据库是使用 OFFSET n ROWS FETCH NEXT m ROWS ONLY 从第n行开始往后取m行(注 不包括第n行数据)
oracle的可以查看这篇文章oracle中将数据进行排序之后获取前几行数据的写法(rownum、fetch方式
2.3、使用List集合的截取功能实现
即将数据都查到内存中List集合在内存中找到要的数据。当然有人说这种方式还不如第二点但请具体情况具体分析有可能需求要的数据是从数据库中查询不到的需要将原始数据查到内存加工处理数据之后得到才能进行分页处理。(同理该方法只能根据需求且数据量少的情况)。
2.4、插件PageHelper
使用优秀的插件PageHelper真的很不错。
如果想详细了解PageHelper插件的可以访问如何使用分页插件
2.5、SpringData
SpringData我还没用过这里就不展开详细说明了后期如果业务使用到了会更新到这篇文章。
三、详细介绍
分页功能交给前端实现的这里就不展示了比较我们标题是后端实现分页功能。
3.1、数据库SQL的限制条件(limit,fetch)
sql语句
mysql写法
SELECT * FROM user2
LIMIT (#{pageNum} - 1) * #{pageSize}, #{pageSize}oracle写法
SELECT * FROM user2
OFFSET (#{pageNum} - 1) * #{pageSize} ROWS FETCH NEXT #{pageSize} ROWS ONLYDao层也可以叫Mapper层
Mapper
public interface PageTestDao {// 查数据// start从第几条开始向后要数据// pageSize一页多少条数据ListUserEntity getUserInfoByParams(Param(nameParam) String name,Param(start) int start,Param(pageSize) int pageSize);// 返回总条数int getCountByParams(Param(nameParam) String name);
}Mapper.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.csdn2.page_test.dao.PageTestDaosql idnameConditionwhereif testnameParam ! null and nameParam ! name like CONCAT(%, #{nameParam}, %)/if/where/sqlselect idgetUserInfoByParams resultTypecom.example.csdn2.page_test.entity.UserEntitySELECT * FROM user2include refidnameCondition /LIMIT #{start}, #{pageSize}/selectselect idgetCountByParams resultTypeintSELECT COUNT(*) FROM user2include refidnameCondition //select
/mapperService实现层
Service
RequiredArgsConstructor
public class PageTestService {private final PageTestDao pageTestDao;public PageResponseUserEntity getPageTest(UserRequest userRequest) {final ListUserEntity userEntityList pageTestDao.getUserInfoByParams(userRequest.getNameParam(),userRequest.getStart(), userRequest.getPageSize());final int total pageTestDao.getCountByParams(userRequest.getNameParam());return new PageResponse(userEntityList, total);}
}PageRequest
// 若分页的需求很多可把分页相关的参数抽出来
Data
public class PageRequest {// 第几页private int pageNum;// 每页几行数据private int pageSize;// 计算从第几行开始// 无论是limit、还是fetch 都是从某一行数据开始向后取 pageSize 条数据public int getStart() {if (pageNum 0) {return 0;}return (pageNum - 1) * pageSize;}
}
UserRequest
// 入参
EqualsAndHashCode(callSuper true)
Data
AllArgsConstructor
NoArgsConstructor
public class UserRequest extends PageRequest {// 搜索参数private String nameParam;
}
PageResponse
我这边只返回给前端查询的某页数据、和一共多少条数据如果前端需要知道可以分多少页需要前端自己计算一下当然后端其实也可以计算只需要添加一个参数和一个方法。
// 返回实体类因为分页需要返回总条数前端好做下标第几页
Data
AllArgsConstructor
public class PageResponseT {private ListT data;// 总条数private int total;
}
Controller层
RestController
RequestMapping(/pageTest)
public class PageTestController {private final PageTestService pageTestService;PostMapping(/page-test)public PageResponseUserEntity getPageTest(RequestBody UserRequest userRequest){return pageTestService.getPageTest(userRequest);}
}运行结果 3.2、使用List集合的截取功能(subList())实现
先看一下List的截取
// 从第几个下标到第几个下标
ListE subList(int fromIndex, int toIndex);public void test_ListSub() {// 创建模拟数据字符串 0-9的集合final ListString list IntStream.range(0, 10).mapToObj(i - i ).collect(Collectors.toList());System.out.println(list);// 截取从下标0到5的数据System.out.println(list.subList(0, 5));// 截取从下标3到5的数据System.out.println(list.subList(3, 5));}回归上述分页例子代码改成如下
dao层 不加 limit 条件 SELECT * FROM user2name like CONCAT(%, #{nameParam}, %)server层
public PageResponseUserEntity getPageTestByListSub(UserRequest userRequest) {final ListUserEntity allData pageTestDao.getUserInfoByParamsNoLimit(userRequest.getNameParam());// 下标开始final int start userRequest.getStart();// 下标结束final int end start userRequest.getPageSize();// 截取数据final ListUserEntity userEntityList allData.subList(start, end);final int total pageTestDao.getCountByParams(userRequest.getNameParam());return new PageResponse(userEntityList, total);}3.3、插件PageHelper
这是一个特别好用的分页插件。
其实PageHelper官网中有详细的文档以及例子https://pagehelper.github.io/docs/howtouse/
下面例子只是讲其与springboot结合的核心内容即快速开发
引入相关jar包坐标到pom.xml中
dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper-spring-boot-starter/artifactIdversion1.3.0/version
/dependency配置项目application.yml文件
#bybatis分页插件配置
pagehelper:helper-dialect: mysql #数据库reasonable: truesupport-methods-arguments: trueparams: countcountSql
3.3.1、案例1
前端所需要的数据就是数据库中表的数据
dao层的sql不需要加 Limit 条件(因为PageHelper会自动帮忙加的) SELECT * FROM user2name like CONCAT(%, #{nameParam}, %)service层修改如下 public PageInfoUserEntity getPageTest(UserRequest userRequest) {// 告诉PageHelper数据要从第几页每页多少条数据// 注一定要在select查询语句之前使用该方法否则无效PageHelper.startPage(userRequest.getPageNum(), userRequest.getPageSize());// 查询sqlfinal ListUserEntity userEntityList
pageTestDao.getUserInfoByParamsNotLimit(userRequest.getNameParam());// 返回dto使用插件自带的PageInforeturn new PageInfo(userEntityList);// 上述逻辑还可以简写为// return PageHelper.startPage(userRequest.getPageNum(), userRequest.getPageSize())// .doSelectPageInfo(() -
pageTestDao.getUserInfoByParamsNotLimit(userRequest.getNameParam()));}
结果如下与之前查询结果一致没问题
{total: 9,list: [{name: 4a,pwd: D},{name: 5a,pwd: E},{name: 6a,pwd: F}],pageNum: 2,pageSize: 3,size: 3,startRow: 4,endRow: 6,pages: 3,prePage: 1,nextPage: 3,isFirstPage: false,isLastPage: false,hasPreviousPage: true,hasNextPage: true,navigatePages: 8,navigatepageNums: [1,2,3],navigateFirstPage: 1,navigateLastPage: 3
}3.3.2、案例2
前端所需要的数据不只是数据库中表的数据还有一些需要Java代码逻辑计算得到的数据。那么上面的PageHelper.startPage(userRequest.getPageNum(), userRequest.getPageSize());就失效了。 public PageInfoUserEntityResp getPageTest(UserRequest userRequest) {//分页类的创建PageInfoUserEntityResp res new PageInfo();// 查询sqlListUserEntity userEntityList
pageTestDao.getUserInfoByParamsNotLimit(userRequest.getNameParam());//对userEntityList中的数据进行了一些算法操作改变了原来从数据库中查询到的数据//或者以什么排序等等操作最终得到resultListUserEntityResp result ..... ; int total result.size();//注意:这里的start,end是需要通过userRequest.getPageNum(), userRequest.getPageSize()//计算得到的Double index (Double)Math.ceil(total * 1.0 / userRequest.getPageSize());if (index.intValue()userRequest.getPage()){start (userRequest.getPage() - 1) * userRequest.getPageSize();end Math.min(start userRequest.getPageSize(), total);} else{start 0;end total;}ListInterfaceConfirmTimeResp pageList result.subList(start, end);//将分页相关对象的属性设置res.setList(pageList);res.setTotal(result.size());res.setPageNum(userRequest.getPage());res.setPageSize(userRequest.getPageSize());res.setPages((int)Math.ceil(result.size()*1.0/userRequest.getPageSize()));return res;}
这是通过PageHelp插件中的PageInfo类和List中的subList()方法实现的其实一般这种情况用的也是比较多的。
3.3.3、为什么PageHelp插件优秀
为什么说该插件很优秀呢查看PageInfo的返回参数核心内容 // 当前页private int pageNum;// 每页的数量private int pageSize;// 当前页的数量private int size;// 总记录数private long total;// 总页数private int pages;// 结果集private ListT 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 navigateFirstPage;// 导航条上的第一页的页码private int navigateLastPage;查看PageHelper执行了什么sql语句 3.3.4、spring结合mybatis整合PageHelper框架
Spring整合导入pom.xml
!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper --dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion5.1.2/version/dependency
配置项目配置文件(我在spring和mybatis整合的配置文件中配置的如果在mybatis核心配置文件中配置百度一下)
bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean!-- 依赖数据源 --property namedataSource refdataSource/!-- 注册加载myBatis映射文件 --property namemapperLocationsarrayvalueclasspath*:com/yyz/mapper/*Mapper.xml/value/array/property!-- PageHelper分页配置 --property namepluginsarraybean classcom.github.pagehelper.PageInterceptorproperty nameproperties!--使用下面的方式配置参数一行配置一个后面会有所有的参数介绍 --value!--helperDialect属性来指定分页插件使用哪种方言。--helperDialectmysql!--分页合理化参数设置为true时pageNum0时会查询第一页,pageNumpages(超过总数时),会查询最后一页。--reasonabletrue!--为了支持startPage(Object params)方法增加了该参数来配置参数映射用于从对象中根据属性名取值可以配置 pageNum,pageSize,count,pageSizeZero,reasonable--paramscountcountSql!--支持通过Mapper接口参数来传递分页参数默认值false分页插件会从查询方法的参数值中自动根据上面 params 配置的字段中取值查找到合适的值时就会自动分页。--supportMethodsArgumentstrue!--默认值为 false。设置为 true 时允许在运行时根据多数据源自动识别对应方言的分页--autoRuntimeDialecttrue/value/property/bean/array/property!-- 给数据库实体起别名 --property nametypeAliasesPackage valuecom.yyz.entity;//bean
以上就是Java实现分页的几种方式希望对你有所帮助如果有其它方式可以在评论区留言 参考文章java中实现分页的常见几种方式_java 分页-CSDN博客