mybatis分页插件
2015-06-18 16:51
246 查看
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.Map;
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 org.apache.log4j.Logger;
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationPluginForMybaits implements Interceptor {
private static Logger log = Logger.getLogger(PaginationPluginForMybaits.class);
private String dialect = "";
private String pageSqlId = "";
/**
* 生成分页的sql语句
* */
private String generatePageSql(String sql, PageModel<?> page) {
if (page != null && (dialect !=null || !dialect.equals(""))) {
StringBuffer pageSql = new StringBuffer();
if ("mysql".equals(dialect)) {
pageSql.append(sql);
pageSql.append(" limit " + page.getCurrentPageStartIndex() + ","
+ page.getPageSize());
} else if ("oracle".equals(dialect)) {
pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from (");
pageSql.append(sql);
pageSql.append(") tmp_tb where ROWNUM<=");
pageSql.append(page.getCurrentPageStartIndex() + page.getPageSize());
pageSql.append(") where row_id>");
pageSql.append(page.getCurrentPageStartIndex());
}
return pageSql.toString();
} else {
return sql;
}
}
/**
* 设置参数
* */
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 propertyName = parameterMapping.getProperty();
PropertyTokenizer prop = new PropertyTokenizer(propertyName);
if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry
.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else if (boundSql.hasAdditionalParameter(propertyName)) {
value = boundSql.getAdditionalParameter(propertyName);
} else if (propertyName
.startsWith(ForEachSqlNode.ITEM_PREFIX)
&& boundSql.hasAdditionalParameter(prop.getName())) {
value = boundSql.getAdditionalParameter(prop.getName());
if (value != null) {
value = configuration.newMetaObject(value)
.getValue(
propertyName.substring(prop
.getName().length()));
}
} else {
value = metaObject == null ? null : metaObject
.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
if (typeHandler == null) {
throw new ExecutorException(
"There was no TypeHandler found for parameter "
+ propertyName + " of statement "
+ mappedStatement.getId());
}
typeHandler.setParameter(ps, i + 1, value,
parameterMapping.getJdbcType());
}
}
}
}
/**
* 拦截方法
* */
@Override
public Object intercept(Invocation ivk) throws Throwable {
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)) {
BoundSql boundSql = delegate.getBoundSql();
Object parameterObject = boundSql.getParameterObject();
if (parameterObject == null) {
throw new NullPointerException("parameterObject error");
} else {
Connection connection = (Connection) ivk.getArgs()[0];
String sql = boundSql.getSql();
String mappedStatementCount=mappedStatement.getId()+"Count";
String countSql = "select count(0) from (" + sql + ") myCount";
try{
MappedStatement countMaped= mappedStatement.getConfiguration().getMappedStatement(mappedStatementCount);
countSql=countMaped.getBoundSql(parameterObject).getSql();
}catch(Exception e){
log.debug("查询总条数SQL未配置");
}
log.debug("sql statement : "+countSql);
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();
PageModel<?> page = null;
if (parameterObject instanceof PageModel) {
page = (PageModel<?>) parameterObject;
page.setTotalSize(count);// .setTotalResult(count);
log.debug("Total Size : "+count);
} else if(parameterObject instanceof Map){
Map<String, Object> map = (Map<String, Object>)parameterObject;
page = (PageModel<?>)map.get("page");
if(page == null){
page = new PageModel();
}
page.setTotalSize(count);
log.debug("Total Size : "+count);
}else {
Field pageField = ReflectHelper.getFieldByFieldName(
parameterObject, "page");
if (pageField != null) {
page = (PageModel<?>) ReflectHelper.getValueByFieldName(
parameterObject, "page");
if (page == null)
page = new PageModel();
page.setTotalSize(count);
log.debug("Total Size : "+count);
ReflectHelper.setValueByFieldName(parameterObject,
"page", page);
} else {
throw new NoSuchFieldException(parameterObject
.getClass().getName());
}
}
//add the pagination plugin for mybaits
//debug the page info for the pageList,pageSize
log.debug("pageInfo : "+page.toString());
String pageSql = generatePageSql(sql, page);
log.debug("page sql : "+pageSql);
ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql);
}
}
}
return ivk.proceed();
}
@Override
public Object plugin(Object arg0) {
return Plugin.wrap(arg0, this);
}
@Override
public void setProperties(Properties p) {
dialect = p.getProperty("dialect");
if (dialect ==null || dialect.equals("")) {
try {
throw new PropertyException("dialect property is not found!");
} catch (PropertyException e) {
e.printStackTrace();
}
}
pageSqlId = p.getProperty("pageSqlId");
if (dialect ==null || dialect.equals("")) {
try {
throw new PropertyException("pageSqlId property is not found!");
} catch (PropertyException e) {
e.printStackTrace();
}
}
}
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
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 org.apache.log4j.Logger;
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationPluginForMybaits implements Interceptor {
private static Logger log = Logger.getLogger(PaginationPluginForMybaits.class);
private String dialect = "";
private String pageSqlId = "";
/**
* 生成分页的sql语句
* */
private String generatePageSql(String sql, PageModel<?> page) {
if (page != null && (dialect !=null || !dialect.equals(""))) {
StringBuffer pageSql = new StringBuffer();
if ("mysql".equals(dialect)) {
pageSql.append(sql);
pageSql.append(" limit " + page.getCurrentPageStartIndex() + ","
+ page.getPageSize());
} else if ("oracle".equals(dialect)) {
pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from (");
pageSql.append(sql);
pageSql.append(") tmp_tb where ROWNUM<=");
pageSql.append(page.getCurrentPageStartIndex() + page.getPageSize());
pageSql.append(") where row_id>");
pageSql.append(page.getCurrentPageStartIndex());
}
return pageSql.toString();
} else {
return sql;
}
}
/**
* 设置参数
* */
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 propertyName = parameterMapping.getProperty();
PropertyTokenizer prop = new PropertyTokenizer(propertyName);
if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry
.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else if (boundSql.hasAdditionalParameter(propertyName)) {
value = boundSql.getAdditionalParameter(propertyName);
} else if (propertyName
.startsWith(ForEachSqlNode.ITEM_PREFIX)
&& boundSql.hasAdditionalParameter(prop.getName())) {
value = boundSql.getAdditionalParameter(prop.getName());
if (value != null) {
value = configuration.newMetaObject(value)
.getValue(
propertyName.substring(prop
.getName().length()));
}
} else {
value = metaObject == null ? null : metaObject
.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
if (typeHandler == null) {
throw new ExecutorException(
"There was no TypeHandler found for parameter "
+ propertyName + " of statement "
+ mappedStatement.getId());
}
typeHandler.setParameter(ps, i + 1, value,
parameterMapping.getJdbcType());
}
}
}
}
/**
* 拦截方法
* */
@Override
public Object intercept(Invocation ivk) throws Throwable {
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)) {
BoundSql boundSql = delegate.getBoundSql();
Object parameterObject = boundSql.getParameterObject();
if (parameterObject == null) {
throw new NullPointerException("parameterObject error");
} else {
Connection connection = (Connection) ivk.getArgs()[0];
String sql = boundSql.getSql();
String mappedStatementCount=mappedStatement.getId()+"Count";
String countSql = "select count(0) from (" + sql + ") myCount";
try{
MappedStatement countMaped= mappedStatement.getConfiguration().getMappedStatement(mappedStatementCount);
countSql=countMaped.getBoundSql(parameterObject).getSql();
}catch(Exception e){
log.debug("查询总条数SQL未配置");
}
log.debug("sql statement : "+countSql);
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();
PageModel<?> page = null;
if (parameterObject instanceof PageModel) {
page = (PageModel<?>) parameterObject;
page.setTotalSize(count);// .setTotalResult(count);
log.debug("Total Size : "+count);
} else if(parameterObject instanceof Map){
Map<String, Object> map = (Map<String, Object>)parameterObject;
page = (PageModel<?>)map.get("page");
if(page == null){
page = new PageModel();
}
page.setTotalSize(count);
log.debug("Total Size : "+count);
}else {
Field pageField = ReflectHelper.getFieldByFieldName(
parameterObject, "page");
if (pageField != null) {
page = (PageModel<?>) ReflectHelper.getValueByFieldName(
parameterObject, "page");
if (page == null)
page = new PageModel();
page.setTotalSize(count);
log.debug("Total Size : "+count);
ReflectHelper.setValueByFieldName(parameterObject,
"page", page);
} else {
throw new NoSuchFieldException(parameterObject
.getClass().getName());
}
}
//add the pagination plugin for mybaits
//debug the page info for the pageList,pageSize
log.debug("pageInfo : "+page.toString());
String pageSql = generatePageSql(sql, page);
log.debug("page sql : "+pageSql);
ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql);
}
}
}
return ivk.proceed();
}
@Override
public Object plugin(Object arg0) {
return Plugin.wrap(arg0, this);
}
@Override
public void setProperties(Properties p) {
dialect = p.getProperty("dialect");
if (dialect ==null || dialect.equals("")) {
try {
throw new PropertyException("dialect property is not found!");
} catch (PropertyException e) {
e.printStackTrace();
}
}
pageSqlId = p.getProperty("pageSqlId");
if (dialect ==null || dialect.equals("")) {
try {
throw new PropertyException("pageSqlId property is not found!");
} catch (PropertyException e) {
e.printStackTrace();
}
}
}
}
相关文章推荐
- 用HAProxy和KeepAlived构建高可用的反向代理
- poj2909 || poj2262
- ORACLE 管理 安全与审计
- 关于array objectAtIndex 出来的model 的内存地址的注意
- 开源作品-PHP写的JS和CSS文件压缩利器(单文件绿色版)-SuMinify_PHP_1_5
- 学习Axure的小列子(滚动条)
- Valid Palindrome
- Codeforces Round #261 (Div. 2) D. Pashmak and Parmida's problem (树状数组)
- JavaScript Number 对象 Javascript Array对象 Location 对象方法 String对象方法
- Linux下磁盘挂载
- [Erlang]supervisor的child设置为dynamic详解
- Revo Uninstaller Pro v3.1.2 测试和评测:
- ORACLE 管理 存储与ASM
- SPRING JDBC详细使用
- spring MVC 2-helloword 入门
- Axis2
- hdu 1052 (greedy algorithm)
- Duang一夏,安码企业流程化管控软件优惠季来了! 活动介绍
- jQuery收藏链接
- HashMap,Hashset,ArrayList以及LinkedList集合的区别,以及各自的用法