今天闲来无事,写了个ssh+ajax分页的demo,还有很多不成熟的地方,大家凑合看吧。 这个demo的框架采用现在很流行的ssh,在分页功能上采用了ajax技术。
框架版本:
Struts:2.0.14
Hibernate:3.3.1
Spring:2.5.6
ajax分页用到了jQuery类库
数据库使用的是MySql 5.0
相信大家对这些都是耳熟能详的了,我也就不在一一做介绍了,如果大家有不明白的地方,自己google一下了。废话不多说,动手干吧,不然就有人捡砖头了。哈哈!
一、准备
1. 项目所需的jar包(struts2,hibernate,spring),不多说了,从官网上都可以下载。截图如下:
2. 数据库,脚本如下:
create database if not exists dbtest; use dbtest; /*数据表 `classify` 的表结构*/ drop table if exists classify; create table classify ( cid int(20) not null auto_increment, classname varchar(50) default null, primary key(cid) ) ENGINE=InnoDB DEFAULT CHARSET=gb2312; /*写个存储过程来初始化数据表数据,很简单*/ DELIMITER $$; DROP PROCEDURE IF EXISTS `dbtest`.`init`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `init`() BEGIN declare v int; set v=0; while v<50 do insert into classify(classname) values('Hi,This is a test'); set v=v+1; end while; END$$ DELIMITER ;$$ /*调用存储过程*/ call init();
3. 打开你的myeclipse,新建一个web项目,添加相应的jar包、配置文件(如applicationContext.xml、struts.xml、hibernate.cfg.xml等),当然还要修改web.xml文件了,这些文件的编写就不一一表述了,因为google一下多的是。
二、编写
1. 先看看整个项目的结构吧,也很简单,相信大家一看便知了。
很简单吧,从dao到action,相信大家都很熟悉了。大家别嫌我懒啊,一会儿会把整个项目的源文件上传,大家自己看源码吧,里面我也有写注释的。
这里主要说说ajax分页吧,我这里用到的是一个我从网上找的基于jQuery的分页组件,然后跟据自己的需求,稍加改动。jQuery的.post方法还是挺好用的,我就是这个方法来实现ajax分页的。
var url = "pagelist.action?page=" + page; $.post( url, function(data){ //alert(data); var items = data.selectNodes("//classify"); var result = "<table id='mytable' width='100%' border='1' cellpadding='0' cellspacing='0'>"; for (var i = 0; i < items.length; i++) { var classify = items[i]; result += "<tr>"; result += "<td width='15%'>"; result += "<input type='checkbox' name='toDelete' value='"; result += classify.getElementsByTagName("cid")[0].firstChild.nodeValue; result += "' />"; result += "</td>"; result += "<td width='20%'>" + classify.getElementsByTagName("cid")[0].firstChild.nodeValue + "</td>"; result += "<td>"; result += "<a href='/SSHTEST/classify/edit.action?cid="; result += classify.getElementsByTagName("cid")[0].firstChild.nodeValue; result += "'>"; result += classify.getElementsByTagName("classname")[0].firstChild.nodeValue; result += "</a>"; result += "</td>"; result += "</tr>"; } result += "</table>"; $("#mainlist").html(""); $("#mainlist").html(result); } );
这段js代码就是使用post方法来获得包含数据的xml文件,并解析这个xml文件,拼写成一段html代码,然后将这段html代码填充到名为“mainlist”的div中。
而最基本的分页实际是采用的hibernate的分页,dao中的分页方法如下,同样也很简单
/** * 分页查询 * @param hql 查询的条件 * @param offset 开始记录 * @param pageSize 一次查询几条记录 * @return list集合 */ public List<T> queryForPage(String hql, int offSet, int pageSize) { Query query = getSession().createQuery(hql); query.setFirstResult(offSet); query.setMaxResults(pageSize); return query.list(); }
这里还用到了一个保存分页信息的类PageBean,如下:
import java.util.List; public class PageBean { private List list; // 要返回的某一页的记录列表 private int currentPage; // 当前页 private int allRow; // 总记录数 private int totalPage; // 总页数 public List getList() { return list; } public void setList(List list) { this.list = list; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getAllRow() { return allRow; } public void setAllRow(int allRow) { this.allRow = allRow; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } /** * 计算当前页,若为0或者请求的URL中没有"?page=",则用1代替 * * @param page * 传入的参数(可能为空,即0,则返回1) * @return 当前页 */ public static int countCurrentPage(int page) { final int curPage = (page == 0 ? 1 : page); return curPage; } /** * 计算当前页开始记录 * * @param pageSize * 每页记录数 * @param currentPage * 当前第几页 * @return 当前页开始记录号 */ public static int countOffset(int pageSize, int currentPage) { final int offset = pageSize * (currentPage - 1); return offset; } /** * 计算总页数,静态方法,供外部直接通过类名调用 * * @param pageSize * 每页记录数 * @param allRow * 总记录数 * @return 总页数 */ public static int countTotalPage(int pageSize, int allRow) { int totalPage = allRow % pageSize == 0 ? allRow / pageSize : allRow / pageSize + 1; return totalPage; } }
此外还有一个用来处理分页操作并返回PageBean对象的工具类,如下:
import java.util.List; import com.sshtest.genericdao.IGenericDAO; public class PageCommand { public static PageBean queryForPage(IGenericDAO<?, ?> dao, String hql, int page, int pageSize) { int allRow = dao.getAllRowCount(hql); // 总记录数 int totalPage = PageBean.countTotalPage(pageSize, allRow); // 总页数 int currentPage = PageBean.countCurrentPage(page); // 计算当前页 int offSet = PageBean.countOffset(pageSize, currentPage); // 当前页开始记录 List list = dao.queryForPage(hql, offSet, pageSize); // "一页"的记录 if (list.size() == 0) { // 如果是最后一页,显示上页内容 if (currentPage > totalPage) { currentPage = totalPage; offSet = PageBean.countOffset(pageSize, currentPage); list = dao.queryForPage(hql, offSet, pageSize); } } // 把分页信息保存到Bean中 PageBean pageBean = new PageBean(); pageBean.setAllRow(allRow); pageBean.setCurrentPage(currentPage); pageBean.setList(list); return pageBean; } }
下面再来看看action吧,在action中处理分页的对应方法如下:
...... // ajax分页 public String doListClassify() throws Exception { PageBean pageBean = classifyBiz.queryForPage(getPage(), 10); String msg = parasToXML(pageBean.getList()); System.out.println(msg); HttpServletResponse response = ServletActionContext.getResponse(); response.setContentType("text/xml"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); out.print(msg); out.flush(); out.close(); return SUCCESS; } @SuppressWarnings("unchecked") private String parasToXML(List list) { StringBuffer bf = new StringBuffer(); bf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); bf.append("<items>"); for (Iterator it = list.iterator(); it.hasNext();) { Classify classify = (Classify) it.next(); bf.append("<classify>"); bf.append("<cid>" + classify.getCid() + "</cid>"); bf.append("<classname>" + classify.getClassname() + "</classname>"); bf.append("</classify>"); } bf.append("</items>"); return bf.toString(); } ......
至于struts.xml的编写,spring的配置等我就不一一详述了,因为附件里都有。
三、测试
终于到测试了,把项目部署到tomcat中,启动服务,打开浏览器,输入相应的地址,运行效果如下:
总结:当然由于篇幅限制,不可能全都说到,不过相信大家水平都很高,不难看懂的。而且本人水平有限,有不对的地方还希望大家能及时的指出,最后将项目代码上传,详细的大家可以看代码了。