分頁設計

1 實現控制檯版本分頁

一:通過發生兩條SQL:

    1):查詢符合條件的當前頁面的結果集

        SELECT * FROM table_name WHERE 條件 ... limit ?,?

        第一個?:beginIndex:當前頁開始索引數:(currentPage - 1)*pageSize.

        第二個?:pageSize:每頁顯示條數

    2):查詢符合條件的結果總數:

        SELECT COUNT(*) FROM table_name WHERE 條件 ...

二:計算三個分頁值:

    總頁數:Integer totalPage = totalCount % pageSize == 0 ? totalCount / pageSize 
                : totalCount/pageSize + 1;

    上一頁:Integer prePage = currentPage - 1 >= 1? currentPage - 1 : 1;

    下一頁:Integer nextPage = currentPage + 1 <= totalCount? currentPage + 1 : totalPage ;

測試實現類:

@Test
    public void testPage() throws Exception {
        SqlSession session = MyBatisUtil.INSTANCE.openSession();
        //前兩個是用戶自己傳入的數據!
        Integer currentPage = 1;//當前頁
        Integer pageSize = 5;//每頁條數

        //查詢結果總數
        Integer totalCount = session.selectOne("cn.itsource.shopping.mapper.ProductMapper.getTotalCount");
        Integer beginPage = 1;//首頁
        //總頁數/末頁
        Integer totalPage = totalCount % pageSize == 0 ? totalCount / pageSize 
                : totalCount/pageSize + 1;
        //上頁
        Integer prePage = currentPage - 1 >= 1? currentPage - 1 : 1;
        //下頁
        Integer nextPage = currentPage + 1 <= totalCount? currentPage + 1 : totalPage ;
        //===========================
        //查詢結果集
        //===========================
        Map<String,Object> limitMap = new HashMap<>();//封裝limit?,?:的信息
        limitMap.put("beginIndex",(currentPage-1)*pageSize);
        limitMap.put("pageSize", pageSize);
        List<Object> selectList = session.selectList("cn.itsource.shopping.mapper.ProductMapper.getPageResult", limitMap);
        for (Object p : selectList) {
            System.out.println(p);
        }
        //===========================
        //打印分頁條信息
        System.out.print("首頁"+beginPage);
        System.out.print("上頁"+prePage);
        System.out.print("下頁"+nextPage);
        System.out.print("末頁"+totalPage);
        System.out.println("當前頁"+currentPage+"/"+totalPage+"頁");
        System.out.println("一共"+totalCount+"條記錄");

        session.close();
    }

ProductMapper.xml映射文件

兩個查詢的SQL

<?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">
 <!-- 映射Product對象和對應表關係的,操作該表/對象的SQL全部都寫在這裏 -->
<mapper namespace="cn.itsource.shopping.mapper.ProductMapper">

    <!-- 查詢結果總數 -->
    <select id="getTotalCount" resultType="int">
        SELECT COUNT(*) FROM product
    </select>

    <!-- 查詢當前頁 的結果集 -->
    <select id="getPageResult"  parameterType="map" resultType="Product">
        SELECT * FROM product limit #{beginIndex},#{pageSize}
    </select>
</mapper>

2 使用Map實現後臺分頁設計

操作步驟:

①:封裝分頁結果對象PageList

②:在IProductDAO中定義,分頁查詢的方法;

   PageList query (Integer currentPage, Integer pageSize);

③:實現ProductDAOImpl中的query方法,並測試。
public class PageList {
    private List ListData;//結果集數據:SQL查詢出來
    private Integer totalCount;//結果總數:SQL查詢出來

    private Integer currentPage = 1;//當前頁:前臺用戶傳入的
    private Integer pageSize = 5;//每頁多少條:前臺用戶傳入的

    private Integer beginPage = 1;//首頁
    //private Integer prePage;  //上一頁 計算出來的
    //private Integer nextPage; //下一頁 計算出來的
    //private Integer totalPage;//總頁數/末頁:計算出來的

    //計算上一頁
    public Integer getPrePage() {
        return currentPage - 1 >= 1? currentPage -1 : 1;
    }
    //計算下一頁
    public Integer getNextPage() {
        return currentPage + 1 <= getTotalPage()? currentPage+1:getTotalPage();
    }
    //計算總頁數
    public Integer getTotalPage() {
        return totalCount % pageSize == 0? totalCount / pageSize : totalCount/ pageSize +1;
    }

    public PageList(Integer currentPage,Integer pageSize,List ListData,Integer totalCount){
        this.currentPage=currentPage;
        this.pageSize=pageSize;
        this.ListData=ListData;
        this.totalCount=totalCount;
    }

    public List getListData() {
        return ListData;
    }
    public void setListData(List listData) {
        ListData = listData;
    }
    public Integer getTotalCount() {
        return totalCount;
    }
    public void setTotalCount(Integer totalCount) {
        this.totalCount = totalCount;
    }
    public Integer getCurrentPage() {
        return currentPage;
    }
    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }
    public Integer getPageSize() {
        return pageSize;
    }
    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
    public Integer getBeginPage() {
        return beginPage;
    }
}

Dao實現接口

public interface IProductDAO {

    /**
     * 分頁查詢
     * @param currentPage  當前頁
     * @param pageSize  每頁顯示條數
     */
    PageList query (Integer currentPage,Integer pageSize);

}

Dao實現類

public class ProductDAOImpl implements IProductDAO {

    public PageList query(Integer currentPage, Integer pageSize) {
        SqlSession session = MyBatisUtil.INSTANCE.openSession();
        try {
            //查詢結果總數
            Integer totalCount = session.selectOne("cn.itsource.shopping.mapper.ProductMapper.getTotalCount");
            //查詢結果集
            Map<String,Object> limitMap = new HashMap<>();
            limitMap.put("beginIndex", (currentPage-1)*pageSize);
            limitMap.put("pageSize", pageSize);
            List<Object> listData = session.selectList("cn.itsource.shopping.mapper.ProductMapper.getPageResult", limitMap);
            return new PageList(currentPage,pageSize,listData,totalCount);
        } finally {
            session.close();
        }
    }
}

測試類

    @Test
    public void testPageQuery(){
        Integer currentPage = 1;
        Integer pageSize = 5;
        PageList pList = dao.query(currentPage, pageSize);
        for (Object p : pList.getListData()) {
            System.out.println(p);
        }
    }

XML映射文件

跟上面的一樣沒有變。
<?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">
 <!-- 映射Product對象和對應表關係的,操作該表/對象的SQL全部都寫在這裏 -->
<mapper namespace="cn.itsource.shopping.mapper.ProductMapper">
    <!-- 查詢結果總數 -->
    <select id="getTotalCount" resultType="int">
        SELECT COUNT(*) FROM product
    </select>
    <!-- 查詢當前頁 的結果集 -->
    <select id="getPageResult"  parameterType="map" resultType="Product">
        SELECT * FROM product limit #{beginIndex},#{pageSize}
    </select>
</mapper>

3 封裝分頁信息到Query對象並與高級查詢整合

封裝分頁信息到Query對象操作步驟:

    1.讓查詢對象封裝分頁信息

      把currentPage和pageSize作爲ProductQueryObject的字段並提供getter/setter.但是分頁是所有查詢對象共用的行爲。應給把currentPage和pageSize抽離到BaseQueryObject中。並暴露一個用於MySQL分頁的開始索引:beginIndex屬性。

    2.在IproductDAO接口中,定義高級查詢+分頁的操作方法:

      PageList query (ProductQueryObject qo)

    3.在ProductDAOImpl中實現該方法。

高級查詢+分頁的操作步驟:

public PageList query(ProductQueryObject qo)方法,可以同時完成高級查詢和分頁操作。

參數:qo,qo對象封裝了所有的高級查詢參數和分頁信息。

操作步驟:

1.修改映射文件,實質支持帶條件的查詢(高級查詢)添加了$(querySql) 跟 prameterType

2.再修改ProductDAOImpl的query方法,使之支持查詢查詢符合條件的結果總數:查詢結果總數的totalCount的方法裏面添加了參數qo對象。

排序的時候用$以後一般都用#,$沒有防止SQL注入功能,不安全!

DAO實現接口

public interface IProductDAO {
    /**
     * 高級查詢+分頁的合體
     * @param qo    包括了高級查詢信息和分頁信息
     * @return
     */
    PageList query(ProductQueryObject qo);
}

DAO的實現類

public class ProductDAOImpl implements IProductDAO {
    public PageList query(ProductQueryObject qo) {
        SqlSession session = MyBatisUtil.INSTANCE.openSession();
        try {
            //查詢結果總數
            Integer totalCount = session.selectOne("cn.itsource.shopping.mapper.ProductMapper.getTotalCount",qo);
            //查詢結果集
            List listData = session.selectList("cn.itsource.shopping.mapper.ProductMapper.getResultList", qo);
            return new PageList(qo.getCurrentPage(),qo.getPageSize(),listData,totalCount);
        } finally {
            session.close();
        }
    }
}

XML映射文件

<?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">
 <!-- 映射Product對象和對應表關係的,操作該表/對象的SQL全部都寫在這裏 -->
<mapper namespace="cn.itsource.shopping.mapper.ProductMapper">
    <!-- 查詢結果總數 -->
    <select id="getTotalCount" resultType="int"
    parameterType="cn.itsource.shopping.query.ProductQueryObject">
        SELECT COUNT(*) FROM product ${querySql}
    </select>
    <!-- 查詢當前頁 的結果集 -->
    <select id="getResultList" resultType="Product"
    parameterType="cn.itsource.shopping.query.ProductQueryObject" >
        SELECT * FROM product ${querySql} limit #{beginIndex},#{pageSize}
    </select>
</mapper>

測試類

//分頁+高級查詢的方法測試
    @Test
    public void testPageList() throws Exception {
        ProductQueryObject qo = new ProductQueryObject();
        //封裝查詢和分頁信息
        qo.setCurrentPage(1);//設置當前頁面
        qo.setPageSize(5);//設置每頁顯示條數
        qo.setProductName("iphone8s");//用於設置查詢條件where name like 'iphone8s'
        PageList pList = dao.query(qo);
        for (Object p : pList.getListData()) {
            System.out.println(p);
        }
    }

ProductQueryObject的父類

public class BaseQueryObject {
    private List<String> conditions = new ArrayList<>();

    private Integer currentPage = 1;//當前頁:前臺用戶傳入的
    private Integer pageSize = 5;//每頁多少條:前臺用戶傳入的

    //提供一個屬性:beginIndex:返回當前頁的開始索引
    public Integer getBeginIndex(){
        return (currentPage-1)*pageSize;
    }

    //拼接查詢條件的SQL
    public String getQuerySql() {
        //拼接SQL
        StringBuilder sql = new StringBuilder();
        this.customizedQuery();
        for (int i = 0; i < conditions.size(); i++) {
            if (i == 0) {
                sql.append(" WHERE ");
            } else {
                sql.append(" AND ");
            }
            sql.append(conditions.get(i));
        }
        return sql.toString();
    }

    /**
     * 專門暴漏給子類,用於編寫自身的查詢條件
     */
    protected void customizedQuery(){

    }

    /**
     * 專門暴漏給子類一個方法,用於添加查詢條件
     */
    protected void addQuery(String condition){
        conditions.add(condition);
    }

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
}

下面的是沒有改動的代碼:

ProductQueryObject對象類

//商品的高級查詢對象,封裝了商品高級查詢表單的數據。
public class ProductQueryObject extends BaseQueryObject{

    //抽離出的自身的訂製查詢
    public void customizedQuery() {
        //若輸入了商品名稱
        if (StringUtil.hasLength(productName)) {//名字佔位符
            super.addQuery(" productName LIKE CONCAT('%',#{productName},'%')");
        }
        //最低零售價
        if (minSalePrice != null) {
            super.addQuery(" salePrice >= #{minSalePrice}");
        }
        //最高零售價
        if (maxSalePrice != null) {
            super.addQuery(" salePrice <= #{maxSalePrice}");
        }
    }

    private String productName;//商品名稱
    private BigDecimal minSalePrice;//最低商品零售價
    private BigDecimal maxSalePrice;//最高商品零售價

    public String getProductName() {
        return productName;
    }
    public BigDecimal getMinSalePrice() {
        return minSalePrice;
    }
    public BigDecimal getMaxSalePrice() {
        return maxSalePrice;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public void setMinSalePrice(BigDecimal minSalePrice) {
        this.minSalePrice = minSalePrice;
    }
    public void setMaxSalePrice(BigDecimal maxSalePrice) {
        this.maxSalePrice = maxSalePrice;
    }
}

PageList對象

public class PageList {
    private List ListData;//結果集數據:SQL查詢出來
    private Integer totalCount;//結果總數:SQL查詢出來

    private Integer currentPage = 1;//當前頁:前臺用戶傳入的
    private Integer pageSize = 5;//每頁多少條:前臺用戶傳入的

    private Integer beginPage = 1;//首頁
    //private Integer prePage;  //上一頁 計算出來的
    //private Integer nextPage; //下一頁 計算出來的
    //private Integer totalPage;//總頁數/末頁:計算出來的

    //計算上一頁
    public Integer getPrePage() {
        return currentPage - 1 >= 1? currentPage -1 : 1;
    }
    //計算下一頁
    public Integer getNextPage() {
        return currentPage + 1 <= getTotalPage()? currentPage+1:getTotalPage();
    }
    //計算總頁數
    public Integer getTotalPage() {
        return totalCount % pageSize == 0? totalCount / pageSize : totalCount/ pageSize +1;
    }

    public PageList(Integer currentPage,Integer pageSize,List ListData,Integer totalCount){
        this.currentPage=currentPage;
        this.pageSize=pageSize;
        this.ListData=ListData;
        this.totalCount=totalCount;
    }

    public List getListData() {
        return ListData;
    }
    public void setListData(List listData) {
        ListData = listData;
    }
    public Integer getTotalCount() {
        return totalCount;
    }
    public void setTotalCount(Integer totalCount) {
        this.totalCount = totalCount;
    }
    public Integer getCurrentPage() {
        return currentPage;
    }
    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }
    public Integer getPageSize() {
        return pageSize;
    }
    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
    public Integer getBeginPage() {
        return beginPage;
    }
}

Product對象

public class Product {
    private Long id;
    private String productName;
    private String brand;
    private String supplier;
    private BigDecimal salePrice;
    private BigDecimal costPrice;
    private Double cutoff;
    private Long dir_id;//分類編號
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public String getSupplier() {
        return supplier;
    }
    public void setSupplier(String supplier) {
        this.supplier = supplier;
    }
    public BigDecimal getSalePrice() {
        return salePrice;
    }
    public void setSalePrice(BigDecimal salePrice) {
        this.salePrice = salePrice;
    }
    public BigDecimal getCostPrice() {
        return costPrice;
    }
    public void setCostPrice(BigDecimal costPrice) {
        this.costPrice = costPrice;
    }
    public Double getCutoff() {
        return cutoff;
    }
    public void setCutoff(Double cutoff) {
        this.cutoff = cutoff;
    }
    public Long getDir_id() {
        return dir_id;
    }
    public void setDir_id(Long dir_id) {
        this.dir_id = dir_id;
    }
    public String toString() {
        return "Product [id=" + id + ", productName=" + productName + ", brand=" + brand + ", suppliet=" + supplier
                + ", salePrice=" + salePrice + ", costPrice=" + costPrice + ", cutoff=" + cutoff + ", dir_id=" + dir_id
                + "]";
    }
}

MyBatisUtil類

public enum MyBatisUtil {
    INSTANCE;

    private static SqlSessionFactory sessionFactory = null;

    static {
        try {
            sessionFactory = new SqlSessionFactoryBuilder().build(Resources
                    .getResourceAsStream("MyBatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public SqlSession openSession() {
        return sessionFactory.openSession();
    }
}

MyBatis的XML配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 引入db.properties文件 -->
    <properties resource="db.properties" />
    <!-- 爲類型起別名 -->
    <typeAliases>
        <typeAlias type="cn.itsource.shopping.domain.Product" alias="Product" />
    </typeAliases>
    <!-- 環境配置 -->
    <environments default="development">
        <!-- 連接數據的基本信息 -->
        <environment id="development">
            <!-- 事務管理器:JDBC的管理機制 -->
            <transactionManager type="JDBC" />
            <!-- 配置連接池(數據源) -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${usename}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>
    <!-- 關聯映射文件 -->
    <mappers>
        <mapper resource="cn\itsource\shopping\domain\ProductMapper.xml" />
    </mappers>
</configuration>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章