<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    badqiu

    XPer
    隨筆 - 46, 文章 - 3, 評論 - 195, 引用 - 0
    數據加載中……

    ibatis3基于方言的分頁

    (注:以下代碼是基于ibatis3 beta4的擴展,ibatis3正式版如果實現改變,將會繼續跟進修改)

     

     

    iBatis3默認使用的分頁是基于游標的分頁,而這種分頁在不同的數據庫上性能差異不一致,最好的辦法當然是使用類似hibernate的基于方言(Dialect)的物理分頁功能。

    iBatis3現在提供插件功能,通過插件我們可以編寫自己的攔截器來攔截iBatis3的主要執行方法來完成相關功能的擴展。

     

     

     

    能夠攔截的的類如下:

     

    Java代碼 
    1. Executor  
    2.     (update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)  
    3. ParameterHandler  
    4.     (getParameterObject,setParameters)  
    5. ResultSetHandler  
    6.     (handleResultSets,handleOutputParameters)  
    7. StatementHandler  
    8.     (prepare,parameterize,batch,update,query)  

     

     但此次我們感興趣的是Executor.query()方法,查詢方法最終都是執行該方法。

    該方法完整是:

     

    Java代碼 
    1. Executor.query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;  

     

     

    分頁方言的基本實現:

    以Mysql數據庫示例,即有一個方法 query(sql,offset,limit);

     

     

    Java代碼 
    1. query("select * from user",5,10);  
     

     

    經過我們的攔截器攔截處理,變成

     

    Java代碼 
    1. query("select * from user limit 5,10",0,0);  
     

     

    1.攔截類實現:

     

    Java代碼 
    1. @Intercepts({@Signature(  
    2.         type= Executor.class,  
    3.         method = "query",  
    4.         args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})  
    5. public class OffsetLimitInterceptor implements Interceptor{  
    6.     static int MAPPED_STATEMENT_INDEX = 0;  
    7.     static int PARAMETER_INDEX = 1;  
    8.     static int ROWBOUNDS_INDEX = 2;  
    9.     static int RESULT_HANDLER_INDEX = 3;  
    10.       
    11.     Dialect dialect;  
    12.       
    13.     public Object intercept(Invocation invocation) throws Throwable {  
    14.         processIntercept(invocation.getArgs());  
    15.         return invocation.proceed();  
    16.     }  
    17.   
    18.     void processIntercept(final Object[] queryArgs) {  
    19.         //queryArgs = query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)  
    20.         MappedStatement ms = (MappedStatement)queryArgs[MAPPED_STATEMENT_INDEX];  
    21.         Object parameter = queryArgs[PARAMETER_INDEX];  
    22.         final RowBounds rowBounds = (RowBounds)queryArgs[ROWBOUNDS_INDEX];  
    23.         int offset = rowBounds.getOffset();  
    24.         int limit = rowBounds.getLimit();  
    25.           
    26.         if(dialect.supportsLimit() && (offset != RowBounds.NO_ROW_OFFSET || limit != RowBounds.NO_ROW_LIMIT)) {  
    27.             BoundSql boundSql = ms.getBoundSql(parameter);  
    28.             String sql = boundSql.getSql().trim();  
    29.             if (dialect.supportsLimitOffset()) {  
    30.                 sql = dialect.getLimitString(sql, offset, limit);  
    31.                 offset = RowBounds.NO_ROW_OFFSET;  
    32.             } else {  
    33.                 sql = dialect.getLimitString(sql, 0, limit);  
    34.             }  
    35.             limit = RowBounds.NO_ROW_LIMIT;  
    36.               
    37.             queryArgs[ROWBOUNDS_INDEX] = new RowBounds(offset,limit);  
    38.             BoundSql newBoundSql = new BoundSql(sql, boundSql.getParameterMappings(), boundSql.getParameterObject());  
    39.             MappedStatement newMs = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));  
    40.             queryArgs[MAPPED_STATEMENT_INDEX] = newMs;  
    41.         }  
    42.     }  
    43.       
    44.     private MappedStatement copyFromMappedStatement(MappedStatement ms,SqlSource newSqlSource) {  
    45.         Builder builder = new MappedStatement.Builder(ms.getConfiguration(),ms.getId(),newSqlSource,ms.getSqlCommandType());  
    46.         builder.resource(ms.getResource());  
    47.         builder.fetchSize(ms.getFetchSize());  
    48.         builder.statementType(ms.getStatementType());  
    49.         builder.keyGenerator(ms.getKeyGenerator());  
    50.         builder.keyProperty(ms.getKeyProperty());  
    51.         builder.timeout(ms.getTimeout());  
    52.         builder.parameterMap(ms.getParameterMap());  
    53.         builder.resultMaps(ms.getResultMaps());  
    54.         builder.cache(ms.getCache());  
    55.         MappedStatement newMs = builder.build();  
    56.         return newMs;  
    57.     }  
    58.   
    59.     public Object plugin(Object target) {  
    60.         return Plugin.wrap(target, this);  
    61.     }  
    62.   
    63.     public void setProperties(Properties properties) {  
    64.         String dialectClass = new PropertiesHelper(properties).getRequiredString("dialectClass");  
    65.         try {  
    66.             dialect = (Dialect)Class.forName(dialectClass).newInstance();  
    67.         } catch (Exception e) {  
    68.             throw new RuntimeException("cannot create dialect instance by dialectClass:"+dialectClass,e);  
    69.         }   
    70.         System.out.println(OffsetLimitInterceptor.class.getSimpleName()+".dialect="+dialectClass);  
    71.     }  
    72.       
    73.     public static class BoundSqlSqlSource implements SqlSource {  
    74.         BoundSql boundSql;  
    75.         public BoundSqlSqlSource(BoundSql boundSql) {  
    76.             this.boundSql = boundSql;  
    77.         }  
    78.         public BoundSql getBoundSql(Object parameterObject) {  
    79.             return boundSql;  
    80.         }  
    81.     }  
    82.       
    83. }  
     

     

    2.ibatis3配置文件內容:

    Xml代碼 
    1. <configuration>  
    2.     <plugins>  
    3.         <!-- 指定數據庫分頁方言Dialect, 其它方言:OracleDialect,SQLServerDialect,SybaseDialect,DB2Dialect,PostgreSQLDialect,MySQLDialect,DerbyDialect-->  
    4.         <plugin interceptor="cn.org.rapid_framework.ibatis3.plugin.OffsetLimitInterceptor">  
    5.             <property name="dialectClass" value="cn.org.rapid_framework.jdbc.dialect.MySQLDialect"/>  
    6.         </plugin>  
    7.     </plugins>  
    8.   
    9.     <environments default="development">  
    10.         <environment id="development">  
    11.             <transactionManager type="JDBC" />  
    12.             <dataSource type="POOLED">  
    13.                 <property name="driver" value="com.mysql.jdbc.Driver" />  
    14.                 <property name="url" value="jdbc:mysql://localhost:3306/test" />  
    15.                 <property name="username" value="root" />  
    16.                 <property name="password" value="123456" />  
    17.             </dataSource>  
    18.         </environment>  
    19.     </environments>  
    20.   
    21.     <mappers>  
    22.         <mapper resource="com/company/project/model/mapper/BlogMapper.xml" />  
    23.     </mappers>  
    24. </configuration>  
     

    3.MysqlDialect實現

    Java代碼 
    1. public class MySQLDialect extends Dialect{  
    2.   
    3.     public boolean supportsLimitOffset(){  
    4.         return true;  
    5.     }  
    6.       
    7.     public boolean supportsLimit() {     
    8.         return true;     
    9.     }    
    10.       
    11.     public String getLimitString(String sql, int offset, int limit) {  
    12.             return getLimitString(sql,offset,String.valueOf(offset),limit,String.valueOf(limit));  
    13.     }  
    14.       
    15.     public String getLimitString(String sql, int offset,String offsetPlaceholder, int limit, String limitPlaceholder) {  
    16.         if (offset > 0) {     
    17.             return sql + " limit "+offsetPlaceholder+","+limitPlaceholder;   
    18.         } else {     
    19.             return sql + " limit "+limitPlaceholder;  
    20.         }    
    21.     }     
    22.     
    23. }  

     

    其它數據庫的Dialect實現請查看:

    http://rapid-framework.googlecode.com/svn/trunk/rapid-framework/src/rapid_framework_common/cn/org/rapid_framework/jdbc/dialect/

     

    4.分頁使用

    直接調用SqlSession.selectList(statement, parameter, new RowBounds(offset,limit))即可使用物理分頁

     

    5.存在的問題

    現不是使用占位符的方式(即不是“limit ?,?”而是使用“limit 8,20”)使用分頁

     

    完整代碼可以查看即將發布的rapid-framework 3.0的ibatis3插件

     

    posted on 2009-10-20 09:04 badqiu 閱讀(3950) 評論(5)  編輯  收藏

    評論

    # re: ibatis3基于方言的分頁  回復  更多評論   

    sqlserver2000怎么辦,oracle怎么辦,db2怎么辦。。。mysql分頁是最簡單的數據庫了。
    2009-11-01 18:10 | spingNo1

    # re: ibatis3基于方言的分頁[未登錄]  回復  更多評論   

    問這個問題前請先仔細再看一下文章內容.
    2009-11-01 19:02 | badqiu

    # re: ibatis3基于方言的分頁  回復  更多評論   

    rapid-framework 3.0的ibatis3插件不錯
    2009-12-17 14:07 | 團派家園

    # re: ibatis3基于方言的分頁  回復  更多評論   

    rapid-framework 好東西啊
    2010-06-04 10:38 | king2ksu

    # re: ibatis3基于方言的分頁  回復  更多評論   

    BoundSql newBoundSql = new BoundSql(sql, boundSql.getParameterMappings(), boundSql.getParameterObject());
    有錯因為BoundSql的構造函數如下,少傳了configuration,應該怎么改呀
    public BoundSql(Configuration configuration, String sql, List parameterMappings, Object parameterObject)

    2011-06-16 17:40 | wypsmall

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲欧洲校园自拍都市| 国产亚洲精品国产福利在线观看 | 一边摸一边桶一边脱免费视频| 区久久AAA片69亚洲| 91免费播放人人爽人人快乐| 亚洲AV无码一区二区三区鸳鸯影院| 久久亚洲av无码精品浪潮| 97视频免费观看2区| 国产成人va亚洲电影| 亚洲国产成人私人影院| 浮力影院第一页小视频国产在线观看免费 | 亚洲丁香婷婷综合久久| 亚洲国产日韩在线视频| 久久久久国产精品免费免费搜索 | 四虎影院免费在线播放| 97无码人妻福利免费公开在线视频| 亚洲自国产拍揄拍| 国产精品亚洲一区二区三区在线 | 亚洲精品无码成人片在线观看| 91免费福利精品国产| 久青草国产免费观看| 亚洲Av无码一区二区二三区| 不卡一卡二卡三亚洲| 免费看AV毛片一区二区三区| 无码精品一区二区三区免费视频 | 亚洲欧洲高清有无| 日韩一卡2卡3卡4卡新区亚洲 | 亚洲va中文字幕无码久久不卡| 日本免费人成视频播放| 免费观看无遮挡www的小视频| 四虎精品成人免费视频| 亚洲中文字幕久久精品蜜桃| 亚洲伊人久久大香线蕉苏妲己| 亚洲国产综合人成综合网站| 女人张腿给男人桶视频免费版| 5g影院5g天天爽永久免费影院| 人成电影网在线观看免费| 亚洲成a人片在线观看天堂无码| 亚洲精品在线不卡| 亚洲av成人无码久久精品| 久久久久久久亚洲精品|