由于业务关系 巴拉巴拉巴拉

好吧 简单来说就是

原来的业务是 需要再实现类里写 selectCount 和selectPage两个方法才能实现分页功能

现在想要达到效果是 只通过一个方法就可以实现 也就是功能合并 所以就有了下面的实践

既然是基于MyBatis 所以就先搭建一个Mybatis的小项目

1.01导入 mybatis和mysql的包

1.02.配置文件 Configuration.xml 中添加

 <environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test" /><property name="username" value="root"/><property name="password" value=""/></dataSource></environment></environments>

 

2.01.然后创建一个模块user  创建user表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` char(32) NOT NULL,`t1` char(32) DEFAULT NULL,`t2` char(32) DEFAULT NULL,`t3` char(32) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

 

3.01.写对应bean:User.java

package lqb.bean;public class User extends Common{private String id;private String name;private String t1;private String t2;private String t3;//省略get set
}

3.02.对应的mapper: UserMapper.java和UserMapper.xml  

简单实现下CRUD

public interface UserMapper {public User selectByID(int id);public List<User> select();public int insert(User u);public int update(User u);public int delete(User u);
}

<mapper namespace="lqb.mapper.UserMapper"><select id="selectByID" parameterType="int" resultType="lqb.bean.User">select * from `user` where id = #{id}</select><select id="select" resultType="lqb.bean.User" parameterType="lqb.bean.User">select * from `user` </select><insert id="insert" parameterType="lqb.bean.User">insert into user (id,name,t1,t2,t3) values (#{id},#{name},#{t1},#{t2},#{t3})</insert><update id="update" parameterType="lqb.bean.User">update user set name=#{name},t1=#{t1},t2=#{t2},t3=#{t3} where id=#{id}</update><delete id="delete" parameterType="lqb.bean.User">delete from user where id=#{id}</delete>
</mapper>

3.03.然后 在配置文件Configuration.xml中添加user的配置

<mappers><mapper resource="lqb/mapper/UserMapper.xml"/>
</mappers>

3.04.然后是实现:UserService.java

public class UserService {private static SqlSessionFactory sqlSessionFactory;private static Reader reader;static{try{reader    = Resources.getResourceAsReader("Configuration.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);}catch(Exception e){e.printStackTrace();}}public static SqlSessionFactory getSession(){return sqlSessionFactory;}
}

4.01 好 然后是重点了

思路: 截获查询的sql 然后拼成 sqlPage和sqlCount 再进行查找取值 然后赋传入对象

所以我们就需要创建一个基础类来让user.java来继承

public class Common {private int pagesize;private int pageid;private int pagebegin;private int count;//省略 get set
}

4.02 然后 让User继承Common

public class User extends Common{

4.03 那怎么截获sql呢 我们就要写一个mybatis的拦截器 用来拦截sql请求 PageInterceptor

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}),  @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class PageInterceptor implements Interceptor {  //插件运行的代码,它将代替原有的方法
    @Overridepublic Object intercept(Invocation invocation) throws Throwable {}// 拦截类型StatementHandler
    @Overridepublic Object plugin(Object target) {}@Overridepublic void setProperties(Properties properties) {     }          

4.04 首先 设置拦截类型 重写plugin方法

@Overridepublic Object plugin(Object target) {if (target instanceof StatementHandler) {  return Plugin.wrap(target, this);  } else {  return target;  }  }

4/05 然后 就要重写最重要的intercept了

这里我们有一个设定  如果查询方法含有searchpage 就进行分页 其他方法无视

所以就要获取方法名

 StatementHandler statementHandler = (StatementHandler) invocation.getTarget();  MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);  MappedStatement mappedStatement=(MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");String selectId=mappedStatement.getId();

4.06 然后判断下 如果含有searchpage 就获取sql

BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
// 分页参数作为参数对象parameterObject的一个属性
String sql = boundSql.getSql();
Common co=(Common)(boundSql.getParameterObject());

4.07 然后 根据这个sql 重新拼写countsql和pagesql 

String countSql=concatCountSql(sql);
String pageSql=concatPageSql(sql,co);
...
public String concatCountSql(String sql){StringBuffer sb=new StringBuffer("select count(*) from ");sql=sql.toLowerCase();if(sql.lastIndexOf("order")>sql.lastIndexOf(")")){sb.append(sql.substring(sql.indexOf("from")+4, sql.lastIndexOf("order")));}else{sb.append(sql.substring(sql.indexOf("from")+4));}return sb.toString();}public String concatPageSql(String sql,Common co){StringBuffer sb=new StringBuffer();sb.append(sql);sb.append(" limit ").append(co.getPagebegin()).append(" , ").append(co.getPagesize());return sb.toString();}

4.08 然后 通过jdbc查询count 然后把值绑定给common

Connection connection = (Connection) invocation.getArgs()[0];  PreparedStatement countStmt = null;  ResultSet rs = null;  int totalCount = 0;  try { countStmt = connection.prepareStatement(countSql);  rs = countStmt.executeQuery();  if (rs.next()) {  totalCount = rs.getInt(1);  } } catch (SQLException e) {  System.out.println("Ignore this exception"+e);  } finally {  try {  rs.close();  countStmt.close();  } catch (SQLException e) {  System.out.println("Ignore this exception"+ e);  }  }  //绑定countco.setCount(totalCount);

4.09 再把pagesql赋给元BoundSql

   metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);  

4.10 最后在配置文件中添加拦截器配置

 <plugins>  <plugin interceptor="lqb.interceptor.PageInterceptor"/>
</plugins> 

4.11 好然后 在UserMapper.java和UserMapper.xml中添加分页代码

 <select id="selectPage"  parameterType="lqb.bean.User" resultType="lqb.bean.User"> select * from `user` where id in(3,4,6,8) order by id </select>
 public List<User> selectPage(User u);

5.01 最后是测试了

main...请允许本人的懒 就姑且在main方法测下吧

User u=new User();
u.setPagebegin(2);
u.setPagesize(3);
System.out.println("-u.getCount()------"+u.getCount());
List<User> l=userService.selectPage(u);
System.out.println(l.size());
System.out.println("-u.getCount()------"+u.getCount());

5.02 结果 略   然后就成功了  

下面附上拦截器的代码

package lqb.interceptor;import java.util.Properties;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import java.sql.*;
import lqb.bean.Common;@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}),  @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class PageInterceptor implements Interceptor {  private static final String SELECT_ID="selectpage";//插件运行的代码,它将代替原有的方法
    @Overridepublic Object intercept(Invocation invocation) throws Throwable {System.out.println("PageInterceptor -- intercept");if (invocation.getTarget() instanceof StatementHandler) {  StatementHandler statementHandler = (StatementHandler) invocation.getTarget();  MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);  MappedStatement mappedStatement=(MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");String selectId=mappedStatement.getId();if(SELECT_ID.equals(selectId.substring(selectId.lastIndexOf(".")+1).toLowerCase())){BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");  // 分页参数作为参数对象parameterObject的一个属性  String sql = boundSql.getSql();Common co=(Common)(boundSql.getParameterObject());// 重写sql  String countSql=concatCountSql(sql);String pageSql=concatPageSql(sql,co);System.out.println("重写的 count  sql        :"+countSql);System.out.println("重写的 select sql        :"+pageSql);Connection connection = (Connection) invocation.getArgs()[0];  PreparedStatement countStmt = null;  ResultSet rs = null;  int totalCount = 0;  try { countStmt = connection.prepareStatement(countSql);  rs = countStmt.executeQuery();  if (rs.next()) {  totalCount = rs.getInt(1);  } } catch (SQLException e) {  System.out.println("Ignore this exception"+e);  } finally {  try {  rs.close();  countStmt.close();  } catch (SQLException e) {  System.out.println("Ignore this exception"+ e);  }  }  metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);            //绑定count
                co.setCount(totalCount);}} return invocation.proceed();}/*** 拦截类型StatementHandler */@Overridepublic Object plugin(Object target) {if (target instanceof StatementHandler) {  return Plugin.wrap(target, this);  } else {  return target;  }  }@Overridepublic void setProperties(Properties properties) {}  public String concatCountSql(String sql){StringBuffer sb=new StringBuffer("select count(*) from ");sql=sql.toLowerCase();if(sql.lastIndexOf("order")>sql.lastIndexOf(")")){sb.append(sql.substring(sql.indexOf("from")+4, sql.lastIndexOf("order")));}else{sb.append(sql.substring(sql.indexOf("from")+4));}return sb.toString();}public String concatPageSql(String sql,Common co){StringBuffer sb=new StringBuffer();sb.append(sql);sb.append(" limit ").append(co.getPagebegin()).append(" , ").append(co.getPagesize());return sb.toString();}public void setPageCount(){}}  

View Code

最后是下载地址

下载

转载于:https://www.cnblogs.com/jethypc/p/5149183.html

MyBatis 拦截器 (实现分页功能)相关推荐

  1. MyBatis拦截器实现分页

    1.mybatis的四大对象:mybatis的核心对象: ParameterHandler:处理SQL的参数对象: ResultSetHandler:处理SQL的返回结果集 StatementHand ...

  2. 一步步教你mybatis分页,mybatis分页拦截器 使用,mybatis拦截器分页

              mybatis 分页详解.mybatis分页查询,mybatis分页拦截器使用.struts2下mybatis分页 mybatis默认是支持分页的,内部通过创建可滚动的Result ...

  3. 面试官:你能说说MyBatis拦截器原理吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Format cnblogs.com/fangjian042 ...

  4. MyBatis拦截器原理探究MyBatis拦截器原理探究

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis拦截 ...

  5. MyBatis拦截器有哪些以及分析

    MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允许你在已映射语句执行过程中 ...

  6. MyBatis拦截器原理探究

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...

  7. Mybatis 拦截器介绍

    Mybatis 拦截器介绍 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 1.6 利用拦截器进行分页 拦截器的一个作用就是我们 ...

  8. MyBatis拦截器原理探究MyBatis拦截器原理探究 1

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis拦截 ...

  9. 《转载》Mybatis 拦截器介绍

    Mybatis 拦截器介绍 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 1.6 利用拦截器进行分页 1.2 拦截器的一个作用 ...

  10. mybatis拦截器实现权限管理

    框架设计 基于Spring Security+JWT技术实现登录认证和访问授权,基于Mybatis 拦截器实现数据权限的控制.由于已有前文介绍Spring Security如有兴趣可以查看,在此将重点 ...

最新文章

  1. 洛谷P4705 玩游戏(生成函数+多项式运算)
  2. 贝叶斯理论与朴素贝叶斯分类理论(Naive Bayesian Model,NBM)
  3. 甲骨文推出全新Oracle Cloud at Customer
  4. 自编码的matlab代码,深度学习自动编码机MATLAB实现
  5. 本周日,王海峰、朱军、李宏毅等大咖邀你加入这场AI开发者盛宴
  6. 转《浅谈数据库设计技巧》
  7. pstools套件在渗透中的应用详解
  8. python中str是什么_python的str()字符串类型的方法详解
  9. 不要在给自己不学习找借口了,否则…
  10. 如何基于Spring Boot搭建一个完整的项目
  11. 不同版本web.xml文件头声明
  12. 我国会计界计算机软件界大规模研究,初级会计电算化第一章练习.doc
  13. java使用easypoi实现word模板导出
  14. 计算机考试祝福,考试前说的祝福语汇编35句 参加考试前的祝福语
  15. 朋友圈微信投票很麻烦?python开发个自动化刷票脚本,再也不用头痛了!
  16. 移远M26实现短信接收
  17. CentOS6.5挂载大于2TB的磁盘使用parted和GPT类型
  18. vue如何在一个工程里判断h5还是pc,(利用在一个页面显示不同router-view内容原理,本文只使用于单页面项目,多页面项目请查看我另一篇博文)
  19. 广发卡知识知多少?不懂来看,不然吃亏了!
  20. github简易教程

热门文章

  1. Linux安装最新版Mono,Jexus(截至2015年12月30日)
  2. Hadoop2.2.0中HDFS的高可用性实现原理
  3. The Python Debugger Command
  4. 您无权查看或编辑目前的权限设置;但是,您可以取得所有权或更改审核设置
  5. 专注于钢铁行业电子商务的服务网站,钢铁行业的网上贸易市场 一起成长
  6. 如何使用postman带Token测试接口?
  7. Myeclipse 2020.5 版本首发!支持 Java14
  8. 最受欢迎Java数据库访问框架(DAO层)
  9. CTO发飙:不要在Java代码中写set/get方法了,逮一次罚款***
  10. 百度开源移动端深度学习框架mobile-deep-learning(MDL)