最近一直在學習Hibernate,在瞭解Hibernate分頁的原理之後,就想自己寫一個分頁代碼。
在寫代碼之前,我們需要知道Hibernate的一些分頁用到的函數
setFirstResult(Int i);//該函數返回的是分頁的起點
setMaxResults(int i);//該函數返回的是最多顯示幾條數據
有了這兩個函數,就可以得到想要的結果集。
現在有兩個問題
1.那就是怎樣獲取當前頁的id。
2.如何做讓id產生變化(++或–),使id傳入後臺,然後將新的值傳給前臺。
我們首先解決第一個問題,如何獲取當前頁的id。
這一點比較容易解決,下面的例子是用struts來實現的(主要就是將Page這個對象放在值棧中,通過值棧來獲取所有的信息)。
創建一個Page.java
public class Page {
/**
*
* 記錄當前頁的id
*
*/
private int pageId;
/**
* 每一頁的數量
*/
private int everyPageCount;
/**
* 總數量
*/
private int totalCount;
//省略get和set方法
創建PageAction
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class PageAction extends ActionSupport implements ModelDriven<Page> {
/**
*
*/
@SuppressWarnings("rawtypes")
private List list=null;
private Map<String, Object> session = ActionContext.getContext().getSession();
private static final long serialVersionUID = 1L;
private Page page = new Page();
public Page getModel() {
return page;
}
/**
*設置登錄的時候,默認當前頁的id爲1
*/
public String login() {
page.setPageId(1);
return "success";
}
public String add() {
//當點擊下一頁的時候pageId+1
page.setPageId(page.getPageId() + 1);
return "add";
}
public String before() {
//當點擊上一頁的時候pageId-1
page.setPageId(page.getPageId() - 1);
return "before";
}
}
接下來是jsp頁面
login.jsp
<body>
<a href="login.action">login</a>
</body>
分頁的頁面
index.jsp
想要用struts的標籤,需要添加
<%@taglib uri=”/struts-tags” prefix=”s”%>
<a href="before.action?pageId=<s:property value="pageId"/>">上一頁</a>
<s:property value="pageId"/>
<a href="add.action?pageId=<s:property value="pageId"/>">下一頁</a>
這樣就可以獲得當前頁的id並且不同的點擊會發生不同的變化
接下來就是如何在頁面得到自己想要的顯示
之前已經創建了一個Page.java,裏面有這些成員變量。
pageId(當前頁的id),everyPageCount(每一頁的數量),totalCount(數據的總量)。還差一個總頁數,
所以我們需要一個操作Page的類,我取名爲PageUtil.java
public class PageUtil {
private static int pageCount;
//得到總頁數
public static int getPageCount(int totalCount, int everyPageCount) {
if (everyPageCount >= totalCount) {
pageCount = 1;
} else {
pageCount = totalCount / everyPageCount + 1;
}
return pageCount;
}
/**
* 是否有上一頁或下一頁
* @param pageId 當前頁的id
* @param pageCount 總頁數
* @return 有就返回true ,沒有就返回false
*/
public static boolean isHasPage(int pageId,int pageCount){
if (pageId==pageCount||pageId==1) {
return false;
}
return true;
}
}
操作Page的內已經有了,還差一個獲取數據的類,
我創建的一個News類
//需要實現Serializable接口,如果沒有可能會報錯誤,雖然不影響結果
public class News implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private String newsTitle;
private String newsContent;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNewsTitle() {
return newsTitle;
}
public void setNewsTitle(String newsTitle) {
this.newsTitle = newsTitle;
}
public String getNewsContent() {
return newsContent;
}
public void setNewsContent(String newsContent) {
this.newsContent = newsContent;
}
public News(){
super();
}
@Override
public String toString() {
return "News [id=" + id + ", newsTitle=" + newsTitle + ", newsContent="
+ newsContent + "]";
}
}
接下來是該類的映射文件
News.hbm.xml
<hibernate-mapping>
<class name="com.action.News" table="news">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="newsTitle" type="java.lang.String">
<column name="NEWS_TITLE" />
</property>
<property name="newsContent" type="java.lang.String">
<column name="NEWS_CONTENT" />
</property>
</class>
</hibernate-mapping>
最後就是最重要的分頁實現
HibernatePage.java
這裏面有幾點需要說明,爲了能讓這個成爲一個模板,我給每個函數都傳入了參數。裏面會有具體的說明
public class HibernatePage {
@SuppressWarnings("unchecked")
//object 需要持久化的對象 Hql 語句 "from xx",xx是持久化類的類名
//因此需要使用object.getClass().getSimpleName()來獲得持久化的類名
public static int getTotalCount(Object object) {
Session session = null;
List<News> list = null;
try {
session = HibernateUtil.getSession();
Transaction t = session.beginTransaction();
list = session.createQuery("from "+object.getClass().getSimpleName()).list();
t.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return list.size();
}
/**
*
* @param object 要查詢的持久化類
* @param pageId 當前頁
* @param everyPageCount 每一頁的數量
* @return
*/
@SuppressWarnings("unchecked")
public static List<Object> showPageList(Object object,int pageId,int everyPageCount){
System.out.println(object.getClass().getSimpleName());
Session session = null;
List<Object> list = null;
try {
session = HibernateUtil.getSession();
Transaction t = session.beginTransaction();
org.hibernate.Query query = session.createQuery("from "+object.getClass().getSimpleName());;
if (pageId==1) {
//如果當前頁id爲1
//需要從第0條讀取
query.setFirstResult(pageId-1);
}
//如果當前頁不爲1 從當前頁-1,乘以每一頁的數量開始讀取參數爲0,代表從第一條開始讀取
query.setFirstResult((pageId-1)*everyPageCount);
query.setMaxResults(everyPageCount);
list=query.list();
t.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
System.out.println(list);
return list;
}
//這個是我做的一個測試
public static void main(String[] args) {
News news=new News();
showPageList(news, 1, 3);
}
}
主體部分基本上已經完成了
接下來就是Action當中的一些修改,以及頁面的顯示
最新版的Action代碼如下所示
PageAction.java
public class PageAction extends ActionSupport implements ModelDriven<Page> {
/**
*
*/
@SuppressWarnings("rawtypes")
private List list=null;
private Map<String, Object> session = ActionContext.getContext().getSession();
private static final long serialVersionUID = 1L;
private Page page = new Page();
public Page getModel() {
return page;
}
public String login() {
//設置當前頁爲1
page.setPageId(1);
//得到第一頁的數據
test(new News(),page.getPageId(),3);
return "success";
}
public String add() {
//每次都會自己加1
page.setPageId(page.getPageId() + 1);
//將得到的新頁數顯示出來
test(new News(),page.getPageId(),3);
return "add";
}
public String before() {
//每次都會自己減1
page.setPageId(page.getPageId() - 1);
//將得到的新頁數顯示出來
test(new News(),page.getPageId(),3);
return "before";
}
/**
*
* @param object 要分頁的對象
* @param pageId 當前頁
* @param count 每一頁的數量
*/
public void test(Object object,int pageId,int count){
//得到總頁數
int pageCount=PageUtil.getPageCount(HibernatePage.getTotalCount(object), count);
//將值放進session中
session.put("pageCount",pageCount);
//獲取當前頁的數據
list =HibernatePage.showPageList(object, pageId , count);
//將值放進session中
session.put("list",
list);
}
}
index.jsp
struts的標籤還是挺好用的
<table border="1px">
<!--我遍歷的是news這個對象的id-->
<s:iterator value="#session.list" id="list">
<tr>
<td>
<s:property value="#list.id"/>
</td>
</tr>
</s:iterator>
</table>
<a href="before.action?pageId=<s:property value="pageId"/>">
<!--判斷是否有上一頁, 如果沒有就不顯示上一頁的這個a標籤-->
<s:if test="pageId>1">
上一頁
</s:if>
</a>
<s:if test="pageId<=1">
沒有上一頁了
</s:if>
<s:property value="pageId"/>/<s:property value="#session.pageCount"/>
<a href="add.action?pageId=<s:property value="pageId"/>">
<s:if test="pageId<3">下一頁 </s:if></a>
<!--判斷是否有下一頁-->
<s:if test="pageId>=3">
沒有下一頁了
</s:if>
struts.xml
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="index" />
<global-results>
<result name="error">/WEB-INF/jsp/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"/>
</global-exception-mappings>
<action name="login" class="com.action.ActionTest" method="login">
<result name="success">/index.jsp</result>
</action>
<action name="add" class="com.action.ActionTest" method="add">
<result name="add">/index.jsp</result>
</action>
<action name="before" class="com.action.ActionTest" method="before">
<result name="before">/index.jsp</result>
</action>
</package>
<include file="example.xml"/>
<!-- Add packages here -->
</struts>
最後說一下結語吧,該程序我總感覺有些彆扭,但畢竟是我所做的第一個分頁程序,如果有什麼好的建議可以留言。
最後說一句吐槽:學的越多,就會對其越來越敬畏,就會感覺自己是多麼的渺小。