import com.mybatis.page.support.PageSqlGenerator; import com.mybatis.page.support.OraclePagerSqlGenerator; import com.mybatis.page.support.PageRowBounds; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Properties; @Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})) public class PagePlugin implements Interceptor { private static PageSqlGenerator sqlGenerator = new OraclePagerSqlGenerator(); @Override public Object intercept(Invocation invocation) throws Throwable { final Object[] args = invocation.getArgs(); RowBounds rowBounds = (RowBounds) args[2]; if (rowBounds instanceof PageRowBounds) { Executor executor = (Executor) invocation.getTarget(); MappedStatement mappedStatement = (MappedStatement) args[0]; Object parameter = args[1]; PageRowBounds pageRowBounds = (PageRowBounds) args[2]; ResultHandler resultHandler = (ResultHandler) args[3]; BoundSql boundSql = mappedStatement.getBoundSql(parameter); PageSqlSqlSource sqlSource = new PageSqlSqlSource(boundSql); MappedStatement statement = buildMappedStatement(mappedStatement, sqlSource); MetaObject msObject = SystemMetaObject.forObject(statement); msObject.setValue("sqlSource.boundSql.sql", sqlGenerator.getPagerSql(boundSql.getSql(), rowBounds)); args[0] = statement; StatementHandler statementHandler = mappedStatement.getConfiguration().newStatementHandler(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql); ResultSet rs = null; try (PreparedStatement stmt = executor.getTransaction().getConnection().prepareStatement(sqlGenerator.getCountSql(boundSql.getSql()))) { statementHandler.parameterize(stmt); rs = stmt.executeQuery(); int totalCount = 0; if (rs.next()) { totalCount = rs.getInt("totalCount"); } pageRowBounds.setTotalCount(totalCount); } finally { if (rs != null) { try { rs.close(); } catch (Throwable ignored) { } } } } return invocation.proceed(); } @Override public Object plugin(Object target) { if (target instanceof Executor) { return Plugin.wrap(target, this); } else { return target; } } @Override public void setProperties(Properties properties) {} private class PageSqlSqlSource implements SqlSource { BoundSql boundSql; public PageSqlSqlSource(BoundSql boundSql) { this.boundSql = boundSql; } public BoundSql getBoundSql(Object parameterObject) { return boundSql; } } private MappedStatement buildMappedStatement(MappedStatement ms, SqlSource sqlSource) { MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), sqlSource, ms.getSqlCommandType()); builder.resource(ms.getResource()); builder.fetchSize(ms.getFetchSize()); builder.statementType(ms.getStatementType()); builder.keyGenerator(ms.getKeyGenerator()); if (ms.getKeyProperties() != null && ms.getKeyProperties().length != 0) { StringBuilder keyProperties = new StringBuilder(); for (String keyProperty : ms.getKeyProperties()) { keyProperties.append(keyProperty).append(","); } keyProperties.delete(keyProperties.length() - 1, keyProperties.length()); builder.keyProperty(keyProperties.toString()); } builder.timeout(ms.getTimeout()); builder.parameterMap(ms.getParameterMap()); builder.resultMaps(ms.getResultMaps()); builder.resultSetType(ms.getResultSetType()); builder.cache(ms.getCache()); builder.flushCacheRequired(ms.isFlushCacheRequired()); builder.useCache(ms.isUseCache()); return builder.build(); } }
import org.apache.ibatis.session.RowBounds; public class PageRowBounds extends RowBounds { public final static int NO_TOTAL_COUNT = -1; private int totalCount = NO_TOTAL_COUNT; public PageRowBounds() { super(); } public PageRowBounds(int offset, int limit) { super(offset, limit); } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public int getTotalCount() { return totalCount; } }
import org.apache.ibatis.session.RowBounds; public interface PageSqlGenerator { public String getPagerSql(String sql, RowBounds rowBounds); public String getCountSql(String sql); }
import org.apache.ibatis.session.RowBounds; public class OraclePagerSqlGenerator implements PageSqlGenerator { public String getPagerSql(String sql, RowBounds rowBounds) { if (rowBounds.getLimit() == Integer.MAX_VALUE) { return sql; } else { return getPagerSql(sql, rowBounds.getOffset(), rowBounds.getLimit()); } } public String getPagerSql(String sql, int offset, int limit) { return "select * from (select inrow.*, rownum rn from (" + sql + ") inrow where rownum <=" + (limit + offset) + ") where rn >= " + offset; } public String getCountSql(String sql) { return "select count(*) totalCount from (" + sql + ")"; } }
配置文件
在mybatis配置文件中添加
<plugins> <plugin interceptor="com.mybatis.page.plugins.PagePlugin"/> </plugins>
测试代码
@Test public void testPage() throws Exception { PageRowBounds pageRowBounds = new PageRowBounds(0,3); HashMap<String,String> hashMap = Maps.newHashMap(); hashMap.put("name","男"); List<Student> students = sqlSession.selectList("com.mybatis.mapper.StudentMapper.page",hashMap,pageRowBounds); System.out.println(pageRowBounds.getTotalCount()); students.forEach(System.out::println); pageRowBounds = new PageRowBounds(0,5); students = sqlSession.selectList("com.mybatis.mapper.StudentMapper.page",hashMap,pageRowBounds); System.out.println(pageRowBounds.getTotalCount()); for(Student student : students){ System.out.println(student); } }
总结:随便写写的,嘿嘿。
时间: 2024-10-10 09:12:47