mybatis框架下物理分页的实现(整个工程采用的是springmvc、spring、mybatis框架,数据库是mysql数据库)

本文主要是介绍mybatis框架下物理分页的实现(整个工程采用的是springmvc、spring、mybatis框架,数据库是mysql数据库),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

   整个工程采用的是springmvc、spring、mybatis框架,数据库是mysql数据库,本工程采用的是拦截器机制实现物理分页。

    因为文章最后会有完整的工程资源文件,这里就不把详细代码贴出来了,只是把拦截器和相关的配置文件的代码跟大家详细探讨下。

    (一)关于分页拦截器的简单理解

    首先,要开发MyBatis的插件需要实现org.apache.ibatis.plugin.Interceptor接口,这个接口将会要求实现几个方法:intercept()、plugin()及setProperties(),intercept方法是开发人员所要执行的操作,plugin是将你插件放入到MyBatis的插件集合中去,而setProperties这是在你配置你插件的时候将plugins/plugin/properties的值设置到该插件中。
    该方法的第一句话就是获得Intercepts注解,接下来将获得在Intercepts里面的参数@Signature注解内容,在该注解中包含三个参数,分别是type,method,args。Type指定要拦截的类对象,method是指明要拦截该类的哪个方法,第三个是指明要拦截的方法参数集合。在Intercepts中可以配置多个@Signature。那么便对这写值进行遍历,已获得对应的type、method以及args。最终是获得一个HashMap对象,这些对象里面的键是类对象,而值是指定的类中方法对象。执行该端程序之后,更具target的classLoader和接口,来创建一个代理,并且,InvocationHandler是创建一个新的Plugin对象,同时将target,interceptor以及signatureMap传递给Plugin对象,当然,这里的Plugin也实现了Invocation接口。那么target对象所有的方法调用都会触发Plugin中的invoke方法,那么这里将执行开发者所有插入的操作。

    另外对拦截器类里面几个关键的类做出解释:

(1)BoundSql类 ,封装mybatis最终产生sql的类,包括sql语句,参数,参数源数据等。
(2)MappedStatement类,MappedStatement类在Mybatis框架中用于表示XML文件中一个sql语句节点,即一个<select />、<update />或者<insert />标签。Mybatis框架在初始化阶段会对XML配置文件进行读取,将其中的sql语句节点对象化为一个个MappedStatement对象。

   总结,本拦截器实现的目标就是在进行数据库查询操作之前,从配置文件读出相应的sql语句,将相应的参数拼接到其中,然后再进行查询。当然在拼接sql语句之前,先查询了一下数据库中相应记录的总数。

(二)拦截器类PageIntercepter.java:

package cn.zyy.paging.intercepter;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;import cn.zyy.paging.vo.PageObject;@Intercepts({@org.apache.ibatis.plugin.Signature(method="query", type=org.apache.ibatis.executor.Executor.class, args={MappedStatement.class, Object.class, RowBounds.class, org.apache.ibatis.session.ResultHandler.class})})
public class PageIntercepter implements Interceptor{@Overridepublic Object intercept(Invocation invocation) throws Throwable {MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];Object object = invocation.getArgs()[1];if(object instanceof PageObject){PageObject pageObject = (PageObject) object;BoundSql boundSql = mappedStatement.getBoundSql(object);String sql = boundSql.getSql();int count = getCount(mappedStatement,boundSql);pageObject.setCount(count);int pages = (pageObject.getCount()+pageObject.getNumber()-1)/pageObject.getNumber();pageObject.setPages(pages>0?pages:1);int offset = (pageObject.getPage() - 1) * pageObject.getNumber();int limit = pageObject.getNumber();String pageSql = pageSql(sql, offset, limit);BoundSql pageBoundSql = new BoundSql(mappedStatement.getConfiguration(), pageSql, boundSql.getParameterMappings(), boundSql.getParameterObject());MappedStatement pageMappedStatement = pageMappedStatement(mappedStatement, new PageSqlSource(pageBoundSql));invocation.getArgs()[0] = pageMappedStatement;invocation.getArgs()[2] = RowBounds.DEFAULT;}return invocation.proceed();}@Overridepublic Object plugin(Object object) {// TODO Auto-generated method stubreturn Plugin.wrap(object, this);}@Overridepublic void setProperties(Properties properties) {// TODO Auto-generated method stub}private int getCount(MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {Connection connection = null;PreparedStatement ps = null;ResultSet rs = null;try {String countSql = countSql(boundSql.getSql());connection = mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection();ps = connection.prepareStatement(countSql);BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());setCountParameters(ps, mappedStatement, countBoundSql);rs = ps.executeQuery();int count = 0;if (rs.next()){count = rs.getInt(1);}return count;} catch (Exception e) {return 1000;}finally{try {rs.close();} catch (Exception localException4) {}try {ps.close();} catch (Exception localException5) {}try {connection.close();}catch (Exception localException6) {}}}private static String countSql(String sql){sql = sql.toUpperCase();StringBuffer countSql = new StringBuffer();countSql.append("SELECT COUNT(1) FROM (");countSql.append(sql.substring(0, sql.indexOf("ORDER BY")==-1?sql.length():sql.indexOf("ORDER BY")-1));countSql.append(") PAY_PAGE_T");return countSql.toString();}private static void setCountParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();if (parameterMappingList != null){Configuration configuration = mappedStatement.getConfiguration();TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();Object parameterObject = boundSql.getParameterObject();MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);int n = 1;for (ParameterMapping parameterMapping : parameterMappingList){if ((parameterMapping.getMode() == ParameterMode.IN) || (parameterMapping.getMode() == ParameterMode.INOUT)){String property = parameterMapping.getProperty();Object value = null;if (parameterObject != null){if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())){value = parameterObject;}else{value = metaObject == null ? null : metaObject.getValue(property);}}TypeHandler typeHandler = parameterMapping.getTypeHandler();typeHandler.setParameter(ps, n, value, parameterMapping.getJdbcType());}n++;}}}private String pageSql(String sql, int offset, int limit) {sql = sql.toUpperCase();StringBuffer pageSql = new StringBuffer();pageSql.append(sql);pageSql.append(" LIMIT ");pageSql.append(offset);pageSql.append(", ");pageSql.append(limit);return pageSql.toString();}private MappedStatement pageMappedStatement(MappedStatement mappedStatement, SqlSource sqlSource){MappedStatement.Builder builder = new MappedStatement.Builder(mappedStatement.getConfiguration(), mappedStatement.getId(), sqlSource, mappedStatement.getSqlCommandType());builder.resource(mappedStatement.getResource());builder.fetchSize(mappedStatement.getFetchSize());builder.statementType(mappedStatement.getStatementType());builder.keyGenerator(mappedStatement.getKeyGenerator());builder.timeout(mappedStatement.getTimeout());builder.parameterMap(mappedStatement.getParameterMap());builder.resultMaps(mappedStatement.getResultMaps());builder.cache(mappedStatement.getCache());builder.resultSetType(mappedStatement.getResultSetType());builder.flushCacheRequired(mappedStatement.isFlushCacheRequired());builder.useCache(mappedStatement.isUseCache());builder.resultOrdered(mappedStatement.isResultOrdered());builder.databaseId(mappedStatement.getDatabaseId());builder.lang(mappedStatement.getLang());if (mappedStatement.getKeyProperties() != null){for (String keyProperty : mappedStatement.getKeyProperties()){builder.keyProperty(keyProperty);}}if (mappedStatement.getKeyColumns() != null){for (String keyColumn : mappedStatement.getKeyColumns()){builder.keyColumn(keyColumn);}}return builder.build();}public static class PageSqlSource implements SqlSource {private BoundSql boundSql;public PageSqlSource(BoundSql boundSql) {this.boundSql = boundSql;}public BoundSql getBoundSql(Object parameterObject){return this.boundSql;}}}

(三)spring配置文件和mybatis配置文件

mybatis配置文件中主要是配置相关的vo类和拦截器

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><typeAliases><typeAlias alias="page" type="cn.zyy.paging.vo.PageObject"/></typeAliases><plugins><plugin interceptor="cn.zyy.paging.intercepter.PageIntercepter"/></plugins>
</configuration>
spring的配置文件中主要就是实现mybatis和spring框架的整合

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"><!-- 读取属性文件 --><bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name = "location" value = "classpath:db.properties"></property></bean><!-- 配置数据源 --><bean id = "dataSource" class = "org.springframework.jdbc.datasource.DriverManagerDataSource"><property name = "driverClassName" value = "${driverClass}"></property><property name = "url" value = "${url}"></property><property name = "username" value = "${username}"></property><property name = "password" value = "${password}"></property></bean><!-- 配置 sqlSessionFactory,实现spring和mybatis框架的整合--><bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean"><property name = "dataSource" ref = "dataSource"></property><property name = "configLocation" value = "classpath:mybatis-config.xml"></property><property name = "mapperLocations" value = "classpath:cn/zyy/paging/xml/*.xml"></property><property name = "typeAliasesPackage" value = "cn.zyy.paging.vo"></property></bean><!-- 配置 MapperScannerConfigurer:将Mapper接口生成代理注入到Spring --><bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer"><property name = "sqlSessionFactoryBeanName" value = "sqlSessionFactory"></property><property name = "basePackage" value = "cn.zyy.paging.dao"></property></bean><!-- 配置事务管理器 --><bean id = "txManage" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name = "dataSource" ref = "dataSource"></property></bean><!-- 配置事务传播机制 --><tx:advice id = "txAdvice" transaction-manager="txManage"><tx:attributes><tx:method name="*" propagation="REQUIRED"/></tx:attributes></tx:advice><!-- 利用aop实现动态代理 --><aop:config><aop:pointcut expression="execution(* cn.zyy.paging.service.*.*(..))" id="pointcut"/><aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/></aop:config><!-- 扫描springmvc不能扫描的service类 --><context:component-scan base-package="cn.zyy.paging.service"></context:component-scan>
</beans>

整个工程的下载地址是:http://download.csdn.net/detail/u011991249/9689207。

注:使用的数据库表很简单,表名称是user,表字段是id(int)、name(varchar)、pwd(varchar)。


这篇关于mybatis框架下物理分页的实现(整个工程采用的是springmvc、spring、mybatis框架,数据库是mysql数据库)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1081183

相关文章

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.