Oracle、Mysql 分頁查詢


1.情景展示

在實際開發過程中,分頁查詢是最常使用的,只要存在表格查詢,就會存在分頁查詢;

分頁的好處在於:減少查詢的數據量,不會給前端、后台服務器、數據庫造成壓力,減少用戶等待時間。

2.Oracle分頁

如果僅僅是SQL,不涉及前后端交互的話,最簡單的分頁查詢就是:

顯然,這種查詢,對於我們來說,基本上沒有意義,它往往蘊含着前后端交互:

由前端來決定要分頁大小PageSize,分頁的當前頁PageIndex;

后台根據PageIndex和PageSize計算出開始頁Start和結束頁End。

前端:傳當前頁數和每頁的大小

java:計算起始數和結束數

其核心點在於:

int start = (pageIndex - 1) * pageSize + 1;
int end = pageIndex * pageSize;

ibatis:

<select id="getACCESS_GRANT" parameterClass="map" resultClass="java.util.HashMap" >
    <isNotNull  property="END">
        SELECT F.* FROM (
    </isNotNull>
            SELECT E.*,ROWNUM ROWNO FROM (
                SELECT T.GRANTJK,T.SECRETKEY,T.ACCESSID,T.ID
                 FROM ACCESS_GRANT T
                <include refid="ACCESS_GRANT_WHERE"/>
            )E ORDER BY T.ID
    <isNotNull  property="END">
        <![CDATA[ WHERE ROWNUM <= #END# ) F WHERE F.ROWNO >= #START#]]>
    </isNotNull>
</select>

其核心點在於:

動態分頁,即:當參數start和end有值時,才進行分頁,沒值時,查詢的是所有數據。

3.Mysql分頁

最簡單查詢:

前端同上;

java:只需計算起始數;

其核心點在於:

計算起始數時,pageIndex需要-1,因為limit是從0開始的,不是1!

使用mysql我們只需要知道start(起始數)和pageSize(分頁大小)。

ibatis:

<select id="getMETA_THEME" parameterClass="map" resultClass="java.util.HashMap" cacheModel="cacheMETA_THEME">
    <isNotNull property="START">
        SELECT F.* FROM (
    </isNotNull>
                SELECT T.THEMEID,T.THEMENAME,T.THEMECODE,T.THEMELEVEL,T.PARENTTHEMEID,T.STATUS,T.ZJM,DATE_FORMAT(T.CREATETIME,'%Y-%m-%d') CREATETIME,T.REMARK1,T.REMARK2,T.REMARK3
                 FROM META_THEME T
                <include refid="META_THEME_WHERE"/>
                ORDER BY T.THEMEID
    <isNotNull property="START">
        ) F
        <![CDATA[ limit #START#,#PAGESIZE#]]>
    </isNotNull>
</select>

其核心點在於:

動態分頁,即:當參數start有值時,才進行分頁,沒值時,查詢的是所有數據。

4.小結

Mysql和Oracle分頁的區別在於:

Mysql使用limit分頁,Oracle使用rownum分頁;

Mysql的limit 1,2 相當於:1<rownum≤3,得到的是第二行和第三行記錄;要想獲得前兩行的記錄,需要:

limit 0,2 相當於:0<rownum≤2

Oracle分頁是:1≤rownum≤2,得到的是第一行和第二行的記錄,也就是前兩行數據。

所以,這才是造成Mysql起始數從0開始,Oracle從1開始的真正原因。

其實Oracle也可以用int start = (pageIndex - 1) * pageSize;

不過,ibatis里面不能再用≥start,而是使用>start即可。

5.分頁+計數

我們知道,查詢數據往往涉及分頁,而分頁又要牽扯到總數;

所以,這里增加oracle和mysql的示例。

2022年2月13日12:02:22

oracle分頁+計數(ibatis)

分頁

<select id="getBASE_DICTIONARY_INFO" parameterClass="map"
    resultClass="java.util.HashMap" cacheModel="cacheBASE_DICTIONARY_INFO">
    <isNotNull prepend="" property="end">
        SELECT F.* FROM (
    </isNotNull>
            SELECT E.*,ROWNUM ROWNO FROM (
                SELECT A.DICTID,A.CLASSID,A.CODE,A.NAME,A.ZJM,
                A.MEMO,A.OID,A.STATUS,
                (SELECT CODE FROM BASE_DICTIONARY_KIND T WHERE A.CLASSID = T.CLASSID) CLASSCODE
                FROM BASE_DICTIONARY_INFO A
                <include refid="BASE_DICTIONARY_INFO_WHERE" />
                ORDER BY A.OID
            ) E
    <isNotNull prepend="" property="end">
        <![CDATA[ WHERE rownum<=#end#) F where ROWNO>=#start# ]]>
    </isNotNull>
</select>

計數

<select id="getBASE_DICTIONARY_INFO_COUNT" parameterClass="map"
    resultClass="java.lang.Integer" cacheModel="cacheBASE_DICTIONARY_INFO">
    SELECT COUNT(1)
    FROM BASE_DICTIONARY_INFO A
    <include refid="BASE_DICTIONARY_INFO_WHERE" />
</select>

動態where條件

<!--表(BASE_DICTIONARY_INFO)通用查詢條件-->
<sql id="BASE_DICTIONARY_INFO_WHERE">
    <dynamic prepend="WHERE">
        <isNotEmpty prepend="and" property="DICTID">
            A.DICTID=#DICTID#
        </isNotEmpty>
        <isNotEmpty prepend="and" property="CLASSID">
            A.CLASSID=#CLASSID#
        </isNotEmpty>
    </dynamic>
</sql>

mysql分頁+計數(mybatis)

分頁

<select id="getPersonInfoByIntoAddressList" resultType="map">
     <![CDATA[
        SELECT
            ( SELECT T2.PASS FROM SC_PASS_INFO T2 WHERE T2.ID = T.INTO_ADDRESS ) kaKou,
            COUNT( 1 ) jiShu
        FROM
            SC_PERSON_INFO T
        WHERE
            T.CREATETIME >= STR_TO_DATE( #{startDate}, '%Y-%m-%d' )
            AND T.CREATETIME < STR_TO_DATE( #{endDate}, '%Y-%m-%d' ) + 1
            AND T.INTO_ADDRESS IS NOT NULL
            AND T.INTO_ADDRESS != ''
        GROUP BY
            T.INTO_ADDRESS
        ORDER BY
            T.INTO_ADDRESS
        LIMIT #{start},#{pageSize}
    ]]>
</select>

計數

<select id="getPersonInfoByIntoAddressTotal" resultType="long">
    <![CDATA[
        SELECT
            COUNT( 1 ) totalCount
        FROM
            (
            SELECT
                1
            FROM
                SC_PERSON_INFO T
            WHERE
                T.CREATETIME >= STR_TO_DATE( #{startDate}, '%Y-%m-%d' )
                AND T.CREATETIME < STR_TO_DATE( #{endDate}, '%Y-%m-%d' ) + 1
                AND T.INTO_ADDRESS IS NOT NULL
                AND T.INTO_ADDRESS != ''
            GROUP BY
                T.INTO_ADDRESS) b
    ]]>
</select>

6.list分頁

使用list進行手動分頁,見文末《mysql 存儲過程 示例》。

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM