日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php框架 > 框架設計 > 深入淺出Mybatis-分頁

深入淺出Mybatis-分頁

來源:程序員人生   發布時間:2017-03-20 09:51:41 閱讀次數:8317次

Mybatis的分頁功能很弱,它是基于內存的分頁(查出所有記錄再按偏移量和limit取結果),在大數據量的情況下這樣的分頁基本上是沒有用的。本文基于插件,通過攔截StatementHandler重寫sql語句,實現數據庫的物理分頁。本文適配的mybatis版本是3.2.2

準備

為何在StatementHandler攔截

深入淺出MyBatis-Sqlsession章節介紹了1次sqlsession的完全履行進程,從中可以知道sql的解析是在StatementHandler里完成的,所以為了重寫sql需要攔截StatementHandler

MetaObject簡介

在我的實現里大量使用了MetaObject這個對象,因此有必要先介紹下它。MetaObjectMybatis提供的1個的工具類,通過它包裝1個對象后可以獲得或設置該對象的本來不可訪問的屬性(比如那些私有屬性)。它有個3個重要方法常常用到:

1)       MetaObject forObject(Object object,ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory)

2)       Object getValue(String name)

3)       void setValue(String name, Object value)

方法1)用于包裝對象;方法2)用于獲得屬性的值(支持OGNL的方法);方法3)用于設置屬性的值(支持OGNL的方法);

插件的原理

參見深入淺出Mybatis-插件原理

 

有了上面這些基礎知識的準備后,就能夠我們的主題了。

攔截器簽名

[java] view plain copy
  1. @Intercepts({@Signature(type =StatementHandler.class, method = "prepare", args ={Connection.class})})  
  2. publicclass PageInterceptor implementsInterceptor {  
  3. ...  
  4. }  

從簽名里可以看出,要攔截的目標類型是StatementHandler(注意:type只能配置成接口類型),攔截的方法是名稱為prepare參數為Connection類型的方法。

intercept的實現

[java] view plain copy
  1. public Object intercept(Invocation invocation) throws Throwable {  
  2.      StatementHandler statementHandler = (StatementHandler) invocation.getTarget();  
  3.      MetaObject metaStatementHandler = MetaObject.forObject(statementHandler,  
  4.      DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);  
  5.      // 分離代理對象鏈(由于目標類可能被多個攔截器攔截,從而構成屢次代理,通過下面的兩次循環  
  6.      // 可以分離出最原始的的目標類)  
  7.      while (metaStatementHandler.hasGetter("h")) {  
  8.          Object object = metaStatementHandler.getValue("h");  
  9.          metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY,   
  10.          DEFAULT_OBJECT_WRAPPER_FACTORY);  
  11.      }  
  12.      // 分離最后1個代理對象的目標類  
  13.      while (metaStatementHandler.hasGetter("target")) {  
  14.          Object object = metaStatementHandler.getValue("target");  
  15.          metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY,   
  16.          DEFAULT_OBJECT_WRAPPER_FACTORY);  
  17.      }  
  18.      Configuration configuration = (Configuration) metaStatementHandler.  
  19.      getValue("delegate.configuration");  
  20.      dialect = configuration.getVariables().getProperty("dialect");  
  21.      if (null == dialect || "".equals(dialect)) {  
  22.          logger.warn("Property dialect is not setted,use default 'mysql' ");  
  23.          dialect = defaultDialect;  
  24.      }  
  25.      pageSqlId = configuration.getVariables().getProperty("pageSqlId");  
  26.      if (null == pageSqlId || "".equals(pageSqlId)) {  
  27.          logger.warn("Property pageSqlId is not setted,use default '.*Page$' ");  
  28.          pageSqlId = defaultPageSqlId;  
  29.      }  
  30.      MappedStatement mappedStatement = (MappedStatement)   
  31.      metaStatementHandler.getValue("delegate.mappedStatement");  
  32.      // 只重寫需要分頁的sql語句。通過MappedStatement的ID匹配,默許重寫以Page結尾的  
  33.      //  MappedStatement的sql  
  34.      if (mappedStatement.getId().matches(pageSqlId)) {  
  35.          BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");  
  36.          Object parameterObject = boundSql.getParameterObject();  
  37.          if (parameterObject == null) {  
  38.              throw new NullPointerException("parameterObject is null!");  
  39.          } else {  
  40.              // 分頁參數作為參數對象parameterObject的1個屬性  
  41.              PageParameter page = (PageParameter) metaStatementHandler  
  42.                      .getValue("delegate.boundSql.parameterObject.page");  
  43.              String sql = boundSql.getSql();  
  44.              // 重寫sql  
  45.              String pageSql = buildPageSql(sql, page);  
  46.              metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);  
  47.              // 采取物理分頁后,就不需要mybatis的內存分頁了,所以重置下面的兩個參數  
  48.              metaStatementHandler.setValue("delegate.rowBounds.offset",   
  49.              RowBounds.NO_ROW_OFFSET);  
  50.              metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);  
  51.              Connection connection = (Connection) invocation.getArgs()[0];  
  52.              // 重
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 亚洲一区二区三区在线 | 91在线免费视频 | 亚洲国产电影 | 色呦呦视频在线观看 | 一区二区美女 | 亚洲精品乱码久久久久久蜜糖图片 | 黄且免费的视频 | 国产一区二区黄 | 久久国产三级 | 国产精品一二三四区 | 欧美日韩中文 | 久久国内视频 | 久久精品国产亚洲一区二区三区 | 国产成人在线看 | 成人av专区 | 亚洲精品18| 国产伦精品一区二区三区视频孕妇 | 亚洲精品一区二区三区99 | 日本99精品 | av电影在线观看网站 | 日韩一区二区三区在线观看 | 国产伦精品一区二区三区在线 | 久久大 | 麻豆成人在线观看 | a视频在线观看免费 | 国产精品毛片va一区二区三区 | 久久亚洲国产精品 | 国产精品三级视频 | 成人国产综合 | 日产精品久久久久久久 | 国产精品国产三级国产aⅴ中文 | 99国产精品久久久久久久 | 亚洲精品乱码久久久久膏 | 色在线播放 | 亚洲国产一区二区三区, | 久久久久网站 | 久久久久久久国产精品 | 国产欧美一区二区三区国产幕精品 | 日韩不卡在线 | 日本在线观看一区 | 亚洲一区二区三区中文字幕 |