MyBatis 最佳實(shí)踐篇 1:分頁

1 默認(rèn)分頁(邏輯分頁)

MyBatis 默認(rèn)提供了分頁功能宋距,即 RowBounds 類轴踱,該類提供兩個(gè)參數(shù):offset 和 limit。offset 為起始行數(shù)谚赎,limit 為要查詢的行數(shù)淫僻。

public class RowBounds {
  //other...
  public static final int NO_ROW_OFFSET = 0;
  public static final int NO_ROW_LIMIT = Integer.MAX_VALUE;

  private final int offset;
  private final int limit;

  public RowBounds() {
    this.offset = NO_ROW_OFFSET;
    this.limit = NO_ROW_LIMIT;
  }

  public RowBounds(int offset, int limit) {
    this.offset = offset;
    this.limit = limit;
  }
  //other...
}

但使用 RowBounds 的默認(rèn)分頁是邏輯分頁:從數(shù)據(jù)庫一次性查詢出所有的記錄,再通過傳入的 RowBounds 的 offset 和 limit 的值壶唤,使用 for 循環(huán)進(jìn)行過濾雳灵。源碼如下:
org.apache.ibatis.executor.resultset.DefaultResultSetHandler 類:

 private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
      throws SQLException {
    DefaultResultContext<Object> resultContext = new DefaultResultContext<Object>();
    skipRows(rsw.getResultSet(), rowBounds);
    while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
      ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
      Object rowValue = getRowValue(rsw, discriminatedResultMap);
      storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
    }
  }
private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {
    if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
      if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {
        rs.absolute(rowBounds.getOffset());
      }
    } else {
      for (int i = 0; i < rowBounds.getOffset(); i++) {
        rs.next();
      }
    }
  }

為了驗(yàn)證上面的邏輯,我們執(zhí)行下面的測試方法:

public void testDefaultPaging() {
        SqlSession session = FactoryBuildByXML.getFactory().openSession(true);
        try {
            RowBounds rowBounds = new RowBounds(2, 11);
            List<Object> list = session.selectList("com.zhaoxueer.learn.dao.AuthorMapper.selectAllTest", null, rowBounds);
            System.out.println("查詢的結(jié)果數(shù):" + list.size());
        } finally {
            session.close();
        }
}

AuthorMapper 中 selectAllTest 方法為:

@Select("select id, name, sex, phone from author")
List<Author> selectAllTest();

執(zhí)行結(jié)果為:

DEBUG [main] - ==>  Preparing: select id, name, sex, phone from author 
DEBUG [main] - ==> Parameters: 
查詢的結(jié)果數(shù):11

這種分頁方式不能滿足我們對(duì)于減輕數(shù)據(jù)庫壓力的要求闸盔,因此不建議使用悯辙。

2 使用 pagehelper 插件(物理分頁)

為了簡單地實(shí)現(xiàn)真正的物理分頁,我們可以使用插件去實(shí)現(xiàn)迎吵,網(wǎng)上有很多這樣的插件躲撰,例如比較常用的 pagehelper 插件
只需要簡單的三步:

  • 第一步:maven 引入依賴:
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>latest version</version>
</dependency>

注:修改 version 為最新的版本號(hào)(如 5.1.7)击费,可點(diǎn)擊上面鏈接查看最新版本拢蛋。

  • 第二步:mybatis-config.xml 注冊(cè)該 plugin:
<plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- config params as the following -->
            <!--<property name="param1" value="value1"/>-->
        </plugin>
</plugins>
  • 第三步:代碼中使用:
public void testPageHelper() {
        SqlSession session = FactoryBuildByXML.getFactory().openSession(true);
        try {
            AuthorMapper authorMapper = session.getMapper(AuthorMapper.class);

            // 只需要在查詢語句前插入該語句即可實(shí)現(xiàn)分頁
            PageHelper.startPage(1, 10);
            List<Author> authorList = authorMapper.selectAllTest();
            System.out.println("查詢的結(jié)果數(shù):" + authorList.size());
        } finally {
            session.close();
        }
    }

執(zhí)行結(jié)果為:

DEBUG [main] - ==>  Preparing: SELECT count(0) FROM author 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 1
DEBUG [main] - ==>  Preparing: select id, name, sex, phone from author LIMIT ? 
DEBUG [main] - ==> Parameters: 10(Integer)
DEBUG [main] - <==      Total: 10
查詢的結(jié)果數(shù):10

注意:注入分頁插件 plugin 元素后,執(zhí)行前面默認(rèn)分頁舉例中的方法蔫巩,也會(huì)實(shí)現(xiàn)物理分頁谆棱,因?yàn)樵摬寮?duì)該方法也進(jìn)行了攔截處理。

pagehelper 插件的 PageInterceptor 類對(duì)以下方法進(jìn)行攔截:

@Intercepts(
        {
                @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
                @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
        }
)

默認(rèn)分頁舉例中的語句:

RowBounds rowBounds = new RowBounds(2, 11);
List<Object> list = session.selectList("com.zhaoxueer.learn.dao.AuthorMapper.selectAllTest", null, rowBounds);

對(duì)上面兩行代碼的執(zhí)行結(jié)果為:

DEBUG [main] - ==>  Preparing: select id, name, sex, phone from author LIMIT ?, ? 
DEBUG [main] - ==> Parameters: 2(Integer), 11(Integer)
DEBUG [main] - <==      Total: 11
查詢的結(jié)果數(shù):11

因此圆仔,若要測試默認(rèn)分頁的邏輯分頁方式垃瞧,請(qǐng)注釋掉 plugin 代碼塊。

更多使用方法查看:MyBatis PageHelper 文檔

附:

當(dāng)前版本:mybatis-3.5.0
官網(wǎng)文檔:MyBatis
項(xiàng)目實(shí)踐:MyBatis Learn
手寫源碼:MyBatis 簡易實(shí)現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末坪郭,一起剝皮案震驚了整個(gè)濱河市个从,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌歪沃,老刑警劉巖信姓,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绸罗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)豆瘫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門珊蟀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事育灸∧逯希” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵磅崭,是天一觀的道長儿子。 經(jīng)常有香客問我,道長砸喻,這世上最難降的妖魔是什么柔逼? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮割岛,結(jié)果婚禮上愉适,老公的妹妹穿的比我還像新娘。我一直安慰自己癣漆,他們只是感情好维咸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惠爽,像睡著了一般癌蓖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上婚肆,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天租副,我揣著相機(jī)與錄音,去河邊找鬼旬痹。 笑死附井,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的两残。 我是一名探鬼主播永毅,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼人弓!你這毒婦竟也來了沼死?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤崔赌,失蹤者是張志新(化名)和其女友劉穎意蛀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體健芭,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡县钥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了慈迈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片若贮。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谴麦,到底是詐尸還是另有隱情蠢沿,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布匾效,位于F島的核電站舷蟀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏面哼。R本人自食惡果不足惜野宜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望精绎。 院中可真熱鬧速缨,春花似錦、人聲如沸代乃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搁吓。三九已至原茅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間堕仔,已是汗流浹背擂橘。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摩骨,地道東北人通贞。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像恼五,于是被迫代替她去往敵國和親昌罩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Mybatis分頁插件-PageHepler的使用 使用方法 1. 引入分頁插件 引入分頁插件一共有下面2種方式灾馒,...
    匆匆歲月閱讀 1,414評(píng)論 0 7
  • MyBatis框架提供的PageHelper分頁插件的使用 PageHelper是國內(nèi)非常優(yōu)秀的一款開源的myba...
    哈哈大圣閱讀 1,441評(píng)論 0 6
  • 在Mybatis配置xml中配置攔截器插件: 這里的com.github.pagehelper.PageHelpe...
    bboymonk閱讀 3,461評(píng)論 6 2
  • 前言 在學(xué)習(xí)mybatis等持久層框架的時(shí)候茎用,會(huì)經(jīng)常對(duì)數(shù)據(jù)進(jìn)行增刪改查操作,使用最多的是對(duì)數(shù)據(jù)庫進(jìn)行查詢操作睬罗,如果...
    高級(jí)java架構(gòu)師閱讀 14,187評(píng)論 1 3
  • 平常工作中的有道云筆記分享一下轨功,暫時(shí)也沒時(shí)間寫成文章,所以就先分享給大家容达,也許會(huì)有人需要古涧。 如果有大佬愿意一起分享...
    明明很安靜閱讀 207評(píng)論 0 0