在前四章中我們已經(jīng)基本完成了對單表的CRUD與多表聯(lián)合查詢方式的Mybatis操作與配置方式,今天這里要講的是關于一個業(yè)務問題中我們常 碰到的分頁問題。在開發(fā)web項目的時候我們經(jīng)常會使用到列表顯示,一般我們都會用一些常用的列表控件例如,datatables(個人感覺十分不 錯),easy ui下面的那些封裝好的表格控件。 思路:在這些控件里要達到分頁的效果,一般都會傳2個參數(shù),第一個是表示當前頁的索 引(一般從0開始),第二個表示當前頁展示多少條業(yè)務記錄,然后將相應的參數(shù)傳遞給List<T> getList(PagenateArgs args)方法,最終實現(xiàn)數(shù)據(jù)庫中的分頁時候我們可以使用limit關鍵詞(針對mysql)進行分頁,如果是oracle或者sql server他們都有自帶的rownum函數(shù)可以使用。 針對上述思路,首先我們需要還是一如既往的在 demo.mybatis.model下面新建一個名為PagenateArgs的分頁參數(shù)實體類與一個名為SortDirectionEnum的枚舉 類,里面包含當前頁面索引pageIndex, 當前頁展示業(yè)務記錄數(shù)pageSize, pageStart屬性表示從第幾條開始,(pageStart=pageIndex*pageSize)因為limit關鍵詞用法是表示【limit 起始條數(shù)(不包含),取幾條】,orderFieldStr排序字段,orderDirectionStr 排序方向,所以具體創(chuàng)建如下:  PagenateArgs分頁參數(shù)類 package david.mybatis.model;
/* * 分頁參數(shù)實體類 */ public class PagenateArgs { private int pageIndex; private int pageSize; private int pageStart; private String orderFieldStr; private String orderDirectionStr;
public PagenateArgs() { // TODO Auto-generated constructor stub }
public PagenateArgs(int pageIndex, int pageSize, String orderFieldStr, String orderDirectionStr) { this.pageIndex = pageIndex; this.pageSize = pageSize; this.orderFieldStr = orderFieldStr; this.orderDirectionStr = orderDirectionStr; pageStart = pageIndex * pageSize; }
public int getPageIndex() { return pageIndex; }
public int getPageStart() { return pageStart; }
public int getPageSize() { return pageSize; }
public String orderFieldStr() { return orderFieldStr; }
public String getOrderDirectionStr() { return orderDirectionStr; } }  SQL排序枚舉 package david.mybatis.model;
/* * 排序枚舉 */ public enum SortDirectionEnum { /* * 升序 */ ASC, /* * 降序 */ DESC } 完成上面的步驟以后我們在IVisitorOperation接口類中繼續(xù)添加一個方法public List<Visitor> getListByPagenate(PagenateArgs args),前幾章中我們其實已經(jīng)有getList方法了,這次的分頁其實也就是在這個的基礎上稍加改動即可,IVisitorOperation接口類 改動后如下所示:  修改后的IVisitorOperation package david.mybatis.demo;
import java.util.List; import david.mybatis.model.PagenateArgs; import david.mybatis.model.Visitor; import david.mybatis.model.VisitorWithRn;
public interface IVisitorOperation { /* * 基礎查詢 */ public Visitor basicQuery(int id);
/* * 添加訪問者 */ public int add(Visitor visitor); /* * 刪除訪問者 */ public int delete(int id); /* * 更新訪問者 */ public int update(Visitor visitor); /* * 查詢訪問者 */ public Visitor query(int id); /* * 查詢List */ public List<Visitor> getList(); /* * 分頁查詢List */ public List<Visitor> getListByPagenate(PagenateArgs args); } 接下來我們就要開始動手改動我們的VisitorMapper.xml配置文件了,新增一個<select>節(jié)點id與參數(shù)類型參照前幾章的方式配置好,如下此處新增的id就為getListByPagenate,配置好以后如下  修改后的VisitorMapper配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="david.mybatis.demo.IVisitorOperation"> <!-- useGeneratedKeys="true"代表是否使用自增長序列, keyProperty="Id"指定自增長列是哪一列, parameterType="Visitor"指定IVisitorOperation接口類中定義中所傳的相應類型 --> <insert id="add" parameterType="Visitor" useGeneratedKeys="true" keyProperty="Id"> insert into Visitor (Name, Email, Status, CreateTime) values (#{name}, #{email}, #{status}, #{createTime}) </insert> <delete id="delete" parameterType="int"> delete from Visitor where status>0 and id = #{id} </delete> <update id="update" parameterType="Visitor"> update Visitor set Name = #{name}, Email=#{email}, Status=#{status} where id=#{id} and Status>0; </update> <select id="query" parameterType="int" resultType="Visitor"> select Id, Name, Email, Status, CreateTime from visitor where id=#{id} and Status>0 order by Id </select> <select id="basicQuery" parameterType="int" resultType="Visitor"> select * from visitor where id=#{id} and Status>0 order by Id </select> <select id="getList" resultMap="visitorRs"> <include refid="getListSql" /> </select> <sql id="getListSql"> select * from Visitor where status>0 </sql> <!-- 以下為新增部分用來分頁,orderBySql這個提取出來是為了后面有示例復用 --> <resultMap type="Visitor" id="visitorRs"> <id column="Id" property="id" /> <result column="Name" property="name" /> <result column="Email" property="email" /> <result column="Status" property="status" /> <result column="CreateTime" property="createTime" /> </resultMap> <select id="getListByPagenate" parameterType="PagenateArgs" resultType="Visitor"> select * from ( <include refid="getListSql" /> <include refid="orderBySql"/> ) t <!-- #{}表示參數(shù)化輸出,${}表示直接輸出不進行任何轉(zhuǎn)義操作,自己進行轉(zhuǎn)移 --> <if test="pageStart>-1 and pageSize>-1"> limit #{pageStart}, #{pageSize} </if> </select> <sql id="orderBySql"> order by ${orderFieldStr} ${orderDirectionStr} </sql> </mapper> 在上面你會發(fā)現(xiàn)有類似,下圖中的配置,這些是屬于后面一章會講述的動態(tài)SQL問題,現(xiàn)在可以暫時不管,這里面的字段屬性都是針對PagenateArgs參數(shù)類中的屬性名,保持一致。 <if test="pageStart>-1 and pageSize>-1"> limit #{pageStart}, #{pageSize} </if>
在DemoRun類中創(chuàng)建測試方法:  DemoRun分頁 /* * 分頁參數(shù) */ public static void queryVisitorListWithPagenate(int pageIndex, int pageSize, String orderField, String orderDire) { PagenateArgs args = new PagenateArgs(pageIndex, pageSize, orderField, orderDire); SqlSession session = MybatisUtils.getSqlSession(); IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class); List<Visitor> visitors = vOperation.getListByPagenate(args); for (Visitor visitor : visitors) { System.out.println(visitor); } MybatisUtils.closeSession(session); MybatisUtils.showMessages(CRUD_Enum.List, visitors.size()); }DemoRun.queryVisitorListWithPagenate(0, 100, "id", SortDirectionEnum.DESC.toString()); 運行后下測試結(jié)果,先按Id倒序排列,查的Visitor表一共有14條記錄, 
假設我們?nèi)≡诘?頁取5條,執(zhí)行下面也就是6-10條數(shù)據(jù),這樣傳參數(shù)就行了 DemoRun.queryVisitorListWithPagenate(1, 5, "id", SortDirectionEnum.DESC.toString()); 結(jié)果如下: 
這樣就自己實現(xiàn)了的一個分頁邏輯啦~^0^,這里需要注意的就是我這邊orderFieldStr字段是沒有做過任何判斷的,理論上要處理下防止錯誤了列名傳進去,不過現(xiàn)在網(wǎng)上應該有現(xiàn)成封裝好的東西,大家也可以去google下,這里只是給個思路演示下怎么用mybatis分頁。 完成這個后,因為是Mysql的關系所以在查詢結(jié)果里他沒有自帶rownum序列ID,所以查看測試數(shù)據(jù)是第幾條的時候可能不明顯,不zao急,我們可 以自己動手豐衣足食改造下上面的方法,這里我重新在model包里新建一個一模一樣的VisitorWithRn實體里面多帶一個rownum參數(shù)持久化 返回的RownumID,如下:  VisitWithRn package david.mybatis.model;
import java.text.SimpleDateFormat; import java.util.Date;
public class VisitorWithRn { private int id; private String name; private String email; private int status; private Date createTime; private int rownum;
public VisitorWithRn() { // TODO Auto-generated constructor stub createTime = new Date(); }
public VisitorWithRn(String name, String email) { this.name = name; this.email = email; this.setStatus(1); this.createTime = new Date(); }
public int getId() { return id; }
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public void setEmail(String email) { this.email = email; }
public String getEmail() { return email; }
public Date getCreateTime() { return createTime; }
public int getStatus() { return status; }
public void setStatus(int status) { this.status = status; }
public int getRownum() { return rownum; }
public void setRownum(int rownum) { this.rownum = rownum; }
@Override public String toString() { // TODO Auto-generated method stub return String.format("{Rownum:%d, Id: %d, Name: %s, CreateTime: %s}", rownum, id, name, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createTime)); } }在 IVisitorOperation里面在新建一個名為 public List<VisitorWithRn> getListByPagenateWithRn(PagenateArgs args)的方法,同樣我們需要在VisitorMapper中配置下相應<select>節(jié)點與腳本,此處唯一的不同就是需要改下sql腳 本,如下:  添加具有Rn效果的配置文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="david.mybatis.demo.IVisitorOperation"> <!-- useGeneratedKeys="true"代表是否使用自增長序列, keyProperty="Id"指定自增長列是哪一列, parameterType="Visitor"指定IVisitorOperation接口類中定義中所傳的相應類型 --> <insert id="add" parameterType="Visitor" useGeneratedKeys="true" keyProperty="Id"> insert into Visitor (Name, Email, Status, CreateTime) values (#{name}, #{email}, #{status}, #{createTime}) </insert> <delete id="delete" parameterType="int"> delete from Visitor where status>0 and id = #{id} </delete> <update id="update" parameterType="Visitor"> update Visitor set Name = #{name}, Email=#{email}, Status=#{status} where id=#{id} and Status>0; </update> <select id="query" parameterType="int" resultType="Visitor"> select Id, Name, Email, Status, CreateTime from visitor where id=#{id} and Status>0 order by Id </select> <select id="basicQuery" parameterType="int" resultType="Visitor"> select * from visitor where id=#{id} and Status>0 order by Id </select> <select id="getList" resultMap="visitorRs"> <include refid="getListSql" /> </select> <sql id="getListSql"> select * from Visitor where status>0 </sql> <resultMap type="Visitor" id="visitorRs"> <id column="Id" property="id" /> <result column="Name" property="name" /> <result column="Email" property="email" /> <result column="Status" property="status" /> <result column="CreateTime" property="createTime" /> </resultMap> <select id="getListByPagenate" parameterType="PagenateArgs" resultType="Visitor"> select * from ( <include refid="getListSql" /> <include refid="orderBySql"/> ) t <!-- #{}表示參數(shù)化輸出,${}表示直接輸出不進行任何轉(zhuǎn)義操作,自己進行轉(zhuǎn)移 --> <if test="pageStart>-1 and pageSize>-1"> limit #{pageStart}, #{pageSize} </if> </select> <!--提煉出來為了2個示例共用下 --> <sql id="orderBySql"> order by ${orderFieldStr} ${orderDirectionStr} </sql> <!-- 帶rownum的SQL腳本書寫方式 --> <resultMap type="VisitorWithRn" id="visitorWithRnRs"> <id column="Id" property="id" /> <result column="Name" property="name" /> <result column="Email" property="email" /> <result column="Status" property="status" /> <result column="CreateTime" property="createTime" /> <result column="Rownum" property="rownum" /> </resultMap> <select id="getListByPagenateWithRn" resultMap="visitorWithRnRs"> <!-- #{}表示參數(shù)化輸出,${}表示直接輸出不進行任何轉(zhuǎn)義操作,自己進行轉(zhuǎn)移 --> select t.Rownum, t.Id, t.Name, t.Email, t.Status, t.CreateTime from (<include refid="getListSqlContainsRn" /> <include refid="orderBySql"/>) t <if test="pageStart>-1 and pageSize>-1"> limit #{pageStart}, #{pageSize} </if> </select> <sql id="getListSqlContainsRn"> select @rownum:=@rownum+1 Rownum, result.id, result.name, result.email, result.status, result.createTime FROM ( select @rownum:=0, Visitor.* from Visitor where status>0) result </sql> </mapper>接下來剩下的就是如剛才在DemoRun下面添加測試方法,這里就不貼圖了,完成后你可以看到剛剛的6-10條數(shù)據(jù)會變成如下 
今天的東西就講到這里啦,下一章繼續(xù)講述Mybatis里面常用的動態(tài)SQL使用方法,希望對園子上的朋友們有幫助~^0^~ 如果你覺得這篇文章對你有用,歡迎推薦[推薦]
如果你覺得文章內(nèi)有錯誤歡迎指出^0^~
如果您想轉(zhuǎn)載本博客,請注明出處
如果您對本文有意見或者建議,歡迎留言 本文版權歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則作者保留追究法律責任的權利。
|
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 |
|
導航
統(tǒng)計
常用鏈接
留言簿
隨筆分類
隨筆檔案
搜索
最新評論

閱讀排行榜
評論排行榜
|
|