(一)關於分頁攔截器的簡單理解
首先,要開發MyBatis的插件須要實現org.apache.ibatis.plugin.Interceptor接口,這個接口將會要求實現幾個方法:intercept()、plugin()及setProperties(),intercept方法是開發人員所要執行的操做,plugin是將你插件放入到MyBatis的插件集合中去,而setProperties這是在你配置你插件的時候將plugins/plugin/properties的值設置到該插件中。
該方法的第一句話就是得到Intercepts註解,接下來將得到在Intercepts裏面的參數@Signature註解內容,在該註解中包含三個參數,分別是type,method,args。Type指定要攔截的類對象,method是指明要攔截該類的哪一個方法,第三個是指明要攔截的方法參數集合。在Intercepts中能夠配置多個@Signature。那麼便對這寫值進行遍歷,已得到對應的type、method以及args。最終是得到一個HashMap對象,這些對象裏面的鍵是類對象,而值是指定的類中方法對象。執行該端程序以後,更具target的classLoader和接口,來建立一個代理,而且,InvocationHandler是建立一個新的Plugin對象,同時將target,interceptor以及signatureMap傳遞給Plugin對象,固然,這裏的Plugin也實現了Invocation接口。那麼target對象全部的方法調用都會觸發Plugin中的invoke方法,那麼這裏將執行開發者全部插入的操做。html
另外對攔截器類裏面幾個關鍵的類作出解釋:java
(1)BoundSql類 ,封裝mybatis最終產生sql的類,包括sql語句,參數,參數源數據等。
(2)MappedStatement類,MappedStatement類在Mybatis框架中用於表示XML文件中一個sql語句節點,即一個<select />、<update />或者<insert />標籤。Mybatis框架在初始化階段會對XML配置文件進行讀取,將其中的sql語句節點對象化爲一個個MappedStatement對象。spring
總結,本攔截器實現的目標就是在進行數據庫查詢操做以前,從配置文件讀出相應的sql語句,將相應的參數拼接到其中,而後再進行查詢。固然在拼接sql語句以前,先查詢了一下數據庫中相應記錄的總數sql
(二)攔截器類PageIntercepter.java:
- package cn.zyy.paging.intercepter;
-
- 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 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.mapping.SqlSource;
- 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.reflection.MetaObject;
- import org.apache.ibatis.session.Configuration;
- import org.apache.ibatis.session.RowBounds;
- import org.apache.ibatis.type.TypeHandler;
- import org.apache.ibatis.type.TypeHandlerRegistry;
- import cn.zyy.paging.vo.PageObject;
- @Intercepts({@org.apache.ibatis.plugin.Signature(method="query", type=org.apache.ibatis.executor.Executor.class, args={MappedStatement.class, Object.class, RowBounds.class, org.apache.ibatis.session.ResultHandler.class})})
- public class PageIntercepter implements Interceptor{
- @Override
- public Object intercept(Invocation invocation) throws Throwable {
- MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
- Object object = invocation.getArgs()[1];
- if(object instanceof PageObject){
-
- PageObject pageObject = (PageObject) object;
- BoundSql boundSql = mappedStatement.getBoundSql(object);
- String sql = boundSql.getSql();
-
- int count = getCount(mappedStatement,boundSql);
- pageObject.setCount(count);
- int pages = (pageObject.getCount()+pageObject.getNumber()-1)/pageObject.getNumber();
- pageObject.setPages(pages>0?pages:1);
-
- int offset = (pageObject.getPage() - 1) * pageObject.getNumber();
- int limit = pageObject.getNumber();
- String pageSql = pageSql(sql, offset, limit);
- BoundSql pageBoundSql = new BoundSql(mappedStatement.getConfiguration(), pageSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
- MappedStatement pageMappedStatement = pageMappedStatement(mappedStatement, new PageSqlSource(pageBoundSql));
- invocation.getArgs()[0] = pageMappedStatement;
- invocation.getArgs()[2] = RowBounds.DEFAULT;
- }
- return invocation.proceed();
- }
-
- @Override
- public Object plugin(Object object) {
-
- return Plugin.wrap(object, this);
- }
-
- @Override
- public void setProperties(Properties properties) {
-
-
- }
-
- private int getCount(MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {
-
- Connection connection = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
-
- try {
- String countSql = countSql(boundSql.getSql());
- connection = mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection();
- ps = connection.prepareStatement(countSql);
- BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
- setCountParameters(ps, mappedStatement, countBoundSql);
- rs = ps.executeQuery();
- int count = 0;
- if (rs.next())
- {
- count = rs.getInt(1);
- }
- return count;
- } catch (Exception e) {
- return 1000;
- }finally{
- try {
- rs.close();
- } catch (Exception localException4) {
- }
- try {
- ps.close();
- } catch (Exception localException5) {
- }
- try {
- connection.close();
- }
- catch (Exception localException6) {
- }
- }
- }
-
- private static String countSql(String sql){
- sql = sql.toUpperCase();
- StringBuffer countSql = new StringBuffer();
- countSql.append("SELECT COUNT(1) FROM (");
- countSql.append(sql.substring(0, sql.indexOf("ORDER BY")==-1?sql.length():sql.indexOf("ORDER BY")-1));
- countSql.append(") PAY_PAGE_T");
- return countSql.toString();
- }
-
- private static void setCountParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {
- List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();
- if (parameterMappingList != null)
- {
- Configuration configuration = mappedStatement.getConfiguration();
- TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
- Object parameterObject = boundSql.getParameterObject();
- MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
-
- int n = 1;
- for (ParameterMapping parameterMapping : parameterMappingList)
- {
- if ((parameterMapping.getMode() == ParameterMode.IN) || (parameterMapping.getMode() == ParameterMode.INOUT))
- {
- String property = parameterMapping.getProperty();
- Object value = null;
- if (parameterObject != null)
- {
- if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))
- {
- value = parameterObject;
- }
- else
- {
- value = metaObject == null ? null : metaObject.getValue(property);
- }
- }
-
- TypeHandler typeHandler = parameterMapping.getTypeHandler();
- typeHandler.setParameter(ps, n, value, parameterMapping.getJdbcType());
- }
-
- n++;
- }
- }
- }
-
- private String pageSql(String sql, int offset, int limit) {
- sql = sql.toUpperCase();
- StringBuffer pageSql = new StringBuffer();
- pageSql.append(sql);
- pageSql.append(" LIMIT ");
- pageSql.append(offset);
- pageSql.append(", ");
- pageSql.append(limit);
- return pageSql.toString();
- }
-
- private MappedStatement pageMappedStatement(MappedStatement mappedStatement, SqlSource sqlSource)
- {
- MappedStatement.Builder builder = new MappedStatement.Builder(
- mappedStatement.getConfiguration(),
- mappedStatement.getId(),
- sqlSource,
- mappedStatement.getSqlCommandType());
-
- builder.resource(mappedStatement.getResource());
- builder.fetchSize(mappedStatement.getFetchSize());
- builder.statementType(mappedStatement.getStatementType());
- builder.keyGenerator(mappedStatement.getKeyGenerator());
- builder.timeout(mappedStatement.getTimeout());
- builder.parameterMap(mappedStatement.getParameterMap());
- builder.resultMaps(mappedStatement.getResultMaps());
- builder.cache(mappedStatement.getCache());
- builder.resultSetType(mappedStatement.getResultSetType());
- builder.flushCacheRequired(mappedStatement.isFlushCacheRequired());
- builder.useCache(mappedStatement.isUseCache());
- builder.resultOrdered(mappedStatement.isResultOrdered());
- builder.databaseId(mappedStatement.getDatabaseId());
- builder.lang(mappedStatement.getLang());
- if (mappedStatement.getKeyProperties() != null)
- {
- for (String keyProperty : mappedStatement.getKeyProperties())
- {
- builder.keyProperty(keyProperty);
- }
- }
- if (mappedStatement.getKeyColumns() != null)
- {
- for (String keyColumn : mappedStatement.getKeyColumns())
- {
- builder.keyColumn(keyColumn);
- }
- }
-
- return builder.build();
- }
-
- public static class PageSqlSource implements SqlSource {
- private BoundSql boundSql;
-
- public PageSqlSource(BoundSql boundSql) {
- this.boundSql = boundSql;
- }
-
- public BoundSql getBoundSql(Object parameterObject)
- {
- return this.boundSql;
- }
- }
-
- }
(三)spring配置文件和mybatis配置文件
mybatis配置文件中主要是配置相關的vo類和攔截器數據庫
[html] view plain copyexpress