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>