struts2 spring3 mybatis3拦截器分页技术
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
struts2 spring3.2.4 mybatis-3.2.3 通用分页(不同数据库)拦截器
mybatis没有根据数据库方言进行分页封装,但是提供了拦截器,我们可以在拦截其中获取数据库方言(数据库方言通过配置文件获取)和查询sql,根据数据库方言进行翻页分装,在拦截其中有两种实现方式:
1. 拦截器中计算总数,通过jdbc的方式,再封装翻页sql
2.计算总数在应用层计算,拦截器中只通过数据库方言进行查询sql的封装本人认为第一种方式可能会影响到性能,下面是通过第二种方法实现分页
1、拦截器类
[java]view plaincopyprint?
1.package com.zhou.bean;
2.
3.import ng.reflect.Field;
4.import java.sql.Connection;
5.import java.sql.PreparedStatement;
6.import java.sql.ResultSet;
7.import java.sql.SQLException;
8.import java.util.List;
9.import java.util.Properties;
10.
11.import org.apache.ibatis.executor.parameter.ParameterHandler;
12.import org.apache.ibatis.executor.statement.RoutingStatementHandler;
13.import org.apache.ibatis.executor.statement.StatementHandler;
14.import org.apache.ibatis.mapping.BoundSql;
15.import org.apache.ibatis.mapping.MappedStatement;
16.import org.apache.ibatis.mapping.ParameterMapping;
17.import org.apache.ibatis.plugin.Interceptor;
18.import org.apache.ibatis.plugin.Intercepts;
19.import org.apache.ibatis.plugin.Invocation;
20.import org.apache.ibatis.plugin.Plugin;
21.import org.apache.ibatis.plugin.Signature;
22.import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
23.
24./**
25.* @author zhouzhenlong
26.* @date 2012-11-20 下午04:33:35
27.* @description 不在拦截器中计算总数,影响效率
28.* @version V1.0
29.*
30.* 分页拦截器,用于拦截需要进行分页查询的操作,然后对其进行分页处理。利用拦截器实
现Mybatis分页的原理:
31.* 要利用JDBC对数据库进行操作就必须要有一个对应的Statement对象
32.* ,Mybatis在执行Sql语句前就会产生一个包含Sql语句的Statement对象,而且对应的
Sql语句
33.* 是在Statement之前产生的,所以我们就可以在它生成Statement之前对用来生成
Statement的Sql语句下手
34.* 。在Mybatis中Statement语句是通过RoutingStatementHandler对象的
35.* prepare方法生成的。所以利用拦截器实现Mybatis分页的一个思路就是拦截
StatementHandler接口的prepare方法
36.* ,然后在拦截器方法中把Sql语句改成对应的分页查询Sql语句,之后再调用
37.* StatementHandler对象的prepare方法,即调用invocation.proceed()。
38.* 对于分页而言,在拦截器里面我们还需要做的一个操作就是统计满足当前条件的记录一共
有多少
39.* ,这是通过获取到了原始的Sql语句后,把它改为对应的统计语句再利用Mybatis封装好
的参数和设
40.* 置参数的功能把Sql语句中的参数进行替换,之后再执行查询记录数的Sql语句进行总记
录数的统计。
41.*
42.*/
43.@Intercepts({ @Signature(method = "prepare", type = StatementHandler.class,
args = { Connection.class }) })
44.public class PageInterceptor implements Interceptor {
45.
46.private String databaseType;// 数据库类型,不同的数据库有不同的分页方法
47.
48./**
49.* 拦截后要执行的方法
50.*/
51.public Object intercept(Invocation invocation) throws Throwable {
52.// 对于StatementHandler其实只有两个实现类,一个是RoutingStatementHandler,另
一个是抽象类BaseStatementHandler,
53.// BaseStatementHandler有三个子类,分别是SimpleStatementHandler,
PreparedStatementHandler和CallableStatementHandler,
54.// SimpleStatementHandler是用于处理Statement的,PreparedStatementHandler
是处理PreparedStatement的,而CallableStatementHandler是
55.// 处理CallableStatement的。Mybatis在进行Sql语句处理的时候都是建立的
RoutingStatementHandler,而在RoutingStatementHandler里面拥有一个
56.// StatementHandler类型的delegate属性,RoutingStatementHandler会依据
Statement的不同建立对应的BaseStatementHandler,即SimpleStatementHandler、57.// PreparedStatementHandler或CallableStatementHandler,在
RoutingStatementHandler里面所有StatementHandler接口方法的实现都是调用的
delegate对应的方法。
58.// 我们在PageInterceptor类上已经用@Signature标记了该Interceptor只拦截
StatementHandler接口的prepare方法,又因为Mybatis只有在建立
RoutingStatementHandler的时候
59.// 是通过Interceptor的plugin方法进行包裹的,所以我们这里拦截到的目标对象肯定是
RoutingStatementHandler对象。
60.final RoutingStatementHandler handler = (RoutingStatementHandler)
invocation.getTarget();
61.// 通过反射获取到当前RoutingStatementHandler对象的delegate属性
62.final StatementHandler delegate = (StatementHandler)
ReflectUtil.getFieldValue(handler, "delegate");
63.// 获取到当前StatementHandler的
64.// boundSql,这里不管是调用handler.getBoundSql()还是直接调用
delegate.getBoundSql()结果是一样的,因为之前已经说过了
65.// RoutingStatementHandler实现的所有StatementHandler接口方法里面都是调用的
delegate对应的方法。
66.final BoundSql boundSql = delegate.getBoundSql();
67.// 拿到当前绑定Sql的参数对象,就是我们在调用对应的Mapper映射语句时所传入的参数
对象
68.final Object obj = boundSql.getParameterObject();