packagecom.jsoft.testmybatis.util;importjava.lang.reflect.Field;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.util.List;importjava.util.Map;importjava.util.Properties;importjavax.xml.bind.PropertyException;importorg.apache.ibatis.scripting.xmltags.ForEachSqlNode;importorg.apache.ibatis.executor.ErrorContext;importorg.apache.ibatis.executor.ExecutorException;importorg.apache.ibatis.executor.statement.BaseStatementHandler;importorg.apache.ibatis.executor.statement.RoutingStatementHandler;importorg.apache.ibatis.executor.statement.StatementHandler;importorg.apache.ibatis.mapping.BoundSql;importorg.apache.ibatis.mapping.MappedStatement;importorg.apache.ibatis.mapping.ParameterMapping;importorg.apache.ibatis.mapping.ParameterMode;importorg.apache.ibatis.plugin.Interceptor;importorg.apache.ibatis.plugin.Intercepts;importorg.apache.ibatis.plugin.Invocation;importorg.apache.ibatis.plugin.Plugin;importorg.apache.ibatis.plugin.Signature;importorg.apache.ibatis.reflection.MetaObject;importorg.apache.ibatis.reflection.property.PropertyTokenizer;importorg.apache.ibatis.session.Configuration;importorg.apache.ibatis.type.TypeHandler;importorg.apache.ibatis.type.TypeHandlerRegistry;
@Intercepts({ @Signature(type= StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class}) })public class PagePlugin implementsInterceptor {private static String dialect = "";private static String pageSqlId = "";
@SuppressWarnings("unchecked")public Object intercept(Invocation ivk) throwsThrowable {if (ivk.getTarget() instanceofRoutingStatementHandler) {
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 countSql= "select count(0) from (" + sql + ") myCount";
System.out.println("总数sql 语句:" +countSql);
PreparedStatement countStmt=connection.prepareStatement(countSql);
BoundSql countBS= newBoundSql(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();
PageInfo page= null;if (parameterObject instanceofPageInfo) {
page=(PageInfo) parameterObject;
page.setTotalResult(count);
}else if (parameterObject instanceofMap) {
Map map = (Map) parameterObject;
page= (PageInfo) map.get("page");if (page == null)
page= newPageInfo();
page.setTotalResult(count);
}else{
Field pageField= ReflectHelper.getFieldByFieldName(parameterObject, "page");if (pageField != null) {
page= (PageInfo) ReflectHelper.getValueByFieldName(parameterObject, "page");if (page == null)
page= newPageInfo();
page.setTotalResult(count);
ReflectHelper.setValueByFieldName(parameterObject,"page", page);
}else{throw newNoSuchFieldException(parameterObject.getClass().getName());
}
}
String pageSql=generatePageSql(sql, page);
System.out.println("page sql:" +pageSql);
ReflectHelper.setValueByFieldName(boundSql,"sql", pageSql);
}
}
}returnivk.proceed();
}private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throwsSQLException {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List 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= newPropertyTokenizer(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());
}
}
}
}privateString generatePageSql(String sql, PageInfo page) {if (page != null && (dialect != null || !dialect.equals(""))) {
StringBuffer pageSql= newStringBuffer();if ("mysql".equals(dialect)) {
pageSql.append(sql);
pageSql.append(" limit " + page.getCurrentResult() + "," +page.getShowCount());
}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.getCurrentResult()+page.getShowCount());
pageSql.append(") where row_id>");
pageSql.append(page.getCurrentResult());
}returnpageSql.toString();
}else{returnsql;
}
}publicObject plugin(Object arg0) {//TODO Auto-generated method stub
return Plugin.wrap(arg0, this);
}public voidsetProperties(Properties p) {
dialect= p.getProperty("dialect");if (dialect == null || dialect.equals("")) {try{throw new PropertyException("dialect property is not found!");
}catch(PropertyException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
pageSqlId= p.getProperty("pageSqlId");if (dialect == null || dialect.equals("")) {try{throw new PropertyException("pageSqlId property is not found!");
}catch(PropertyException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}