内容简介:看完趣味数学书后,开始技术填坑之路通常在业务中,需要进行数据分页查询,这样一来,每条SQL语句都加上limit限制,会多了很多重复的代码,而且每次需要自己在代码中进行偏移量的计算,略微有些麻烦。还好有大神在
看完趣味数学书后,开始技术填坑之路
通常在业务中,需要进行数据分页查询,这样一来,每条 SQL 语句都加上limit限制,会多了很多重复的代码,而且每次需要自己在代码中进行偏移量的计算,略微有些麻烦。
还好有大神在 Github 里贡献了分页插件,而且使用起来很方便,了解了一下使用原理,发现是使用了MyBatis里面的拦截器Interceptor,学习记录一下。
简单:chestnut:
项目中进行引用
一般JavaWeb项目使用到的是maven和gradle进行项目管理
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>最新版本</version> </dependency> ··· // https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper compile group: 'com.github.pagehelper', name: 'pagehelper', version: '5.1.4' 复制代码
在mybatis-config或者spring中进行配置
mybatis: <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --> <property name="param1" value="value1"/> </plugin> </plugins> spring: <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描mapping.xml文件 --> <property name="mapperLocations" value="classpath:mapping/*.xml"> </property> <!-- 配置分页插件 --> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <value> reasonable=true </value> </property> </bean> </array> </property> </bean> 复制代码
我是用的是第二种配置方式(Spring),更加细详细配置说明可以在Github文档中进行查看。
mapper查询语句
为了简单,使用了单表查询
<select id="selectByUserId" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM course_user WHERE user_id = #{userId, jdbcType=INTEGER} </select> 复制代码
代码使用
查询时,在代码中使用的是官网推荐的第二种实现方式,
// 使用这个方法,接下来的第一个select方法会进行分页 PageHelper.startPage(1, 5); List<CourseUser> list = mapper.selectByUserId(userId); // 查询结果list类型是Page<E>,要取出分页信息,可以强转,也可以使用PageInfo // 用PageInfo对结果进行包装 PageInfo page = new PageInfo(list); // 获取总数量 int count = page.getTotal(); 复制代码
分页插件,源码实现原理
该插件支持很多数据库,Oracle、 MySQL 、mongdb等都支持,一般常用的话是MySQL,测试用的项目也是使用MySQL作为持久层,该分页插件可以通过autoDialect自动方言适配了MySQL。
插件通过MyBatis的 拦截器Interceptor进行SQL重写 ,可以从源码中看出
统计数量
拦截器入口:com.github.pagehelper.PageInterceptor#intercept
获取统计数量的方法:com.github.pagehelper.parser.CountSqlParser#getSmartCountSql(java.lang.String, java.lang.String)
/** * 获取智能的countSql * * @param sql * @param name 列名,默认 0 * @return */ public String getSmartCountSql(String sql, String name) { //解析SQL Statement stmt = null; //特殊sql不需要去掉order by时,使用注释前缀 if(sql.indexOf(KEEP_ORDERBY) >= 0){ return getSimpleCountSql(sql); } try { stmt = CCJSqlParserUtil.parse(sql); } catch (Throwable e) { //无法解析的用一般方法返回count语句 return getSimpleCountSql(sql); } Select select = (Select) stmt; SelectBody selectBody = select.getSelectBody(); try { //处理body-去order by processSelectBody(selectBody); } catch (Exception e) { //当 sql 包含 group by 时,不去除 order by return getSimpleCountSql(sql); } //处理with-去order by processWithItemsList(select.getWithItemsList()); //处理为count查询 sqlToCount(select, name); String result = select.toString(); return result; } 复制代码
通过该方法,去掉参数args,然后改成count(*),修改成统计数量的SQL。
进行分页查询
具体调用方法:com.github.pagehelper.dialect.helper.MySqlDialect#getPageSql
@Override public String getPageSql(String sql, Page page, CacheKey pageKey) { StringBuilder sqlBuilder = new StringBuilder(sql.length() + 14); sqlBuilder.append(sql); // 判断是不是第一页,如果是第一页,不需要设置偏移量 if (page.getStartRow() == 0) { sqlBuilder.append(" LIMIT ? "); } else { sqlBuilder.append(" LIMIT ?, ? "); } pageKey.update(page.getPageSize()); return sqlBuilder.toString(); } 复制代码
从这里看出,该插件不是通过内存进行分页,而是通过修改SQL进行物理分页。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JavaScript设计模式与开发实践
曾探 / 人民邮电出版社 / 2015-5 / 59.00元
本书在尊重《设计模式》原意的同时,针对JavaScript语言特性全面介绍了更适合JavaScript程序员的了16个常用的设计模式,讲解了JavaScript面向对象和函数式编程方面的基础知识,介绍了面向对象的设计原则及其在设计模式中的体现,还分享了面向对象编程技巧和日常开发中的代码重构。本书将教会你如何把经典的设计模式应用到JavaScript语言中,编写出优美高效、结构化和可维护的代码。一起来看看 《JavaScript设计模式与开发实践》 这本书的介绍吧!