浅谈PageHelper插件分页实现原理及大数据量下SQL查询效率问题解决

https://blog.csdn.net/baidu_38083619/article/details/82463058

浅谈PageHelper插件分页实现原理及大数据量下SQL查询效率问题解决

2018年09月06日 17:25:19 岁月安然 阅读数:2058

前因:项目一直使用的是PageHelper实现分页功能,项目前期数据量较少一直没有什么问题。随着业务扩增,数据库扩增PageHelper出现了明显的性能问题。几十万甚至上百万的单表数据查询性能缓慢,需要几秒乃至十几秒的查询时间。故此特地研究了一下PageHelper源码,查找PageHelper分页的实现方式。

一段较为简单的查询,跟随debug开始源码探寻之旅。

 
  1. public ResultContent select(Integer id) {

  2. Page<Test> blogPage = PageHelper.startPage(1,3).doSelectPage( () -> testDao.select(id));

  3. List<Test> test = (List<Test>)blogPage.getResult();

  4. return new ResultContent(0, "success", test);

  5. }

主要保存由前端传入的pageNum(页数)、pageSize(每页显示数量)和count(是否进行count(0)查询)信息。

这里是简单的创建page并保存当前线程的变量副本心里,不做深究。

 
  1. public static <E> Page<E> startPage(int pageNum, int pageSize) {

  2. return startPage(pageNum, pageSize, DEFAULT_COUNT);

  3. }

  4.  
  5. public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count) {

  6. return startPage(pageNum, pageSize, count, (Boolean)null, (Boolean)null);

  7. }

  8.  
  9. public static <E> Page<E> startPage(int pageNum, int pageSize, String orderBy) {

  10. Page<E> page = startPage(pageNum, pageSize);

  11. page.setOrderBy(orderBy);

  12. return page;

  13. }

  14.  
  15. public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {

  16. Page<E> page = new Page(pageNum, pageSize, count);

  17. page.setReasonable(reasonable);

  18. page.setPageSizeZero(pageSizeZero);

  19. Page<E> oldPage = getLocalPage();

  20. if(oldPage != null && oldPage.isOrderByOnly()) {

  21. page.setOrderBy(oldPage.getOrderBy());

  22. }

  23.  
  24. setLocalPage(page);

  25. return page;

  26. }

开始执行真正的select语句

 
  1. public <E> Page<E> doSelectPage(ISelect select) {

  2. select.doSelect();

  3. return this;

  4. }

进入MapperProxy类执行invoke方法获取到方法名称及参数值

 
  1. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

  2. if (Object.class.equals(method.getDeclaringClass())) {

  3. try {

  4. return method.invoke(this, args);

  5. } catch (Throwable t) {

  6. throw ExceptionUtil.unwrapThrowable(t);

  7. }

  8. }

  9. final MapperMethod mapperMethod = cachedMapperMethod(method);

  10. return mapperMethod.execute(sqlSession, args);

  11. }

接着是MapperMethod方法执行execute语句,判断是增、删、改、查。判断返回值是多个,进入executeForMany方法

 
  1. public Object execute(SqlSession sqlSession, Object[] args) {

  2. Object result;

  3. if (SqlCommandType.INSERT == command.getType()) {

  4. Object param = method.convertArgsToSqlCommandParam(args);

  5. result = rowCountResult(sqlSession.insert(command.getName(), param));

  6. } else if (SqlCommandType.UPDATE == command.getType()) {

  7. Object param = method.convertArgsToSqlCommandParam(args);

  8. result = rowCountResult(sqlSession.update(command.getName(), param));

  9. } else if (SqlCommandType.DELETE == command.getType()) {

  10. Object param = method.convertArgsToSqlCommandParam(args);

  11. result = rowCountResult(sqlSession.delete(command.getName(), param));

  12. } else if (SqlCommandType.SELECT == command.getType()) {

  13. if (method.returnsVoid() && method.hasResultHandler()) {

  14. executeWithResultHandler(sqlSession, args);

  15. result = null;

  16. } else if (method.returnsMany()) {

  17. result = executeForMany(sqlSession, args);

  18. } else if (method.returnsMap()) {

  19. result = executeForMap(sqlSession, args);

  20. } else {

  21. Object param = method.convertArgsToSqlCommandParam(args);

  22. result = sqlSession.selectOne(command.getName(), param);

  23. }

  24. } else if (SqlCommandType.FLUSH == command.getType()) {

  25. result = sqlSession.flushStatements();

  26. } else {

  27. throw new BindingException("Unknown execution method for: " + command.getName());

  28. }

  29. if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {

  30. throw new BindingException("Mapper method '" + command.getName()

  31. + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");

  32. }

  33. return result;

  34. }

这个方法开始调用SqlSessionTemplate、DefaultSqlSession等类获取到Mapper.xml文件的SQL语句

 
  1. private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {

  2. List<E> result;

  3. Object param = method.convertArgsToSqlCommandParam(args);

  4. if (method.hasRowBounds()) {

  5. RowBounds rowBounds = method.extractRowBounds(args);

  6. result = sqlSession.<E>selectList(command.getName(), param, rowBounds);

  7. } else {

  8. result = sqlSession.<E>selectList(command.getName(), param);

  9. }

  10. // issue #510 Collections & arrays support

  11. if (!method.getReturnType().isAssignableFrom(result.getClass())) {

  12. if (method.getReturnType().isArray()) {

  13. return convertToArray(result);

  14. } else {

  15. return convertToDeclaredCollection(sqlSession.getConfiguration(), result);

  16. }

  17. }

  18. return result;

  19. }

 开始进入PageHelper的真正实现,Plugin通过实现InvocationHandler进行动态代理获取到相关信息

 
  1. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

  2. try {

  3. Set<Method> methods = signatureMap.get(method.getDeclaringClass());

  4. if (methods != null && methods.contains(method)) {

  5. return interceptor.intercept(new Invocation(target, method, args));

  6. }

  7. return method.invoke(target, args);

  8. } catch (Exception e) {

  9. throw ExceptionUtil.unwrapThrowable(e);

  10. }

  11. }

PageInterceptor 实现Mybatis的Interceptor 接口,进行拦截

 
  1. public Object intercept(Invocation invocation) throws Throwable {

  2. try {

  3. Object[] args = invocation.getArgs();

  4. MappedStatement ms = (MappedStatement)args[0];

  5. Object parameter = args[1];

  6. RowBounds rowBounds = (RowBounds)args[2];

  7. ResultHandler resultHandler = (ResultHandler)args[3];

  8. Executor executor = (Executor)invocation.getTarget();

  9. CacheKey cacheKey;

  10. BoundSql boundSql;

  11. if(args.length == 4) {

  12. boundSql = ms.getBoundSql(parameter);

  13. cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);

  14. } else {

  15. cacheKey = (CacheKey)args[4];

  16. boundSql = (BoundSql)args[5];

  17. }

  18.  
  19. this.checkDialectExists();

  20. List resultList;

  21. if(!this.dialect.skip(ms, parameter, rowBounds)) {

  22. if(this.dialect.beforeCount(ms, parameter, rowBounds)) {

  23. Long count = this.count(executor, ms, parameter, rowBounds, resultHandler, boundSql);

  24. if(!this.dialect.afterCount(count.longValue(), parameter, rowBounds)) {

  25. Object var12 = this.dialect.afterPage(new ArrayList(), parameter, rowBounds);

  26. return var12;

  27. }

  28. }

  29.  
  30. resultList = ExecutorUtil.pageQuery(this.dialect, executor, ms, parameter, rowBounds, resultHandler, boundSql, cacheKey);

  31. } else {

  32. resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);

  33. }

  34.  
  35. Object var16 = this.dialect.afterPage(resultList, parameter, rowBounds);

  36. return var16;

  37. } finally {

  38. this.dialect.afterAll();

  39. }

  40. }

转到ExecutorUtil抽象类的pageQuery方法

 
  1. public static <E> List<E> pageQuery(Dialect dialect, Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql, CacheKey cacheKey) throws SQLException {

  2. if(!dialect.beforePage(ms, parameter, rowBounds)) {

  3. return executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, boundSql);

  4. } else {

  5. parameter = dialect.processParameterObject(ms, parameter, boundSql, cacheKey);

  6. String pageSql = dialect.getPageSql(ms, boundSql, parameter, rowBounds, cacheKey);

  7. BoundSql pageBoundSql = new BoundSql(ms.getConfiguration(), pageSql, boundSql.getParameterMappings(), parameter);

  8. Map<String, Object> additionalParameters = getAdditionalParameter(boundSql);

  9. Iterator var12 = additionalParameters.keySet().iterator();

  10.  
  11. while(var12.hasNext()) {

  12. String key = (String)var12.next();

  13. pageBoundSql.setAdditionalParameter(key, additionalParameters.get(key));

  14. }

  15.  
  16. return executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, pageBoundSql);

  17. }

  18. }

在抽象类AbstractHelperDialect的getPageSql获取到对应的Page对象 

 
  1. public String getPageSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey pageKey) {

  2. String sql = boundSql.getSql();

  3. Page page = this.getLocalPage();

  4. String orderBy = page.getOrderBy();

  5. if(StringUtil.isNotEmpty(orderBy)) {

  6. pageKey.update(orderBy);

  7. sql = OrderByParser.converToOrderBySql(sql, orderBy);

  8. }

  9.  
  10. return page.isOrderByOnly()?sql:this.getPageSql(sql, page, pageKey);

  11. }

进入到MySqlDialect类的getPageSql方法进行SQL封装,根据page对象信息增加Limit。分页的信息就是这么拼装起来的

 
  1. public String getPageSql(String sql, Page page, CacheKey pageKey) {

  2. StringBuilder sqlBuilder = new StringBuilder(sql.length() + 14);

  3. sqlBuilder.append(sql);

  4. if(page.getStartRow() == 0) {

  5. sqlBuilder.append(" LIMIT ? ");

  6. } else {

  7. sqlBuilder.append(" LIMIT ?, ? ");

  8. }

  9.  
  10. return sqlBuilder.toString();

  11. }

将最后拼装好的SQL返回给DefaultSqlSession执行查询并返回

 
  1. public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {

  2. try {

  3. MappedStatement ms = configuration.getMappedStatement(statement);

  4. return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);

  5. } catch (Exception e) {

  6. throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);

  7. } finally {

  8. ErrorContext.instance().reset();

  9. }

至此整个查询过程完成,原来PageHelper的分页功能是通过Limit拼接SQL实现的。查询效率低的问题也找出来了,那么应该如何解决。

首先分析SQL语句,limit在数据量少或者页数比较靠前的时候查询效率是比较高的。(单表数据量百万进行测试)

select * from user where age = 10 limit 1,10;结果显示0.43s

当where条件后的结果集较大并且页数达到一个量级整个SQL的查询效率就十分低下(哪怕where的条件加上了索引也不行)。

select * from user where age = 10 limit 100000,10;结果显示4.73s

那有什么解决方案呢?mysql就不能单表数据量超百万乃至千万嘛?答案是NO,显然是可以的。

SELECT a.* FROM USER a
INNER JOIN 
    (SELECT id FROM USER WHERE age = 10 LIMIT 100000,10) b 
ON a.id = b.id;

结果0.53s

完美解决了查询效率问题!!!其中需要对where条件增加索引,id因为是主键自带索引。select的字段越多,字段数据量越大,速度就越慢,所以采用查询主键字段后进行关联大幅度提升了查询效率。

PageHelper想要优化需要在拦截器的拼接SQL部分进行重构,由于博主能力有限暂未实现。能力较强的读者可以自己进行重构

附上PageHelper的git地址:https://github.com/pagehelper/Mybatis-PageHelper/

 

java分页的实现,插件PageHelper的使用及原理

1.9万

如果你只希望知道PageHelper的用法,直接去github查看官网文档 Mybatis-PageHelper. 1.关于分页。 在web项目中,分页是一个常见的功能。在我刚学完javaweb的...来自: qq_25498677

PageHelper分页插件源码及原理剖析

 3.5万

摘要: com.github.pagehelper.PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件。 PageHelper是一款好用的开源免费的Mybatis第三...来自: Optimistic

浅析pagehelper分页原理

 4476

写的第一篇文章,不足之处,请多提宝贵意见,谢谢。之前项目一直使用的是普元框架,最近公司项目搭建了新框架,主要是由公司的大佬搭建的,以springboot为基础。为了多学习点东西,我也模仿他搭了一套自己...来自: 王大锤的博客

Mybatis使用pageHelper分页插件原理

 2.9万

首先在Mybatis的配置文件 SqlMapConfig.xml中配置PageHelper插件 xml version="1.0" encoding="UTF-8" ?> DOCTYPE c...来自: jaryle的专栏

 

mybatis使用PageHelper分页插件原理

 4605

1、官方介绍: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md 官方介绍文档中已经说明了详细的配...来自: lh87270202的博客

pageHelper分页插件实现原理及使用方法

 5913

插件官方网站:https://github.com/pagehelper/Mybatis-PageHelper/tree/master/src/main/java/com/github/pagehel...来自: summerwindl的博客

MyBatis拦截器分页原理及PageHelper分页插件教学

 2517

闲来无事,特地整理了一下MyBatis拦截器实现分页的原理。地球人应该都知道要利用JDBC对数据库进行操作,就需要一个statement对象,MyBatis也是如此。MyBatis在执行sql语句前会...来自: jant的博客

Mybatis分页插件——PageHelper使用与原理介绍

 554

推荐一款Mybatis分页插件 以前也写过一篇博文介绍Mybatis的插件,以及如何通过...来自: itcats_cn的博客

使用pagehelper分页插件详细教程

 2931

pagehelper是一个简单的实现分页技巧的插件我们要使用这个插件无可避免的需要引用它的jar包,你可以从下面的地址中下载最新版本的 jar 包 1:https://oss.sonatype....来自: 醉梦无生的博客

 

PageHelper分页使用

 5054

使用分页插件的好处: 在编写Web后台代码时,分页是必不可少的,当然最通常的思路是在Sql中使用分页关键字来进行分页。在实际开发中,更多的是使用分页插件来减少代码冗杂,使编码更加清晰 思路:分页控...来自: ALearrring的博客

文章热词

SQL Server SQL Server视频教程 SQL Server培训 SQL Server培训套餐 SQL Server教程

相关热词

bootstrap分页插件客户端分页 c# sql分页 bootstrap表单分页插件 js 分页插件bootstrap bootstrap js分页插件 SmartContract插件配置 VS插件LineCounter

MySQL 百万级分页优化(Mysql千万级快速分页)

 1.3万

一般刚开始学SQL的时候,会这样写 SELECT * FROM table ORDER BY id LIMIT 1000, 10; 但在数据达到百万级的时候,这样写会慢死 SELECT * FR...来自: liDE博客

eson_15关注

eson_15

 

215篇文章

排名:611

 

isea533关注

isea533

 

274篇文章

排名:523

 

蜗牛201关注

蜗牛201

 

80篇文章

排名:8000+

 

一杯甜酒关注

一杯甜酒

 

1016篇文章

排名:210

 

SpringBoot Mybatis PageHelper分页插件的两种用法(二)

 716

与第一种方式的区别  1、替换pom.xml中的依赖  dependency> groupId>com.github.pagehelpergroupId> artif...来自: 你可路过我的倾城时光、

easyUI前端分页与后台分页总结

 1.2万

分页往往是依附于数据表格的,所以我们就使用的是easyui的datagrid组件,来开启pagination分页组件,为了方便,我们使用js实现。        表格显示初始化 ...来自: 小老弟的博客

mybatis的分页插件pagehelper-fix使用、数据库分页查询模板sql、总结mysql与oracle语句的区别

 561

数据库查询分页模板sql语句来自: 中年闰土的博客

 

分页插件pagehelper ,在sql server 中是怎么配置的

 1684

&amp;lt;configuration&amp;gt;     &amp;lt;plugins&amp;gt;          &amp;lt;!-- com.github.pagehelper...来自: ysn135的博客

分页插件SQLServer查询语句转换成分页语句

 2310

分页插件地址:https://github.com/pagehelper/Mybatis-PageHelper 本次演示使用jar包版本:http://repo1.maven.org/maven2/c...来自: Master-Pan的专栏

使用mybatis分页插件PageHelper5.0.0遇到的问题总结

 2.2万

最近在学习一个项目,就是网上流传的taotao-shop,学到使用分页插件的时候,突然卡主了,异常,我的天,要知道这种整合项目中出现异常,要不就是jar包冲突,要不就是配置文件哪个地方不对,这样找起来...来自: Appleyk的专栏

spring boot学习3之mybatis+druid+事务+PageHelper分页插件+sql打印插件整合

 8240

上篇博文学习了spring boot下对于配置文件的读取。这篇博文学习下spring boot怎样整合mybatis,并使用指定的数据库连接池,事务,分页插件的整合。       本例子用的是mave...来自: 夢の殇

PageHelper分页插件的原理及其使用

 166

PageHelper分页插件原理 PageHelper本身是一个物理分页插件,实际原理就是修改最后的执行sql,增加相应的分页内容,是基于拦截器实现的。 例如,首先你配置了PageHelper的P...来自: 开发猫

 

PageHelper 分页原理

 94

1 分页内容存储 2 mybatis Interceptor 在使用PageHelper的时候我很想知道它的分页信息存储位置,似乎是存在当前请求线程中。 分页信息存储 作者的例子https://...来自: dang7758的博客

Mybatis插件原理和PageHelper结合实战分页插件

 2530

今天和大家分享下mybatis的一个分页插件PageHelper,在讲解PageHelper之前我们需要先了解下mybatis的插件原理。PageHelper 的官方网站:https://git...来自: fengqilove520的专栏

下载 

PageHelper实现前端分页

06-02

使用Mabatis中的分页插件PageHelper实现分页功能,此插件使用简单加快项目的开发效率。

Mybatis 分页插件pagehelper示例

 119

pom.xml文件中,引入相关jar包&amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&qu...来自: lzgsea的博客

mybatis pagehelper分页插件使用

 1.4万

mybatis pagehelper来自: 我爱奔跑的浮云_的博客

原来血糖高真正的元凶是它!你知道吗?鑫丰杰 · 顶新

项目中PageHelper分页插件的使用实例(SSM)

 142

分页(英语:Paging),是一种操作系统里存储器管理的一种技术,可以使计算机的主存可以使用存储在辅助存储器中的数据。操作系统会将辅助存储器(通常是磁盘)中的数据分区成固定大小的区块,称为“页”(pa...来自: fz13768884254的博客

sqlsever2012使用pageHelper分页插件报错解决

 95

错误信息如下: org.springframework.jdbc.UncategorizedSQLException: ### Error querying database. Cause: co...来自: 大碍桃花开

分页插件pageHelper使用

 631

1.pom包加入插件依赖   &amp;lt;!-- 分页助手 --&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;...来自: ws346348183的博客

PageHelper5.0在oracle数据库中使用

 3790

原理:         pageHelper会使用ThreadLocal获取到同一线程中的变量信息,各个线程之间的Threadlocal不会相互干扰,也就是Thread1中的ThreadLocal1之...来自: PSY_God的博客

mybatis使用PageHelper实现分页的技术

 1.3万

1、如果你也在用Mybatis,建议尝试该分页插件,这个一定是最方便使用的分页插件。 该插件目前支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库...来自: 刷刷刷

原来血糖高真正的元凶是它!你知道吗?鑫丰杰 · 顶新

PageHelper 实现原理

 5352

PageHelper 原理来自: 彻底拆分,一切可控!

2017.12.14 Mybatis物理分页插件PageHelper的使用(一)

 1620

参考来自: http://www.360doc.com/content/15/0728/15/12642656_487954693.shtml https://www.cnblogs.com/di...来自: 七月流火滋滋滋

spring boot 中分页插件PageHelper的使用

 331

PageHelper做的是什么呢?它封装了分页的后台部分,将你的语句改装成了一个分页查询的sql。它的优缺点: 优点:封装分页sql,使我们不需要每个地方都去写分页的查询语句;同时,使我们selec...来自: 三三良良

【MyBatis】MyBatis分页插件PageHelper的使用

 4.3万

好多天没写博客了,因为最近在实习,大部分时间在熟悉实习相关的东西,也没有怎么学习新的东西,这周末学习了MyBatis的一个分页插件PageHelper,虽然没有那么的强大(我在最后会说明它的缺点),但...来自: 倪升武的博客

Mybatis分页实现的方法(拦截器+pageHelper

 187

一、拦截器实现 1.原理 在mybatis 运行过程中拦截执行对象,获得sql信息,将分页信息添加到sql语句中,然后放行mybatis的执行过程 2.了解一点mybatis源码 首先我们需要...来自: oraly的博客

陈小春坦言:这游戏不充钱都能当全服大哥,找到充值入口算我输!贪玩游戏 · 顶新

智能将SqlServer的查询语句转换为分页语句

 5463

主要用到了jsqlparser,前面有篇博客介绍过: JAVA - Sql解析工具jsqlparser简单使用 为了给Mybatis分页插件增加对sqlserver的支持,专门写了这样一个独...来自: 偶尔记一下

基于Mybatis分页插件PageHelper实现分页功能

 4436

使用PageHelper插件实现分页功能分页的功能几乎是所有项目必备的功能,在SSM(spring 、springmvc、mybatis)组织的项目中如何实现分页呢? 下面介绍一种基于mybatis...来自: 住在城北的猫

【JAVA秒会技术之玩转高效分页】EasyUI + PageHelper实现分页

 2073

EasyUI + PageHelper实现分页 一、EasyUI页面分页 页面逻辑:页面初始化时,通过jquery easyui的DataGrid(数据表格)的url属性异步加载,返回指定的json格...来自: qq296398300的博客

下载 

PageHelper分页实例(带页面)

11-03

PageHelper分页实例(带页面),基于Spring+Mybatis+SpringMVC后台与前台分页展示

Mybatis分页插件-PageHelper的使用

 7.2万

Mybatis分页插件-PageHelper的使用怎样配置mybatis这里就不提了,我来说说我配置这个分页插件的过程吧。下载JAR包分页插件pagehelper.jar:https://oss.so...来自: 新涯特

拒绝装修猫腻!

博洛尼家装一线建材限量1折抢,买贵差价5倍还,保价120天!限北京

使用mybatis分页插件PageHelper5.1.2遇到的问题

 3017

添加PageHelper依赖 在maven项目的pom.xml文件里添加依赖: com.github.pagehelper pagehelper 5.1.2 配置SqlMa...来自: 简简单单的专栏

oracle 大数据量分页查询

 3227

(一)分页实现及性能 Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用。 分页查询格式: SELECT * FROM ( SELECT A.*, ROWNUM RN ...来自: minxwy的专栏

Springboot集成PageHelper插件实现分页

 917

Springboot集成PageHelper插件实现分页 第一步:增加jar包 &amp;lt;!-- 分页插件 --&amp;gt; &amp;lt;dependency&a...来自: 昆仔的博客

【转】大数据量分页查询方法

 869

本文旨在介绍一种对数据库中的大数据量表格进行分页查询的实现方法,该方法对应用服务器、数据库服务器、查询客户端的cpu和内存占用都较低,查询速度较快,是一个较为理想的分页查询实现方案。  1.问题的...来自: 大厨的专栏

MyBatis扩展-PageHelpler分页-批量处理-调用存储过程

 154

一、PageHelpler分页插件使用步骤: • 1、导入相关包pagehelper-x.x.x.jar 和 jsqlparser-0.9.5.jar。 • 2、在MyBatis全局配置文件中配置...来自: liberty12345678的专栏

 

MySQL高效分页-mybatis插件PageHelper改进

 3932

MySQL分页在表比较大的时候,分页就会出现性能问题,MySQL的分页逻辑如下:比如select * from user limit 100000,10它是先执行select * from user ...来自: weixin_36666151的博客

Mybatis分页插件 - PageHelper很好很强大,转载

 3010

1.引入分页插件 1.引入Jar包 如果你想使用本项目的jar包而不是直接引入类,你可以在这里下载各个版本的jar包(点击Download下的jar即可下载) https:/...来自: callmedarcy的博客

推荐好用的分页插件PageHelper

 424

轻松解决分页问题 老板再也不会觉得你工作效率慢使用PageHelper需要引入jar包。 com.github.pagehelper pagehelper 4.2.1 ...来自: 董硕的博客

为什么pageHelper超过最大页数后还会返回数据

 1.2万

问题描述:在微服务里面做查询接口,用到pageHelper,数据库只有8行数据,pageNum=1&pageSize=10,pageNum=2&pageSize=10,pageNum=3&pageSi...来自: Lovnx

pageHelper实现分页

 1.2万

最近做的一个项目在持久层我们采用的是Mybatis今天完成了商品列表的分页查询的功能,这篇博客我分享一下如何采用pageHelper的插件实现分页。mybatis的应用,最大的好处就在于我们可以更加方...来自: 致力于顶级java全栈工程师

傲游5云浏览器,一键拦截所有网页广告,轻松云同步所有文件!

 

Mybatis基于MySql分页插件PageHelper的使用

 765

一、Mybatis框架的分页插件PageHelper是目前我用过的最简单的分页插件了,该插件目前支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库...来自: justdoit_potato的博客

颈椎病怎么能治好,看我用Python对接

 32411

盘点现代社会中年轻人常见病例,很显然“颈椎病”一定是排在第一的。年轻人长期伏案工作、长期面对电脑、长期低头玩手机等,这些行为都是导致颈椎病的发病率急剧升高的最基本原因。但是,还有一个危险因素就潜伏在我...来自: john_dung的博客

史上最简单的 SpringCloud 教程 | 终章

 1262924

转载请标明出处: http://blog.csdn.net/forezp/article/details/70148833 本文出自方志朋的博客 错过了这一篇,你可能再也学不会 Sp...来自: 方志朋的专栏

基于XMLHttpRequest对象的ajax拦截

 3240

导读     在web前端开发中,我们经常会与后端进行数据的交互,ajax即是其中的一种方式;它是通过XMLHttpRequest(简称xhr)对象进行的http请求;在发起请求时,首先会创建一个xh...来自: 幽幽小春

整理了10个干净、好用的BT、磁力链搜索网站给大家

 135559

现在越来越流行在线看视频了,但是对于我得收藏癖爱好者,还是希望可以有比较好的资源网站的,尤其是种子、磁力链网站。所以就整理了一份干净、好用的TOP10出来: 先推荐一个下载磁力链的工具: 马...来自: YXAPP的技术分享

webgl第26课-在图形上贴图片

 7149

需要电子档书籍可以Q群:828202939   希望可以和大家一起学习、一起进步!! 上一节课我们学习了  颜色与纹理中--彩色三角形 这一节课我们将学习  颜色与纹理中-在图像上贴图片 实...来自: 谷子的博客

Postman 使用方法详解

 200378

一、Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具。今天给大家...来自: fxbin123的博客

Webstorm 最新激活码 多种破解方式(持续更新...)

 99415

方法:License server 注册 安装完成,打开Webstorm,在弹出的License Activation窗口中选择“License server”,在输入框输入下面的网址:  htt...来自: 老妖儿的博客

webgl第30课-用键盘来改变视点

 7364

需要电子档书籍可以Q群:828202939   希望可以和大家一起学习、一起进步!! 所有的课程源代码在我上传的资源里面,本来想设置开源,好像不行!博客和专栏同步! 如有错别字或有理解不到位的地方...来自: 谷子的博客

很黄很暴力的十个网站

 93042

13岁的北京学生张某,在去年12月27日19时新闻联播一则关于净化网络视听的新闻里,接受采访时说的话激起了轩然大波:“上次我上网查资料,突然弹出来一个网页,很黄很暴力,我赶紧把它给关了。”这个片段被C...来自: Kinb_huangwei的专栏

webstorm 2018 激活破解方法大全

 708406

webstorm 作为最近最火的前端开发工具,也确实对得起那个价格,但是秉着勤俭节约的传统美德,我们肯定是能省则省啊。 方法一:(更新时间:2018/4/8)v3.3 注册时,在打开的Lice...来自: 唐大帅的编程之路

最新迅雷“应版权方要求,文件无法下载”的解决办法

 242291

迅雷下载有的电影电视剧的时候会出现:应版权方要求,文件无法下载,或者显示迅雷任务包含违规内容 无法继续下载。这个是因为版权方和迅雷公司交涉,迅雷公司通过技术手段阻止了迅雷任务的下载,比如下载最近的《人...来自: 徐奕的专栏

js常用的正则验证

 4698

一、手机号码验证 (一)中国电信号段: 133、149、153、173、177、180、181、189、199 (二)中国联通号段 130、131、132、145、155、156、166、17...来自: 幽幽小春

pyCharm最新2019激活码

 1296675

本教程对jetbrains全系列可用例:IDEA、WebStorm、phpstorm、clion等 因公司的需求,需要做一个爬取最近上映的电影、列车号、航班号、机场、车站等信息,所以需要我做一个爬虫...来自: 昌昌

刚发布!Python2 月再夺语言榜首! 一二线城市月薪增长迅猛!

 21863

几年前Python在国内还只是一门小众语言,但从2011开始到现在,Python的百度搜索指数翻了10倍,Python究竟为什么可以发展如此迅猛?                          ...来自: CSDN学院

Sqoop导入与导出数据

 524

一.导入数据 在Sqoop中,&quot;导入&quot;指的是从非大数据集群(RDBMS)向大数据集群(HDFS,HBASE,HIVE)中传输数据,即import。 1.RDBMS到HDFS ...来自: myllxy的博客

微服务Springcloud超详细教程+实战(八)

 29010

如在文档中遇到什么问题请联系作者 QQ:1172796094 本人正在找深圳Java实习工作,求大佬带飞 —————————————————————————————————————— 消费者从Eure...

微服务Springcloud超详细教程+实战(十)

 25765

本人正在找深圳Java实习工作,求大佬带飞 QQ:1172796094 如在文档中遇到什么问题请联系作者 —————————————————————————————————————— 服务消费者 获...

利用k-means算法对点云数据进行目标分割,提取其中的建筑物、房屋等

 4226

原始点云数据在CloudCompare的显示如下: 点云原始数据以及提取出的房屋道路等数据下载地址:https://download.csdn.net/download/qq_39343904/...来自: qq_39343904的博客

java缓冲区

 21326

1 缓冲区的分类 ByteBuffer CharBuffer ShortBuffer IntBuffer LongBuffer FloatBuffer DoubleBuffer 2 ByteBuffe...来自: weixin_43694144的博客

FFmpeg详解及常用命令使用

 23663

FFMPEG简介 FFMPEG堪称自由软件中最完备的一套多媒体支持库,它几乎实现了所有当下常见的数据封装格式、多媒体传输协议以及音视频编解码器,提供了录制、转换以及流化音视频的完整解决方案。市面上使...来自: qq_26464039的博客

Kotlin实战(三)

 3984

Kotlin实战(三) 一、元组 1.1、二元元组 data class Pair&amp;amp;amp;lt;out A, out B&amp;amp;amp;gt;( public va...来自: zping0808的博客

安装和激活Office 2019

 40959

有条件请支持正版!相比费尽力气找一个可能不太安全的激活工具,直接买随时随地更新的Office 365确实是最好的办法。暂时没有经济实力的,可以看看这篇文章。 下载OTP工具 首先到Office Too...来自: 过了即是客

日志框架NLog简单配置使用

 26433

NLog日志管理工具 一、获得NLog 这里介绍最简单的获得方式 1.管理NuGet程序包 2.在打开页面中搜索NLog并进行安装,安装NLog和NLog.Config 3.安装成功后我们可以看到...来自: Maybe_ch的博客

webgl第27课-三维空间-不同位置的三角形

 7500

需要电子档书籍可以Q群:828202939   希望可以和大家一起学习、一起进步!! 上一节课我们学习了  颜色与纹理中--在图像上贴图片 这一节课我们将学习  三维空间-不同位置的三角形 在学...来自: 谷子的博客

史上最全Java面试题(带全部答案)

 136347

今天要谈的主题是关于求职,求职是在每个技术人员的生涯中都要经历多次。对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面细致面试题将帮助我们减少许多麻烦。在跳槽季来临之前,特地做这...来自: 林老师带你学编程

webgl第28课-三维空间之加入旋转矩阵的三角形

 7586

需要电子档书籍可以Q群:828202939   希望可以和大家一起学习、一起进步!! 上一节课我们学习了  三维空间-不同位置的三角形 这一节课我们将学习  三维空间之加入旋转矩阵的三角形 本案...来自: 谷子的博客

Proxyee-down的下载与安装教程

 155897

Proxyee-down是monkeyWie在Github上的一个开源项目,向作者致敬。 最新版的Proxyee-down为3.12(2018.10更新),因为作者在3.x后的版本中并未发布exe版...来自: shadandeajian的博客

军事理论课答案(西安交大版)

 1179573

1.1 1 【单选题】我国陆地领土面积排名世界第几?(C) A、1 B、2 C、3 D、4 2 【单选题】以下哪个国家不属于金砖五国(BRICS)?(B) A、中国 B、日本 C...来自: ling_wang的博客

微服务Springcloud超详细教程+实战(九)

 22165

如在文档中遇到什么问题请联系作者 QQ:1172796094 本人正在找深圳Java实习工作,求大佬带飞 —————————————————————————————————————— 八在审核中,请见...

PageInfo介绍及使用

 437

PageInfo介绍及使用1.MyBatis分页插件-PageHelper的配置与应用2.参考封装PageInfo类3.PageInfo属性表 下载PageInfo文档 1.MyBatis分页插件-P...来自: 猪精的博客

2018最好用百度云破解版,百度网盘不限速下载,教你如何解决百度网盘限速的方法。亲测完美使用

 129934

百度网盘不限速 点击下载 提取码:jsk0 百度网盘不限速 点击下载 提取码:jsk0 对于大多数人来说,每次在百度网盘下载东西的时候总会被限速,如果不想被限速就要充值百度网盘的SVIP,...来自: qq_41925894的博客

智慧树走进故宫章节测试答案智慧树走进故宫刷课插件2018年智慧树走进故宫期末考试答案

 126223

欢迎通过微信客户端搜索jiutu2019或者扫描下方二维码关注樛图公众号获取智慧树刷题插件。 智慧树刷课插件获取方法:微信关注公众号(jiutu2019)后,后台回复“智慧树刷课插件”即可获取。 ...来自: 柠檬很酸的博客

webgl第35课-深度缓冲-正确处理图像的位置关系

 5159

需要电子档书籍可以Q群:828202939   希望可以和大家一起学习、一起进步!! 所有的课程源代码在我上传的资源里面,本来想设置开源,好像不行!博客和专栏同步! 如有错别字或有理解不到位的地方...来自: 谷子的博客

100个小学生猜字谜大全及答案

 212941

100个小学生猜字谜大全及答案 1.字谜:山上还有山。猜一字,答案是:出 2.字谜:十张口,一颗心。猜一字,答案是:思 3.字谜:说它小,下边大,说它大,上边小。猜一字,答案是:...来自: 欢迎光临 包国工作室

vs2017安装和使用教程(详细)

 232234

VS2017如此强大,不仅仅是C语言,Python,ios,Android,Web,Node.js,Azure,Unity,JavaScript等开发都可以执行,大家快来使用呀~ csdn的兄弟们看...来自: qq_36556893的博客

手把手教你如何安装Pycharm——靠谱的Pycharm安装详细教程

 297529

今天小编给大家分享如何在本机上下载和安装Pycharm,具体的教程如下:1、首先去Pycharm官网,或者直接输入网址:http://www.jetbrains.com/pycharm/downloa...来自: pdcfighting的博客

国内用户无法使用TikTok(国外版抖音)的解决方案

 106148

首先,我是不推荐程序员使用这个东西的,毕竟很浪费时间.我平时比较忙,也是没时间玩这些. 1. 背景 娱乐娱乐也是可以,但不要沉迷其中.我们可以从这款产品中学习它的优点. 无独有偶,那天忽然在...来自: 潇风寒月

webgl第24课-几何图形的装配和光栅化

 6970

需要电子档书籍可以Q群:828202939   希望可以和大家一起学习、一起进步!!纯手打!! 上一节课我们学习了   颜色与纹理中-将非坐标数据传入顶点着色器的另外一种方式--交错组织 这一节课...来自: 谷子的博客

学习Webpack(一)之 初识webpack

 3097

学习Webpack(一)之 初识webpack webpack简介 在官网中说,webpack是一个现代javaScript应用程序的静态模块打包器。他可以分为入口(entry)、出口(output...来自: 幽幽小春

各大磁力种子搜索引擎对比

 460302

现在磁力种子搜索引擎质量参差不齐,现在就重点整理几个常用的种子搜索站,做个对比分析 1.屌丝搜-最懂屌丝的搜索引擎(www.diaosisou.com) 号称最懂屌丝的BT搜索引擎,确实名副其实,屌丝...来自: lizhengnanhua的专栏

岁月安然

关注

原创

10

粉丝

2

喜欢

0

评论

0

等级:

 

访问:

 

3404

积分:

 

152

排名:

 

115万+

 

最新文章

个人分类

展开

归档

 

联系我们

微信客服

微信客服

QQ客服

QQ客服

kefu@csdn.netQQ客服

客服论坛400-660-0108

工作时间 8:00-22:00

关于我们招聘广告服务 网站地图

百度提供站内搜索 京ICP证09002463号

©1999-2018 江苏乐知网络技术有限公司

江苏知之为计算机有限公司 北京创新乐知信息技术有限公司版权所有

经营性网站备案信息网络110报警服务

北京互联网违法和不良信息举报中心

中国互联网举报中心

  •  

    0

  •  
  •  
  •  
  •  
  •  

 

猿学习

 

  • 0
    点赞
  • 0
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值