package com.yq.common.page;
import java.lang.reflect.Field;
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 javax.xml.bind.PropertyException;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
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.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import com.alibaba.druid.util.StringUtils;
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PagePlugin implements Interceptor
{
private static String dialect = ""; // 数据库方言
private static String pageSqlId = ""; // mapper.xml中需要拦截的ID(正则匹配)
public Object intercept(Invocation ivk) throws Throwable
{
// TODO Auto-generated method stub
if (ivk.getTarget() instanceof RoutingStatementHandler)
{
RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler,
"delegate");
MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate,
"mappedStatement");
if (mappedStatement.getId().matches(pageSqlId))
{ // 拦截需要分页的SQL
BoundSql boundSql = delegate.getBoundSql();
Object parameterObject = boundSql.getParameterObject();// 分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空
if (parameterObject == null)
{
throw new NullPointerException("parameterObject尚未实例化!");
}
else
{
Connection connection = (Connection) ivk.getArgs()[0];
String sql = boundSql.getSql();
// String countSql = "select count(0) from (" + sql+ ") as tmp_count"; //记录统计
String countSql = "select count(0) from (" + sql + ") tmp_count"; // 记录统计 == oracle 加 as 报错(SQL
// command not properly ended)
PreparedStatement countStmt = connection.prepareStatement(countSql);
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,
boundSql.getParameterMappings(), parameterObject);
setParameters(countStmt, mappedStatement, countBS, parameterObject);
ResultSet rs = countStmt.executeQuery();
int count = 0;
if (rs.next())
{
count = rs.getInt(1);
}
rs.close();
countStmt.close();
// System.out.println(count);
Page page = null;
if (parameterObject instanceof Page)
{ // 参数就是Page实体
page = (Page) parameterObject;
page.setEntityOrField(true);
page.setTotalResult(count);
if(count<=0){
page.setTotalPage(0);
}
else{
if(count%page.getiDisplayLength()==0){
page.setTotalPage(count/page.getiDisplayLength());
}
else{
page.setTotalPage(count/page.getiDisplayLength()+1);
}
}
}
else
{ // 参数为某个实体,该实体拥有Page属性
Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page");
if (pageField != null)
{
page = (Page) ReflectHelper.getValueByFieldName(parameterObject, "page");
if (page == null)
page = new Page();
page.setEntityOrField(false);
page.setTotalResult(count);
if(count<=0){
page.setTotalPage(0);
}
else{
if(count%page.getiDisplayLength()==0){
page.setTotalPage(count/page.getiDisplayLength());
}
else{
page.setTotalPage(count/page.getiDisplayLength()+1);
}
}
ReflectHelper.setValueByFieldName(parameterObject, "page", page); // 通过反射,对实体对象设置分页对象
}
else
{
throw new NoSuchFieldException(parameterObject.getClass().getName() + "不存在 page 属性!");
}
}
String pageSql = generatePageSql(sql, page);
ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); // 将分页sql语句反射回BoundSql.
}
}
}
return ivk.proceed();
}
/**
* 对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler
*
* @param ps
* @param mappedStatement
* @param boundSql
* @param parameterObject
* @throws SQLException
*/
@SuppressWarnings("unchecked")
private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql,
Object parameterObject) throws SQLException
{
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null)
{
Configuration configuration = mappedStatement.getConfiguration();
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
for (int i = 0; i < parameterMappings.size(); i++)
{
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT)
{
Object value;
String p
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
test-project.rar (48个子文件)
test-project
.project 1KB
src
main
webapp
WEB-INF
views
showData.jsp 511B
web.xml 2KB
index.jsp 67B
resources
spring-context.xml 7KB
config.properties 365B
mapper
UserMapper.xml 1KB
spring-mvc.xml 3KB
mybatis-config.xml 790B
log4j.properties 981B
java
com
yq
common
annotation
MyBatisDao.java 774B
page
PageData.java 4KB
Page.java 2KB
PagePlugin.java 12KB
ReflectHelper.java 2KB
test
service
UserService.java 379B
controller
UserController.java 1KB
dao
UserDao.java 195B
entity
User.java 885B
target
m2e-wtp
web-resources
META-INF
MANIFEST.MF 107B
maven
com.yq.test
test-project
pom.properties 234B
pom.xml 9KB
classes
spring-context.xml 7KB
config.properties 365B
mapper
UserMapper.xml 1KB
com
yq
common
annotation
MyBatisDao.class 548B
page
PageData.class 4KB
Page.class 2KB
PagePlugin.class 10KB
ReflectHelper.class 2KB
test
service
UserService.class 712B
controller
UserController.class 2KB
dao
UserDao.class 259B
entity
User.class 1KB
spring-mvc.xml 3KB
mybatis-config.xml 790B
log4j.properties 981B
test-classes
.settings
org.eclipse.wst.jsdt.ui.superType.container 49B
org.eclipse.wst.common.project.facet.core.xml 252B
org.eclipse.m2e.core.prefs 90B
org.eclipse.jdt.core.prefs 736B
org.eclipse.wst.validation.prefs 50B
org.eclipse.wst.jsdt.ui.superType.name 6B
org.eclipse.core.resources.prefs 147B
org.eclipse.wst.common.component 677B
.jsdtscope 639B
pom.xml 9KB
.classpath 1KB
共 48 条
- 1
资源评论
双子叶
- 粉丝: 25
- 资源: 23
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 实现坐标转换程序(C#桌面窗体)
- 毕业设计基于树莓派、OpenCV及Python语言的人脸识别.zip
- 客流量预测.rar客流量预测.rar客流量预测.rar
- 613155687470549安卓鸿蒙手机版_10.7.6.6.apk
- 基于51单片机的蓝牙避障小车源码.zip
- esp8266wifi模块教程: 《嵌入式编程与网络通信:C语言操作ESP8266 WiFi模块》-涵盖嵌入式系统、网络编程、
- 基于51单片机的智能工厂火灾检测预警系统源码.zip
- 毕业设计基于SSM和SpringBoot的动态旅游网站.zip
- 基于51单片机的mp3播放器源码+原理图+参考资料.zip
- 随机森林回归预测模型的构建与应用.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功