MyBatis 拦截器 (实现分页功能)
由于业务关系 巴拉巴拉巴拉
好吧 简单来说就是
原来的业务是 需要再实现类里写 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 结果 略 然后就成功了
下面附上拦截器的代码
![](/assets/blank.gif)
![](/assets/blank.gif)
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 拦截器 (实现分页功能)相关推荐
- MyBatis拦截器实现分页
1.mybatis的四大对象:mybatis的核心对象: ParameterHandler:处理SQL的参数对象: ResultSetHandler:处理SQL的返回结果集 StatementHand ...
- 一步步教你mybatis分页,mybatis分页拦截器 使用,mybatis拦截器分页
mybatis 分页详解.mybatis分页查询,mybatis分页拦截器使用.struts2下mybatis分页 mybatis默认是支持分页的,内部通过创建可滚动的Result ...
- 面试官:你能说说MyBatis拦截器原理吗?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Format cnblogs.com/fangjian042 ...
- MyBatis拦截器原理探究MyBatis拦截器原理探究
MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis拦截 ...
- MyBatis拦截器有哪些以及分析
MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允许你在已映射语句执行过程中 ...
- MyBatis拦截器原理探究
MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...
- Mybatis 拦截器介绍
Mybatis 拦截器介绍 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 1.6 利用拦截器进行分页 拦截器的一个作用就是我们 ...
- MyBatis拦截器原理探究MyBatis拦截器原理探究 1
MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis拦截 ...
- 《转载》Mybatis 拦截器介绍
Mybatis 拦截器介绍 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 1.6 利用拦截器进行分页 1.2 拦截器的一个作用 ...
- mybatis拦截器实现权限管理
框架设计 基于Spring Security+JWT技术实现登录认证和访问授权,基于Mybatis 拦截器实现数据权限的控制.由于已有前文介绍Spring Security如有兴趣可以查看,在此将重点 ...
最新文章
- 洛谷P4705 玩游戏(生成函数+多项式运算)
- 贝叶斯理论与朴素贝叶斯分类理论(Naive Bayesian Model,NBM)
- 甲骨文推出全新Oracle Cloud at Customer
- 自编码的matlab代码,深度学习自动编码机MATLAB实现
- 本周日,王海峰、朱军、李宏毅等大咖邀你加入这场AI开发者盛宴
- 转《浅谈数据库设计技巧》
- pstools套件在渗透中的应用详解
- python中str是什么_python的str()字符串类型的方法详解
- 不要在给自己不学习找借口了,否则…
- 如何基于Spring Boot搭建一个完整的项目
- 不同版本web.xml文件头声明
- 我国会计界计算机软件界大规模研究,初级会计电算化第一章练习.doc
- java使用easypoi实现word模板导出
- 计算机考试祝福,考试前说的祝福语汇编35句 参加考试前的祝福语
- 朋友圈微信投票很麻烦?python开发个自动化刷票脚本,再也不用头痛了!
- 移远M26实现短信接收
- CentOS6.5挂载大于2TB的磁盘使用parted和GPT类型
- vue如何在一个工程里判断h5还是pc,(利用在一个页面显示不同router-view内容原理,本文只使用于单页面项目,多页面项目请查看我另一篇博文)
- 广发卡知识知多少?不懂来看,不然吃亏了!
- github简易教程
热门文章
- Linux安装最新版Mono,Jexus(截至2015年12月30日)
- Hadoop2.2.0中HDFS的高可用性实现原理
- The Python Debugger Command
- 您无权查看或编辑目前的权限设置;但是,您可以取得所有权或更改审核设置
- 专注于钢铁行业电子商务的服务网站,钢铁行业的网上贸易市场 一起成长
- 如何使用postman带Token测试接口?
- Myeclipse 2020.5 版本首发!支持 Java14
- 最受欢迎Java数据库访问框架(DAO层)
- CTO发飙:不要在Java代码中写set/get方法了,逮一次罚款***
- 百度开源移动端深度学习框架mobile-deep-learning(MDL)