SSH整合實現分頁查詢(兩種方式)
介紹:
使用SSH整合開發,進行分頁查詢,我採用了hibernate的兩種不同物件來操作,第一種:DetachedCriteria離線物件;第一種:是hibernateTemplate模板的HibernateCallback<>()函式回撥,實際上它是一個介面,使用它時,需要實現它裡面的方法。
分頁思路:
剛開始我也覺得分頁查詢很難,但其實理清了思路之後,其實一點都不難。
其實分頁的目的,是為前臺使用者服務的,作用在於讓資料有規則性的顯示給使用者。
重點來了,如何實現呢?
1、使用hibernate框架操作持久層運算元據時,他為我們提供了兩個分頁的函式:setFirstResult() 設定起始查詢索引、setMaxResults()設定每次查詢多少條。還有表的總記錄數,可以使用find(hql).size()來獲取,到此分頁時,持久層所做的工作,就到此結束了。
2、上面說到從資料庫中獲取分頁資料,如果不使用傳參方式進行獲取資料時,那只是一個固定的一頁資料,資料永遠不會變,它不符合我們的前臺需求,前臺客戶所需的功能,是可以靈活的點選上一頁,下一頁或跳頁來顯示資料,因此客戶點選頁數時候,就會向後臺傳遞了引數發出請求,獲取資料。這時候,就需要進行持久層的傳參,來完成靈活的分頁了。該如何傳參,這應該是業務層的事情,service層的任務就是進行傳參,去完成客戶的需求和從資料庫中獲取分好頁的資料,並將分好頁的資料封裝好,並傳給前臺客戶。
3、service層該是如何封裝分頁的資料呢?這時就需要我們自定義一個分頁Bean來獲取分好頁的資料,通過這個Bean來傳給controller層,再傳給客戶。
思路總結:分頁的總思路,只需理解分頁Bean即可,這個bean相當於一艏小船,在來回不停地,將分好頁的資料運輸給前臺,再將前臺給它的資料清單去到service層中取資料,如何取,按照前臺的傳給它的引數來取資料。
第一種分頁方法:DetachedCriteria離線物件
1、實體類:User.java
import java.io.Serializable;
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private int userId;
private String userName;
private String userPassword;
private String userType;
public User() {
}
public User(String userName, String userPassword, String userType) {
this.userName = userName;
this.userPassword = userPassword;
this.userType = userType;
}
//get與set方法省略......
}
2、對映檔案:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.lice.entity">
<class name="User" table="user">
<id name="userId" type="int">
<column name="userId" precision="22" scale="0"/>
<generator class="identity" />
</id>
<property name="userName" type="java.lang.String">
<column name="userName" not-null="false" length="100" />
</property>
<property name="userPassword" type="java.lang.String">
<column name="userPassword" length="100" not-null="false" />
</property>
<property name="userType" type="java.lang.String">
<column name="userType" length="500" not-null="false"/>
</property>
</class>
</hibernate-mapping>
3、自定義PageBean
import java.io.Serializable;
import java.util.List;
/**
- 用於封裝分頁資料物件
- 伺服器做的事情
- @author 11606
*
*/
public class Page implements Serializable {
//這三條不是我們能知道的
private int currentPageNum; //當前頁數 (使用者提供)
private int pageSize=5; //每頁記錄條數 (設定)
private int totalRecords; //總記錄數 (從資料庫中查詢)
//能計算的資料
private int startIndex; //查詢開始記錄索引
private int totalPageNum; //總頁數
private List pageData; //分好頁的結果集 (結果條數為pageSize,設定好的)
private int prePageNum; //上一頁
private int nextPageNum; //下一頁
//用於顯示頁碼的屬性,在頁面上最多顯示9頁,當前頁在允許的情況下,永遠居中
private int beginPageNum;
private int endPageNum;
/**
* 要想使用此類,必須提供兩個引數
* @param currentPageNum 當前頁
* @param totalRecords 總記錄條數
*/
public Page(int currentPageNum,int totalRecords) {
this.currentPageNum = currentPageNum; //獲取當前頁引數
this.totalRecords = totalRecords; //獲取總記錄數
//計算開始索引
startIndex = (currentPageNum-1)*pageSize;
//計算總頁數
totalPageNum = totalRecords%pageSize==0? totalRecords/pageSize :totalRecords/pageSize+1;
//計算頁號
if(totalPageNum<9) {
//如果沒有9頁資料庫記錄條數
beginPageNum=1;
endPageNum=totalPageNum;
}else {
//前提條件是有9頁資料記錄條數,才執行
beginPageNum = currentPageNum-4;
endPageNum = currentPageNum+4;
if (beginPageNum<1) {
beginPageNum=1;
endPageNum=beginPageNum+8;
}
if (endPageNum>totalPageNum) {
endPageNum=totalPageNum;
beginPageNum=endPageNum-8;
}
}
}
public int getPrePageNum() {
prePageNum = currentPageNum-1;
if (prePageNum<1) {
prePageNum=1;
}
//計算上一頁
return prePageNum;
}
public int getNextPageNum() {
//計算下一頁
nextPageNum = currentPageNum+1;
if (nextPageNum>totalPageNum) {
nextPageNum=totalPageNum;
}
return nextPageNum;
}
public int getCurrentPageNum() {
return currentPageNum;
}
public void setCurrentPageNum(int currentPageNum) {
this.currentPageNum = currentPageNum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRecords() {
return totalRecords;
}
public void setTotalRecords(int totalRecords) {
this.totalRecords = totalRecords;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
this.startIndex = startIndex;
}
public int getTotalPageNum() {
return totalPageNum;
}
public void setTotalPageNum(int totalPageNum) {
this.totalPageNum = totalPageNum;
}
public List getPageData() {
return pageData;
}
public void setPageData(List pageData) {
this.pageData = pageData;
}
public void setPrePageNum(int prePageNum) {
this.prePageNum = prePageNum;
}
public void setNextPageNum(int nextPageNum) {
this.nextPageNum = nextPageNum;
}
public int getBeginPageNum() {
return beginPageNum;
}
public void setBeginPageNum(int beginPageNum) {
this.beginPageNum = beginPageNum;
}
public int getEndPageNum() {
return endPageNum;
}
public void setEndPageNum(int endPageNum) {
this.endPageNum = endPageNum;
}
}
注意:page最重要的有三個引數,是我們不知道,不能少定義,其他的定義可有可無,根據需要
三個引數數:
1、currentPageNum; //當前頁數 (使用者提供)
2、pageSize=5; //每頁記錄條數 (需要設定)
totalRecords; //總記錄數 (從資料庫中查詢)
4、持久層:
4.1UserDao.java
/**
*分頁查詢
* @param dCriteria 查詢條
* @param firstResult 查詢的開始記錄索引
* @param maxResults 每次查詢的記錄條數
* @return
*/
List<User> findAllForPage(DetachedCriteria dCriteria,int firstResult,int maxResults);
/**
* 查詢總記錄條數
* @param dCriteria 查詢條件
* @return
*/
int findTotalRecords(DetachedCriteria dCriteria);
4.2UserDaoImpl.java
/**
* 查詢總記錄條數
* @param dCriteria 查詢條件
* @return
*/
@Override
public int findTotalRecords(DetachedCriteria dCriteria) {
//hibernateTemplate.findByCriteria(dCriteria) 返回的的是集合物件,不是int
dCriteria.setProjection(Projections.count("userId")); //等同於 select count(*);獲取表總記錄數
List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(dCriteria);
return list.isEmpty()? 0:list.get(0).intValue();//獲取這個集合的數量,即獲取表中總記錄數
}
/**
*分頁查詢
* @param dCriteria 查詢條
* @param firstResult 查詢的開始記錄索引
* @param maxResults 每次查詢的記錄條數
* @return
*/
@Override
public List<User> findAllForPage(DetachedCriteria dCriteria, int firstResult, int maxResults) {
//將之前的設定清空
dCriteria.setProjection(null);
return (List<User>) hibernateTemplate.findByCriteria(dCriteria, firstResult, maxResults);
}
值得注意的是:dCriteria.setProjection(null);是因為,一個物件被呼叫了兩次,需要將dCriteria物件的值清空,不然查詢不出來。
5、業務層:
5.1UserService.java
/**
* 分頁查詢業務
* @param dCriteria 查詢條件
* @param num 當前頁 (業務方法中無法獲取,使用者點選,傳引數進來)
* @return page 封裝好的分頁資訊
*/
Page findAllForPage(DetachedCriteria dCriteria,Integer num);
5.2UserServiceImpl.java
/**
* 分頁查詢業務
* @param dCriteria 查詢條件
* @param num 當前頁 (業務方法中無法獲取,使用者點選,傳引數進來)
* @return page 封裝好的分頁資訊
*/
@Override
public Page findAllForPage(DetachedCriteria dCriteria, Integer num) {
//1.準備當前頁的資訊
int currentPageNum = 1;
if (num!=null) {
currentPageNum = num;
}
//2.獲取總記錄條數
int totalRecords = userDao.findTotalRecords(dCriteria);
//3.建立page物件
Page page = new Page(currentPageNum, totalRecords);
//4.使用page物件中的資料,查詢帶有分頁的結果集
List<User> pageData = userDao.findAllForPage(dCriteria, page.getStartIndex(), page.getPageSize());
//5.將查詢出來的資料封裝到page物件
page.setPageData(pageData);
//返回page物件
return page;
}
6、控制層
import javax.annotation.Resource;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import cn.lice.entity.User;
import cn.lice.service.UserService;
import cn.lice.utils.Page;
@Controller("userQueryAction")
@Scope("prototype")
@ParentPackage("struts-default")
@Namespace("/user")
@Results({
@Result(name="success", type="dispatcher",location="/jsp/user/showuser.jsp"),
@Result(name="error", type="dispatcher",location="/jsp/error/error.jsp")
})
public class UserQueryAction extends ActionSupport implements ModelDriven<User>{
private static final long serialVersionUID = 213518999309249850L;
private User user = new User();
@Override
public User getModel() {
return user;
}
private Page page; //聲名page物件值棧
private Integer num; //當前頁
//注入業務層屬性
@Resource(name="userService")
private UserService userService;
@Action("userQuery")
public String userQuery() throws Exception {
DetachedCriteria dCriteria = DetachedCriteria.forClass(User.class);//等同from User;
//獲取所有使用者
page=userService.findAllForPage(dCriteria, num);
ServletActionContext.getRequest().setAttribute("page", page);
return SUCCESS;
}
//page
public Page getPage() {
return page;
}
public void setPage(Page page) {
this.page = page;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
}
7、jsp檔案
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
}
<meta charset="utf-8">
<title>使用者資訊</title>
<script type="text/javascript">
function deleteUser(userId) {
var sure = window.confirm("確定刪除嗎?");
if (sure) {
window.location.href="${pageContext.request.contextPath}/user/delete.action?userId="+userId;
}
}
function updateUser(userId) {
window.location.href="${pageContext.request.contextPath}/user/editUIUser.action?userId="+userId;
</script>
</head>
<body>
<h3>使用者資訊</h3>
<s:form action="/user/userQuery.action">
<s:hidden name="num" value="" id="pagenum">/s:hidden
<table border="1" width="400" cellpadding="0" cellspacing="0" >
<tr>
<td>使用者ID</td>
<td>使用者名稱</td>
<td>使用者密碼</td>
<td>使用者型別</td>
<td>是否刪除</td>
<td>是否更新</td>
</tr>
<s:iterator value="#request.page.pageData" var="page">
<tr>
<td align="center"><s:property value="#page.userId"/></td>
<td align="center"><s:property value="#page.userName"/></td>
<td align="center"><s:property value="#page.userPassword"/></td>
<td align="center"><s:property value="#page.userType"/></td>
<td><s:a href="javascript:updateUser('%{userId}')">更新/s:a</td>
<td><s:a href="javascript:deleteUser('%{userId}')">刪除/s:a</td>
</tr>
/s:iterator
</table>
<table>
<tr>
<td align="center">
<!-- 分頁開始 -->
<%@ include file="/jsp/commons/page.jsp" %>
<!-- 分頁結束 -->
</td>
</tr>
</table>
/s:form
<br>
新增使用者
</body>
</html>
8、公共引用的分頁jsp檔案
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<script type="text/javascript">
function topage(num) {
//1.給表單提供一個隱藏域,用於提供當前頁
document.getElementById("pagenum").value = num;
//提交表單
document.forms[0].submit();
}
</script>
9、效果顯示
第二種方法:hibernateTemplate模板的HibernateCallback<>()函式回撥
1、Dao層
import java.util.List;
import cn.itcast.pojo.OrderItem;
/**
- 訂單分頁持久化介面
- @author 11606
*
*/
public interface OrderDao {
/**
- 分頁查詢
- @param hql 查詢條件
- @param firstResult 查詢開始記錄索引
- @param maxResults 查詢最大記錄數
- @return 返回一頁資料
*/
public List<OrderItem> findForPage(final String hql,final int firstResult,final int maxResults);
/**
- 查詢總記錄數
- @param hql 查詢條件
- @return 總記錄數
*/
public int findTotalRow(final String hql);
}
實現類:
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.HibernateTemplate;
import cn.itcast.dao.OrderDao;
import cn.itcast.pojo.OrderItem;
/**
- 分頁dao層實現類
- @author 11606
*
*/
public class OrderDaoImpl implements OrderDao {
private HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
/**
- 分頁查詢
- @param hql 查詢條件
- @param firstResult 查詢開始記錄索引
- @param maxResults 查詢最大記錄數
- @return 返回一頁的資料
*/
@Override
public List<OrderItem> findForPage(String hql, int firstResult, int maxResults) {
List<OrderItem> list = (List<OrderItem>) hibernateTemplate.execute(new HibernateCallback<List<OrderItem>>() {
@Override
public List<OrderItem> doInHibernate(Session session) throws HibernateException {
Query query = session.createQuery(hql); //查詢條件
query.setFirstResult(firstResult); //起始查詢索引
query.setMaxResults(maxResults); //查詢最大記錄數
List<OrderItem> list = query.list();
//session.close();
return list;
}
/**
- 查詢總記錄數
- @param hql 查詢條件
- @return 返回總記錄數
*/
@Override
public int findTotalRow(String hql) {
return hibernateTemplate.find(hql).size(); //總記錄數
}
}
2、Service層
public interface OrderService {
/**
* 訂單業務分頁查詢
* @param hql 查詢條件
* @param num 當前頁數
* @return 返回一頁資料結果集
*/
public PageBean<OrderItem> findForPage(String hql,Integer num);
}
實現類:
import java.util.List;
import cn.itcast.bean.PageBean;
import cn.itcast.dao.OrderDao;
import cn.itcast.pojo.OrderItem;
import cn.itcast.service.OrderService;
public class OrderServiceImpl implements OrderService {
private OrderDao orderDao;
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
/**
* 訂單業務分頁查詢
* @param hql 查詢條件
* @param num 當前頁數
* @return 返回一頁資料結果集
*/
@Override
public PageBean<OrderItem> findForPage(String hql, Integer num) {
//2.設定當前頁資訊
int currentPageNum =1 ;
if (num!=0) {
currentPageNum = num;
}
//3.總記錄數
int totalRecords = orderDao.findTotalRow(hql);
//1.建立分頁物件
PageBean<OrderItem> pageBean = new PageBean<>(currentPageNum, totalRecords);
//4.使用page物件中的資料,查詢帶有分頁的結果集
List<OrderItem> list = orderDao.findForPage(hql, pageBean.getStartIndex(), pageBean.getPageSize());
//2.給分頁物件傳入結果集
pageBean.setPageData(list);
return pageBean;
}
}
3、controller層
import com.opensymphony.xwork2.ActionSupport;
/**
- 分頁action
- @author 11606
*
*/
import cn.itcast.bean.PageBean;
import cn.itcast.pojo.OrderItem;
import cn.itcast.service.OrderService;
public class PageAction extends ActionSupport {
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
private int num; //當前頁數
private PageBean<OrderItem> pageBean; //分頁值棧
public String pageForOrder() {
String hql = "from OrderItem";
pageBean = orderService.findForPage(hql, num);
return SUCCESS;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public PageBean<OrderItem> getPageBean() {
return pageBean;
}
public void setPageBean(PageBean<OrderItem> pageBean) {
this.pageBean = pageBean;
}
}
兩種方法:所用的分頁Bean是一樣的,頁面jsp檔案也是一樣。
值得一提的是第二種方法使用HibernateCallback<List>()函式回撥,此種方法可以取得session物件,可以很靈活的運算元據庫,但總是要實現介面方法,也有不便之處。兩種方法各有不同,僅供參考!
分頁查詢到此結束了,如果有錯誤請指出,共同學習,一起進步!當然分頁查詢可以有很多種方法,也可以藉助一些很方便的外掛來完成了,大家可以分享一下,
相關文章
- SSH框架下的分頁查詢框架
- 【記錄】SSH分頁查詢功能
- indexdb實現分頁查詢Index
- Java中Elasticsearch 實現分頁方式(三種方式)JavaElasticsearch
- SSM框架實現分頁查詢例子SSM框架
- c# winform 實現分頁查詢C#ORM
- 二分查詢的兩種實現形式遞迴和迭代遞迴
- 如何優雅地實現分頁查詢
- #MyBatis多表查詢 #多對一、一對多的兩種實現方式 @FDDLCMyBatis
- SSH:hiberate實現資料的查詢(單查詢和全查詢)
- ElasticSearch - 分頁查詢方式二 【scroll】滾動查詢(kibana、Java示例)ElasticsearchJava
- SpringMVC+Spring Data JPA +Bootstrap 分頁實現和模糊查詢分頁SpringMVCboot
- golang透過mysql語句實現分頁查詢GolangMySql
- golang通過mysql語句實現分頁查詢GolangMySql
- 使用SSH完成條件及分頁查詢的主要程式碼
- MyBatis實現分頁的方式MyBatis
- Elasticsearch 分頁查詢Elasticsearch
- 兩種方式實現輪播圖
- SpringBoot實現熱部署兩種方式!Spring Boot熱部署
- Spring實現IOC容器的兩種實現方式Spring
- SpringBoot 整合Mybatis + PageHelper 實現分頁Spring BootMyBatis
- 398、Java框架52 -【Hibernate - 分頁、兩種獲取方式】 2020.10.27Java框架
- Native 工程整合Flutter 的兩種方式Flutter
- MaxCompute如何對SQL查詢結果實現分頁獲取SQL
- JSP怎樣將查詢的資料實現分頁操作JS
- NET 集合分頁查詢
- AntDesignBlazor示例——分頁查詢Blazor
- MySQL的分頁查詢MySql
- ThinkPhp框架:分頁查詢PHP框架
- 分頁查詢優化優化
- SSH:查詢
- hibernate的三種查詢方式
- PHP 實現二分查詢PHP
- elasticsearch查詢之大資料集分頁查詢Elasticsearch大資料
- 兩種方式實現橫向滾動條
- 前端--實現隔行變色的兩種方式前端
- ViewPager兩種方式實現無限輪播Viewpager
- CQRS命令查詢分離架構的多種形式實現 - Kapil架構API