- 浏览: 21442 次
文章分类
最新评论
本文介绍一种分页组件的完整代码,最后封装了一个简单的jsp自定义标签
分页效果如下:
没有加页面效果,只是意思一下。这个分页的功能比较简单,不过更复杂的分页功能,原理也是差不多的
首先是Page对象
Java代码
1.public class Page {
2.
3. private static final int DEFAULT_PAGE_SIZE = 10;
4.
5. private static final int DEFAULT_CURRENT_PAGE = 1;
6.
7. private int currentPage;// 当前页数,通常在Action层设置
8.
9. private int pageSize;// 每页记录数,通常在Action层设置
10.
11. private int totalCount;// 总记录数,在DAO层设置
12.
13. public Page(int currentPage, int pageSize) {
14. this.currentPage = currentPage;
15. this.pageSize = pageSize;
16. }
17.
18. public Page(int currentPage) {
19. this.currentPage = currentPage;
20. this.pageSize = DEFAULT_PAGE_SIZE;
21. }
22.
23. public Page() {
24. this.currentPage = DEFAULT_CURRENT_PAGE;
25. this.pageSize = DEFAULT_PAGE_SIZE;
26. }
27.
28. public int getFirstIndex() {
29. return pageSize * (currentPage - 1);
30. }
31.
32. public boolean hasPrevious() {
33. return currentPage > 1;
34. }
35.
36. public boolean hasNext() {
37. return currentPage < getTotalPage();
38. }
39.
40. public int getTotalPage() {
41.
42. long remainder = totalCount % this.getPageSize();
43.
44. if (0 == remainder) {
45. return totalCount / this.getPageSize();
46. }
47.
48. return totalCount / this.getPageSize() + 1;
49. }
50.}
public class Page {
private static final int DEFAULT_PAGE_SIZE = 10;
private static final int DEFAULT_CURRENT_PAGE = 1;
private int currentPage;// 当前页数,通常在Action层设置
private int pageSize;// 每页记录数,通常在Action层设置
private int totalCount;// 总记录数,在DAO层设置
public Page(int currentPage, int pageSize) {
this.currentPage = currentPage;
this.pageSize = pageSize;
}
public Page(int currentPage) {
this.currentPage = currentPage;
this.pageSize = DEFAULT_PAGE_SIZE;
}
public Page() {
this.currentPage = DEFAULT_CURRENT_PAGE;
this.pageSize = DEFAULT_PAGE_SIZE;
}
public int getFirstIndex() {
return pageSize * (currentPage - 1);
}
public boolean hasPrevious() {
return currentPage > 1;
}
public boolean hasNext() {
return currentPage < getTotalPage();
}
public int getTotalPage() {
long remainder = totalCount % this.getPageSize();
if (0 == remainder) {
return totalCount / this.getPageSize();
}
return totalCount / this.getPageSize() + 1;
}
}
省略了必须的getter和setter方法。这里主要有3个字段currentPage、pageSize、totalCount,分别表示当前页、每页记录数、总记录数。基本上所有的分页组件,都需要这些字段
其实总页数totalPage也是必须的,但是这个字段是由pageSize和totalCount算出来的,所以即时计算得到比较好,如果也作为一个字段的话,那么和另外2个字段就不正交
getFirstIndex()方法也很重要,因为后面查询数据库的时候,需要作为第一条记录的标识,作为参数传给查询数据库的方法
下面是DAO的写法
Java代码
1.public interface IBookDAO extends IGenericDAO<Book> {
2.
3. public Book queryByIsbn(String isbn);
4.
5. public List<Book> queryByNameWithPage(String name, Page page);
6.
7. public List<Book> queryByNameWithoutPage(String name);
8.
9.}
public interface IBookDAO extends IGenericDAO<Book> {
public Book queryByIsbn(String isbn);
public List<Book> queryByNameWithPage(String name, Page page);
public List<Book> queryByNameWithoutPage(String name);
}
其中涉及到分页查询的就是queryByNameWithPage()方法,这个Page对象是从Action传递下来的
Java代码
1.@Repository
2.public class BookDAO extends GenericDAO<Book> implements IBookDAO {
3.
4. public BookDAO() {
5. super(Book.class);
6. }
7.
8. @Override
9. public Book queryByIsbn(String isbn) {
10. String hql = "from Book b where b.isbn = ?";
11. return queryForObject(hql, new Object[] { isbn });
12. }
13.
14. @Override
15. public List<Book> queryByNameWithPage(String name, Page page) {
16. String hql = "from Book b where b.name = ?";
17. return queryForList(hql, new Object[] { name }, page);
18. }
19.
20. @Override
21. public List<Book> queryByNameWithoutPage(String name) {
22. String hql = "from Book b where b.name = ?";
23. return queryForList(hql, new Object[] { name });
24. }
25.
26.}
@Repository
public class BookDAO extends GenericDAO<Book> implements IBookDAO {
public BookDAO() {
super(Book.class);
}
@Override
public Book queryByIsbn(String isbn) {
String hql = "from Book b where b.isbn = ?";
return queryForObject(hql, new Object[] { isbn });
}
@Override
public List<Book> queryByNameWithPage(String name, Page page) {
String hql = "from Book b where b.name = ?";
return queryForList(hql, new Object[] { name }, page);
}
@Override
public List<Book> queryByNameWithoutPage(String name) {
String hql = "from Book b where b.name = ?";
return queryForList(hql, new Object[] { name });
}
}
这里调用的是GenericDAO里的方法queryForList()
Java代码
1.@SuppressWarnings("unchecked")
2. protected List<T> queryForList(String hql, Object[] params, Page page) {
3.
4. generatePageTotalCount(hql, params, page);
5.
6. Query query = sessionFactory.getCurrentSession().createQuery(hql);
7. setQueryParams(query, params);
8. query.setFirstResult(page.getFirstIndex());
9. query.setMaxResults(page.getPageSize());
10. return query.list();
11. }
12.
13. /**
14. * 该方法会改变参数page的totalCount字段
15. *
16. * @param originHql
17. * 原始hql语句
18. * @param params
19. * 原始参数
20. * @param page
21. * 页面对象
22. */
23. private void generatePageTotalCount(String originHql, Object[] params,
24. Page page) {
25. String generatedCountHql = "select count(*) " + originHql;
26. Query countQuery = sessionFactory.getCurrentSession().createQuery(
27. generatedCountHql);
28. setQueryParams(countQuery, params);
29. int totalCount = ((Long) countQuery.uniqueResult()).intValue();
30. page.setTotalCount(totalCount);
31. }
@SuppressWarnings("unchecked")
protected List<T> queryForList(String hql, Object[] params, Page page) {
generatePageTotalCount(hql, params, page);
Query query = sessionFactory.getCurrentSession().createQuery(hql);
setQueryParams(query, params);
query.setFirstResult(page.getFirstIndex());
query.setMaxResults(page.getPageSize());
return query.list();
}
/**
* 该方法会改变参数page的totalCount字段
*
* @param originHql
* 原始hql语句
* @param params
* 原始参数
* @param page
* 页面对象
*/
private void generatePageTotalCount(String originHql, Object[] params,
Page page) {
String generatedCountHql = "select count(*) " + originHql;
Query countQuery = sessionFactory.getCurrentSession().createQuery(
generatedCountHql);
setQueryParams(countQuery, params);
int totalCount = ((Long) countQuery.uniqueResult()).intValue();
page.setTotalCount(totalCount);
}
这段代码关键有2点
一个是调用Page对象的getFirstIndex()方法和getPageSize()方法,确定查询结果的范围
另一个是设置Page对象自身的totalCount字段,因为Action里持有该Page对象的引用,所以根据totalCount和pageSize计算出totalPage之后,就可以在前台显示出总页数
接下来是Action层的写法(中间的Service层只是起一个传递作用和事务控制作用,省略)
Java代码
1.@Controller
2.@Scope("prototype")
3.public class BookAction extends ActionSupport {
4.
5. private static final long serialVersionUID = -4400311497910666205L;
6.
7. @Autowired
8. private IBookService bookService;
9.
10. private Page page;// 分页组件
11.
12. private List<Book> books;// 查询结果列表
13.
14. public String list() {
15. if (null == page) {
16. page = new Page();// 如果page对象为空,说明不是通过点击页码跳转
17. }
18. books = bookService.getBooks(page);
19. return SUCCESS;
20. }
21.}
@Controller
@Scope("prototype")
public class BookAction extends ActionSupport {
private static final long serialVersionUID = -4400311497910666205L;
@Autowired
private IBookService bookService;
private Page page;// 分页组件
private List<Book> books;// 查询结果列表
public String list() {
if (null == page) {
page = new Page();// 如果page对象为空,说明不是通过点击页码跳转
}
books = bookService.getBooks(page);
return SUCCESS;
}
}
这里省略了与分页无关的方法和字段,以及getter、setter方法
这里重点是list()方法,如果是通过jsp页面点击“上一页”、“下一页”的链接进入此方法的,那么struts2框架就会自动初始化Page对象。如果这个时候page对象为空,那么说明是用户直接进入该页面,就需要初始化一个Page对象(currentPage=1,表示是第一页)
该Page对象此时的totalCount是0,在查询之后,才会根据查询到的记录总数,设置totalCount的值,由于Action持有此Page的引用,所以可以在前台显示出来
下面是前台页面的写法
Jsp代码
1.<div id="page_area">
2.
3. <s:if test="page.hasPrevious()">
4. <a href="list.action?page.currentPage=${page.currentPage-1}">上一页</a>
5. </s:if>
6.
7. <span>第${page.currentPage}页</span>
8. <span>共${page.getTotalPage()}页</span>
9.
10. <s:if test="page.hasNext()">
11. <a href="list.action?page.currentPage=${page.currentPage+1}">下一页</a>
12. </s:if>
13.
14. </div>
<div id="page_area">
<s:if test="page.hasPrevious()">
<a href="list.action?page.currentPage=${page.currentPage-1}">上一页</a>
</s:if>
<span>第${page.currentPage}页</span>
<span>共${page.getTotalPage()}页</span>
<s:if test="page.hasNext()">
<a href="list.action?page.currentPage=${page.currentPage+1}">下一页</a>
</s:if>
</div>
里面用到了struts2的<s:if>标签,还有${}表达式。我感觉${]表达式还是很方便的,struts2封装的各种<s:>标签我倒是不喜欢用,自己用html标签开发,我觉得更灵活一点
这个分页组件在各个页面都可以用到,但是如果每个jsp都要拷贝这段代码,就不好了,所以需要把它封装成标签
封装后的效果是这样的:
Jsp代码
1.<wfm:page page="${page}" />
<wfm:page page="${page}" />
下面就介绍下这个自定义标签的开发
首先需要在WEB-INF目录下创建一个.tld文件,只要放在WEB-INF目录下就可以了,所以一般会单独建一个子目录tld来保存
这个tld内容如下
Xml代码
1.<?xml version="1.0" encoding="UTF-8" ?>
2.
3.<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
6. version="2.0">
7.
8. <description>Workforce Tag Lib</description>
9. <tlib-version>1.0</tlib-version>
10. <short-name>WorkforceTagLibrary</short-name>
11. <uri>/wfm-tags</uri>
12.
13. <tag>
14. <description>generate page bar</description>
15. <name>page</name>
16. <tag-class>com.huawei.inoc.framework.tag.PageTag</tag-class>
17. <body-content>empty</body-content>
18. <attribute>
19. <name>page</name>
20. <required>true</required>
21. <rtexprvalue>true</rtexprvalue>
22. </attribute>
23. </tag>
24.
25.</taglib>
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>Workforce Tag Lib</description>
<tlib-version>1.0</tlib-version>
<short-name>WorkforceTagLibrary</short-name>
<uri>/wfm-tags</uri>
<tag>
<description>generate page bar</description>
<name>page</name>
<tag-class>com.huawei.inoc.framework.tag.PageTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>page</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
上面比较重要的元素是<uri>,后面在jsp页面里使用这个标签的时候会用到,然后可以定义多个<tag>元素,每个都是一个标签,命名都很清晰,就不用解释了。其中<rtexprvalue>这个标签,设置为true之后,则此属性支持变量
下面是标签的实现类
Java代码
1.public class PageTag extends SimpleTagSupport {
2.
3. private Page page;
4.
5. @Override
6. public void doTag() throws JspException, IOException {
7. String content = generateContent();
8. getJspContext().getOut().write(content);
9. }
10.
11. private String generateContent() {
12.
13. StringBuilder response = new StringBuilder();
14.
15. response.append("<div id=\"page_area\">");
16.
17. if (page.hasPrevious()) {
18. response.append("<a href=\"list.action?page.currentPage="
19. + (page.getCurrentPage() - 1) + "\">上一页</a>");
20. }
21.
22. response.append("<span>第" + page.getCurrentPage() + "页</span>");
23. response.append("<span>共" + page.getTotalPage() + "页</span>");
24.
25. if (page.hasNext()) {
26. response.append("<a href=\"list.action?page.currentPage="
27. + (page.getCurrentPage() + 1) + "\">下一页</a>");
28. }
29.
30. response.append("</div>");
31.
32. return response.toString();
33. }
34.
35. public Page getPage() {
36. return page;
37. }
38.
39. public void setPage(Page page) {
40. this.page = page;
41. }
42.
43.}
public class PageTag extends SimpleTagSupport {
private Page page;
@Override
public void doTag() throws JspException, IOException {
String content = generateContent();
getJspContext().getOut().write(content);
}
private String generateContent() {
StringBuilder response = new StringBuilder();
response.append("<div id=\"page_area\">");
if (page.hasPrevious()) {
response.append("<a href=\"list.action?page.currentPage="
+ (page.getCurrentPage() - 1) + "\">上一页</a>");
}
response.append("<span>第" + page.getCurrentPage() + "页</span>");
response.append("<span>共" + page.getTotalPage() + "页</span>");
if (page.hasNext()) {
response.append("<a href=\"list.action?page.currentPage="
+ (page.getCurrentPage() + 1) + "\">下一页</a>");
}
response.append("</div>");
return response.toString();
}
public Page getPage() {
return page;
}
public void setPage(Page page) {
this.page = page;
}
}
上面的代码很简单,jsp2.0之后,要实现自定义标签是很容易的,继承SimpleTagSupport类,实现doTag()方法即可,如果需要设置一些属性的话,声明为字段,并添加getter和setter方法
最后是jsp页面的引用方法
Jsp代码
1.<%@ taglib prefix="wfm" uri="/wfm-tags"%>
<%@ taglib prefix="wfm" uri="/wfm-tags"%>
Jsp代码
1.<wfm:page page="${page}" />
<wfm:page page="${page}" />
在比较早的版本里,还需要在web.xml里增加tag-lib的配置,从某个版本的servlet规范之后(好像是3.0),就不需要了,容器会自动到WEB-INF目录下加载所有的.tld文件
分页效果如下:
没有加页面效果,只是意思一下。这个分页的功能比较简单,不过更复杂的分页功能,原理也是差不多的
首先是Page对象
Java代码
1.public class Page {
2.
3. private static final int DEFAULT_PAGE_SIZE = 10;
4.
5. private static final int DEFAULT_CURRENT_PAGE = 1;
6.
7. private int currentPage;// 当前页数,通常在Action层设置
8.
9. private int pageSize;// 每页记录数,通常在Action层设置
10.
11. private int totalCount;// 总记录数,在DAO层设置
12.
13. public Page(int currentPage, int pageSize) {
14. this.currentPage = currentPage;
15. this.pageSize = pageSize;
16. }
17.
18. public Page(int currentPage) {
19. this.currentPage = currentPage;
20. this.pageSize = DEFAULT_PAGE_SIZE;
21. }
22.
23. public Page() {
24. this.currentPage = DEFAULT_CURRENT_PAGE;
25. this.pageSize = DEFAULT_PAGE_SIZE;
26. }
27.
28. public int getFirstIndex() {
29. return pageSize * (currentPage - 1);
30. }
31.
32. public boolean hasPrevious() {
33. return currentPage > 1;
34. }
35.
36. public boolean hasNext() {
37. return currentPage < getTotalPage();
38. }
39.
40. public int getTotalPage() {
41.
42. long remainder = totalCount % this.getPageSize();
43.
44. if (0 == remainder) {
45. return totalCount / this.getPageSize();
46. }
47.
48. return totalCount / this.getPageSize() + 1;
49. }
50.}
public class Page {
private static final int DEFAULT_PAGE_SIZE = 10;
private static final int DEFAULT_CURRENT_PAGE = 1;
private int currentPage;// 当前页数,通常在Action层设置
private int pageSize;// 每页记录数,通常在Action层设置
private int totalCount;// 总记录数,在DAO层设置
public Page(int currentPage, int pageSize) {
this.currentPage = currentPage;
this.pageSize = pageSize;
}
public Page(int currentPage) {
this.currentPage = currentPage;
this.pageSize = DEFAULT_PAGE_SIZE;
}
public Page() {
this.currentPage = DEFAULT_CURRENT_PAGE;
this.pageSize = DEFAULT_PAGE_SIZE;
}
public int getFirstIndex() {
return pageSize * (currentPage - 1);
}
public boolean hasPrevious() {
return currentPage > 1;
}
public boolean hasNext() {
return currentPage < getTotalPage();
}
public int getTotalPage() {
long remainder = totalCount % this.getPageSize();
if (0 == remainder) {
return totalCount / this.getPageSize();
}
return totalCount / this.getPageSize() + 1;
}
}
省略了必须的getter和setter方法。这里主要有3个字段currentPage、pageSize、totalCount,分别表示当前页、每页记录数、总记录数。基本上所有的分页组件,都需要这些字段
其实总页数totalPage也是必须的,但是这个字段是由pageSize和totalCount算出来的,所以即时计算得到比较好,如果也作为一个字段的话,那么和另外2个字段就不正交
getFirstIndex()方法也很重要,因为后面查询数据库的时候,需要作为第一条记录的标识,作为参数传给查询数据库的方法
下面是DAO的写法
Java代码
1.public interface IBookDAO extends IGenericDAO<Book> {
2.
3. public Book queryByIsbn(String isbn);
4.
5. public List<Book> queryByNameWithPage(String name, Page page);
6.
7. public List<Book> queryByNameWithoutPage(String name);
8.
9.}
public interface IBookDAO extends IGenericDAO<Book> {
public Book queryByIsbn(String isbn);
public List<Book> queryByNameWithPage(String name, Page page);
public List<Book> queryByNameWithoutPage(String name);
}
其中涉及到分页查询的就是queryByNameWithPage()方法,这个Page对象是从Action传递下来的
Java代码
1.@Repository
2.public class BookDAO extends GenericDAO<Book> implements IBookDAO {
3.
4. public BookDAO() {
5. super(Book.class);
6. }
7.
8. @Override
9. public Book queryByIsbn(String isbn) {
10. String hql = "from Book b where b.isbn = ?";
11. return queryForObject(hql, new Object[] { isbn });
12. }
13.
14. @Override
15. public List<Book> queryByNameWithPage(String name, Page page) {
16. String hql = "from Book b where b.name = ?";
17. return queryForList(hql, new Object[] { name }, page);
18. }
19.
20. @Override
21. public List<Book> queryByNameWithoutPage(String name) {
22. String hql = "from Book b where b.name = ?";
23. return queryForList(hql, new Object[] { name });
24. }
25.
26.}
@Repository
public class BookDAO extends GenericDAO<Book> implements IBookDAO {
public BookDAO() {
super(Book.class);
}
@Override
public Book queryByIsbn(String isbn) {
String hql = "from Book b where b.isbn = ?";
return queryForObject(hql, new Object[] { isbn });
}
@Override
public List<Book> queryByNameWithPage(String name, Page page) {
String hql = "from Book b where b.name = ?";
return queryForList(hql, new Object[] { name }, page);
}
@Override
public List<Book> queryByNameWithoutPage(String name) {
String hql = "from Book b where b.name = ?";
return queryForList(hql, new Object[] { name });
}
}
这里调用的是GenericDAO里的方法queryForList()
Java代码
1.@SuppressWarnings("unchecked")
2. protected List<T> queryForList(String hql, Object[] params, Page page) {
3.
4. generatePageTotalCount(hql, params, page);
5.
6. Query query = sessionFactory.getCurrentSession().createQuery(hql);
7. setQueryParams(query, params);
8. query.setFirstResult(page.getFirstIndex());
9. query.setMaxResults(page.getPageSize());
10. return query.list();
11. }
12.
13. /**
14. * 该方法会改变参数page的totalCount字段
15. *
16. * @param originHql
17. * 原始hql语句
18. * @param params
19. * 原始参数
20. * @param page
21. * 页面对象
22. */
23. private void generatePageTotalCount(String originHql, Object[] params,
24. Page page) {
25. String generatedCountHql = "select count(*) " + originHql;
26. Query countQuery = sessionFactory.getCurrentSession().createQuery(
27. generatedCountHql);
28. setQueryParams(countQuery, params);
29. int totalCount = ((Long) countQuery.uniqueResult()).intValue();
30. page.setTotalCount(totalCount);
31. }
@SuppressWarnings("unchecked")
protected List<T> queryForList(String hql, Object[] params, Page page) {
generatePageTotalCount(hql, params, page);
Query query = sessionFactory.getCurrentSession().createQuery(hql);
setQueryParams(query, params);
query.setFirstResult(page.getFirstIndex());
query.setMaxResults(page.getPageSize());
return query.list();
}
/**
* 该方法会改变参数page的totalCount字段
*
* @param originHql
* 原始hql语句
* @param params
* 原始参数
* @param page
* 页面对象
*/
private void generatePageTotalCount(String originHql, Object[] params,
Page page) {
String generatedCountHql = "select count(*) " + originHql;
Query countQuery = sessionFactory.getCurrentSession().createQuery(
generatedCountHql);
setQueryParams(countQuery, params);
int totalCount = ((Long) countQuery.uniqueResult()).intValue();
page.setTotalCount(totalCount);
}
这段代码关键有2点
一个是调用Page对象的getFirstIndex()方法和getPageSize()方法,确定查询结果的范围
另一个是设置Page对象自身的totalCount字段,因为Action里持有该Page对象的引用,所以根据totalCount和pageSize计算出totalPage之后,就可以在前台显示出总页数
接下来是Action层的写法(中间的Service层只是起一个传递作用和事务控制作用,省略)
Java代码
1.@Controller
2.@Scope("prototype")
3.public class BookAction extends ActionSupport {
4.
5. private static final long serialVersionUID = -4400311497910666205L;
6.
7. @Autowired
8. private IBookService bookService;
9.
10. private Page page;// 分页组件
11.
12. private List<Book> books;// 查询结果列表
13.
14. public String list() {
15. if (null == page) {
16. page = new Page();// 如果page对象为空,说明不是通过点击页码跳转
17. }
18. books = bookService.getBooks(page);
19. return SUCCESS;
20. }
21.}
@Controller
@Scope("prototype")
public class BookAction extends ActionSupport {
private static final long serialVersionUID = -4400311497910666205L;
@Autowired
private IBookService bookService;
private Page page;// 分页组件
private List<Book> books;// 查询结果列表
public String list() {
if (null == page) {
page = new Page();// 如果page对象为空,说明不是通过点击页码跳转
}
books = bookService.getBooks(page);
return SUCCESS;
}
}
这里省略了与分页无关的方法和字段,以及getter、setter方法
这里重点是list()方法,如果是通过jsp页面点击“上一页”、“下一页”的链接进入此方法的,那么struts2框架就会自动初始化Page对象。如果这个时候page对象为空,那么说明是用户直接进入该页面,就需要初始化一个Page对象(currentPage=1,表示是第一页)
该Page对象此时的totalCount是0,在查询之后,才会根据查询到的记录总数,设置totalCount的值,由于Action持有此Page的引用,所以可以在前台显示出来
下面是前台页面的写法
Jsp代码
1.<div id="page_area">
2.
3. <s:if test="page.hasPrevious()">
4. <a href="list.action?page.currentPage=${page.currentPage-1}">上一页</a>
5. </s:if>
6.
7. <span>第${page.currentPage}页</span>
8. <span>共${page.getTotalPage()}页</span>
9.
10. <s:if test="page.hasNext()">
11. <a href="list.action?page.currentPage=${page.currentPage+1}">下一页</a>
12. </s:if>
13.
14. </div>
<div id="page_area">
<s:if test="page.hasPrevious()">
<a href="list.action?page.currentPage=${page.currentPage-1}">上一页</a>
</s:if>
<span>第${page.currentPage}页</span>
<span>共${page.getTotalPage()}页</span>
<s:if test="page.hasNext()">
<a href="list.action?page.currentPage=${page.currentPage+1}">下一页</a>
</s:if>
</div>
里面用到了struts2的<s:if>标签,还有${}表达式。我感觉${]表达式还是很方便的,struts2封装的各种<s:>标签我倒是不喜欢用,自己用html标签开发,我觉得更灵活一点
这个分页组件在各个页面都可以用到,但是如果每个jsp都要拷贝这段代码,就不好了,所以需要把它封装成标签
封装后的效果是这样的:
Jsp代码
1.<wfm:page page="${page}" />
<wfm:page page="${page}" />
下面就介绍下这个自定义标签的开发
首先需要在WEB-INF目录下创建一个.tld文件,只要放在WEB-INF目录下就可以了,所以一般会单独建一个子目录tld来保存
这个tld内容如下
Xml代码
1.<?xml version="1.0" encoding="UTF-8" ?>
2.
3.<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
6. version="2.0">
7.
8. <description>Workforce Tag Lib</description>
9. <tlib-version>1.0</tlib-version>
10. <short-name>WorkforceTagLibrary</short-name>
11. <uri>/wfm-tags</uri>
12.
13. <tag>
14. <description>generate page bar</description>
15. <name>page</name>
16. <tag-class>com.huawei.inoc.framework.tag.PageTag</tag-class>
17. <body-content>empty</body-content>
18. <attribute>
19. <name>page</name>
20. <required>true</required>
21. <rtexprvalue>true</rtexprvalue>
22. </attribute>
23. </tag>
24.
25.</taglib>
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>Workforce Tag Lib</description>
<tlib-version>1.0</tlib-version>
<short-name>WorkforceTagLibrary</short-name>
<uri>/wfm-tags</uri>
<tag>
<description>generate page bar</description>
<name>page</name>
<tag-class>com.huawei.inoc.framework.tag.PageTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>page</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
上面比较重要的元素是<uri>,后面在jsp页面里使用这个标签的时候会用到,然后可以定义多个<tag>元素,每个都是一个标签,命名都很清晰,就不用解释了。其中<rtexprvalue>这个标签,设置为true之后,则此属性支持变量
下面是标签的实现类
Java代码
1.public class PageTag extends SimpleTagSupport {
2.
3. private Page page;
4.
5. @Override
6. public void doTag() throws JspException, IOException {
7. String content = generateContent();
8. getJspContext().getOut().write(content);
9. }
10.
11. private String generateContent() {
12.
13. StringBuilder response = new StringBuilder();
14.
15. response.append("<div id=\"page_area\">");
16.
17. if (page.hasPrevious()) {
18. response.append("<a href=\"list.action?page.currentPage="
19. + (page.getCurrentPage() - 1) + "\">上一页</a>");
20. }
21.
22. response.append("<span>第" + page.getCurrentPage() + "页</span>");
23. response.append("<span>共" + page.getTotalPage() + "页</span>");
24.
25. if (page.hasNext()) {
26. response.append("<a href=\"list.action?page.currentPage="
27. + (page.getCurrentPage() + 1) + "\">下一页</a>");
28. }
29.
30. response.append("</div>");
31.
32. return response.toString();
33. }
34.
35. public Page getPage() {
36. return page;
37. }
38.
39. public void setPage(Page page) {
40. this.page = page;
41. }
42.
43.}
public class PageTag extends SimpleTagSupport {
private Page page;
@Override
public void doTag() throws JspException, IOException {
String content = generateContent();
getJspContext().getOut().write(content);
}
private String generateContent() {
StringBuilder response = new StringBuilder();
response.append("<div id=\"page_area\">");
if (page.hasPrevious()) {
response.append("<a href=\"list.action?page.currentPage="
+ (page.getCurrentPage() - 1) + "\">上一页</a>");
}
response.append("<span>第" + page.getCurrentPage() + "页</span>");
response.append("<span>共" + page.getTotalPage() + "页</span>");
if (page.hasNext()) {
response.append("<a href=\"list.action?page.currentPage="
+ (page.getCurrentPage() + 1) + "\">下一页</a>");
}
response.append("</div>");
return response.toString();
}
public Page getPage() {
return page;
}
public void setPage(Page page) {
this.page = page;
}
}
上面的代码很简单,jsp2.0之后,要实现自定义标签是很容易的,继承SimpleTagSupport类,实现doTag()方法即可,如果需要设置一些属性的话,声明为字段,并添加getter和setter方法
最后是jsp页面的引用方法
Jsp代码
1.<%@ taglib prefix="wfm" uri="/wfm-tags"%>
<%@ taglib prefix="wfm" uri="/wfm-tags"%>
Jsp代码
1.<wfm:page page="${page}" />
<wfm:page page="${page}" />
在比较早的版本里,还需要在web.xml里增加tag-lib的配置,从某个版本的servlet规范之后(好像是3.0),就不需要了,容器会自动到WEB-INF目录下加载所有的.tld文件
相关推荐
Hibernate分页查询小结
#### 三、Hibernate分页查询实现原理 ##### 3.1 使用SQL LIMIT实现分页 对于支持LIMIT关键字的数据库(例如MySQL),Hibernate会通过特定的方言(Dialect)来生成包含LIMIT关键字的SQL语句。具体实现如下: ```...
此外,优化查询,避免N+1查询问题,合理设计实体关系,都能有效提升Hibernate分页查询的效率。 总结起来,Hibernate的分页查询和数据库连接管理是其强大功能的重要组成部分。正确理解和使用这些特性,能够帮助...
标题与描述均提到了“Hibernate分页的设计和编码”,这表明文章主要聚焦于如何在Hibernate框架中实现数据分页功能。下面将详细解析这一主题的关键知识点。 ### Hibernate分页概念 Hibernate是Java环境下一个开放源...
让我们深入探讨Hibernate分页查询的相关知识点。 一、Hibernate分页原理 Hibernate分页查询基于SQL的LIMIT和OFFSET子句,通过Session的createQuery或createSQLQuery方法创建查询,并设置FirstResult和MaxResults...
hibernate分页(无排序,搜索,仅仅分页显示),服务器端分页在datatables上展现,有关 datatables的知识请关注它的官网http://www.datatables.net/,datatables的功能很 全面。 2,建表的sql--studentinfo和插入...
总结起来,"hibernate分页代码"是一个关于如何在Hibernate中进行分页查询的实践示例,适用于在MyEclipse环境下运行。通过Criteria API或HQL,开发者能够方便地实现分页功能,提升应用性能,为用户提供更好的体验。...
在"Struts + Hibernate 分页实现"这个项目中,重点在于如何在Web应用中整合这两个框架,并实现数据的分页显示。分页是大型数据集处理时常见的需求,它能够帮助用户更有效地浏览和管理大量信息,避免一次性加载所有...
本篇文章将详细讲解如何在基于Struts2、Spring和Hibernate的项目中实现分页功能。 首先,我们从DAO层开始。在`MemberDao`接口中,我们定义了两个关键的方法,一个是用于分页查询,另一个是获取所有记录的数量。这两...
在"Struts+Hibernate分页及条件查询练习"这个项目中,开发者可能采用了以下步骤: 1. **配置Struts和Hibernate**:首先,需要在项目中引入Struts和Hibernate的相关库,配置Struts的struts-config.xml文件和...
1. **配置Hibernate分页**: 在Hibernate中,我们通常使用`Criteria`或`Query` API进行分页查询。`Criteria`提供了一种更面向对象的方式来执行SQL查询,而`Query` API则对应于原生的SQL语句。在这些API中,我们可以...
hibernate分页 博文链接:https://iomo.iteye.com/blog/243518
本篇主要围绕"Hibernate分页查询效果"这一主题,深入探讨如何利用Hibernate框架实现高效、便捷的分页功能。 首先,Hibernate是一个优秀的Java持久化框架,它提供了ORM(对象关系映射)解决方案,使得开发者可以使用...
这个"高效率的dw+spring+hibernate分页演示例子"提供了一个实用的示例,展示了如何将这三个框架整合起来,以实现高效的数据分页功能。 首先,让我们来逐一了解这三个技术: 1. **DWR (Direct Web Remoting)**:DWR...
### Hibernate分页基础 1. **Criteria API**:Hibernate的Criteria API允许我们创建动态查询,同时也支持分页。通过设置`setFirstResult()`和`setMaxResults()`方法,可以实现分页效果。例如: ```java Criteria ...
综上所述,"struts+hibernate分页"涉及到的主要是如何在Struts的控制层和Hibernate的数据层之间协调处理分页请求,以及在DAO层利用Hibernate的特性实现数据库查询的分页。理解并掌握这两个框架的分页机制,对于开发...
java 实现的一个简单的hibernate分页类 可以设置,从某一条开始取、显示的条数 不依赖struts spring
本教程将通过一个具体的“hibernate分页例子”来深入理解如何在Hibernate中实现分页功能。 在实际应用中,当数据量大到一定程度时,一次性加载所有数据会导致内存压力过大,影响系统性能。因此,分页查询成为一种...
本主题将探讨如何在Hibernate分页类和JDBC的SQL分页方法之间实现完美的融合,以提高性能并提供更好的用户体验。 首先,让我们了解一下Hibernate的分页功能。Hibernate提供了一种方便的方式来处理分页查询,通过...