mybatis框架下物理分页的实现(整个工程采用的是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{
- @Override
- public 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();
- }
- @Override
- public Object plugin(Object object) {
- // TODO Auto-generated method stub
- return Plugin.wrap(object, this);
- }
- @Override
- public 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类和拦截器
[html] view plain copy
mybatis框架下物理分页的实现(整个工程采用的是springmvc、spring、mybatis框架,数据库是mysql数据库)的更多相关文章
- ssm项目框架搭建(增删改查案例实现)——(SpringMVC+Spring+mybatis项目整合)
Spring 常用注解 内容 一.基本概念 1. Spring 2. SpringMVC 3. MyBatis 二.开发环境搭建 1. 创建 maven 项目 2. SSM整合 2.1 项目结构图 2 ...
- 手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版)
手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版) SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级架构方案.标准的MVC设计模式, ...
- spring+websocket综合(springMVC+spring+MyBatis这是SSM框架和websocket集成技术)
java-websocket该建筑是easy.儿童无用的框架可以在这里下载主线和个人教学好java-websocket计划: Apach Tomcat 8.0.3+MyEclipse+maven+JD ...
- springMVC,spring,mybatis全注解搭建框架--第一步,让框架跑起来
自己从事java开发工作也有一年多了,自己却没有亲手搭建一个完整的框架.于是今天自己动手搭建一个,过程中遇到一些问题,倒腾了大半天终于搞定了. 现在给大家分享一下过程,自己也记录下来,以后学习参考使用 ...
- 单工程搭建springmvc+spring+mybatis(maven,idea)
单工程搭建springmvc+spring+mybatis(maven,idea) 1.pom.xml <properties> <project.build.sourceEncod ...
- (一)springmvc+spring+mybatis+maven框架搭建
(一)springmvc+spring+mybatis+maven框架搭建 1.说明 工作之余,为了学习点东西.先搭建个框架. 以后要往里面加东西,比如rabbitMQ.redis.shiro等. 也 ...
- SSM(SpringMVC+Spring+MyBatis)三大框架使用Maven快速搭建整合(实现数据库数据到页面进行展示)
本文介绍使用SpringMVC+Spring+MyBatis三大框架使用Maven快速搭建一个demo,实现数据从数据库中查询返回到页面进行展示的过程. 技术选型:SpringMVC+Spring+M ...
- SpringMVC+Spring+mybatis+maven+搭建多模块框架前后端分离开发框架的完整demo,拿走不谢。——猿实战02
猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...
- 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01
猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...
- SSM(SpringMVC+Spring+Mybatis)框架学习理解
近期做到的项目中,用到的框架是SSM(SpringMVC+Spring+Mybatis).之前比较常见的是SSH.用到了自然得了解各部分的分工 spring mvc 是spring 处理web层请求的 ...
随机推荐
- [php-pear]如何使用 PHP-PEAR安装器,以及使用 PEAR 安装扩展库
我们都知道 PHP PEAR,就是 PHP Extension and Application Respository,也就是 PHP 扩展和应用代码库. PHP 也可以通过 PEAR 安装器来进行 ...
- Python——面向对象(初级篇)
1.如何创建类 class 类名: pass 2.如何创建方法 构造方法: __init__ obj = 类名('a1') 普通方法: obj = 类名('xxx') obj.普通方法名() 3.图解 ...
- ServiceStack DateTime数据类型转Json出现的困扰
执行dotnet-new selfhost sstest 创建项目,然后打开解决方案 修改ssTest.ServiceModel中的Hello.cs,在HellopResponse中添加时间属性,然后 ...
- 用WPF写一个登录界面,我想在输入完密码后按回车就能够验证登陆,而不需要用鼠标单击登陆按钮
在wpf中,将按钮的IsDefault设置为true
- 【译】准备好你求职时候用的 GitHub 账号
我目前正在招聘,很多人分享了他们的GitHubs个人资料和项目,但是维护得很差,所以我决定为活跃的求职者写一个小指南. 无论是否合理,技术招聘人员倾向于从您的GitHub个人资料中推断出很多关于您的信 ...
- prometheus比zabbix好在哪点?
分享网易云轻舟微服务选择基于 Prometheus 开发微服务监控系统的考量: 开源 云原生 与微服务监控需求的匹配度很高 开源 Prometheus是CNCF(云原生计算基金会)旗下成熟的开源项目, ...
- [NOIP2018]赛道修建(二分+multiset)
考场上打了一个 \(vector\) 解法,因为我当时不会 \(multiset\) 好吧,我来讲一讲今年的 \(tgD1T3\) 首先,这题 \(55\) 分是不难想的 1. \(b_i=a_i+1 ...
- 装饰者模式&数据库连接池原理
装饰者模式: 我是一个没有感情的杀手 在复习到自建数据库连接池的时候有点蒙了,再次翻看视频整理如下:(装饰者模式下自建数据库连接池修改close功能为 回收连接对象) 自备材料:数据库连接对象的获取的 ...
- 大脸猫讲逆向之ARM汇编中PC寄存器详解
i春秋作家:v4ever 近日,在研究一些开源native层hook方案的实现方式,并据此对ARM汇编层中容易出问题的一些地方做了整理,以便后来人能有从中有所收获并应用于现实问题中.当然,文中许多介绍 ...
- 【hyperscan】编译hyperscan 4.0.0
ref: http://01org.github.io/hyperscan/dev-reference/getting_started.html 1. 硬件需求 intel x86处理器 64-bit ...