分页查询
分页是系统中常用到的功能,只要涉及到查询必定伴随而来的就是分页,之前也学习过关于分页的内容,例如在牛腩的新闻发布系统,之前学习的大部分都是使用了假分页,这次学习java,使用Oracle数据库来实现一下真分页。
首先来说一下实现这个分页查询的流程:
一、封装分页信息:
需要分页的部分我们首先要做的是为分页封装一个分页实体,方便返回查询信息,封装如下:
- /**
- *封装分页信息
- * @author YoungJong
- *
- */
- public class PageModel<E> {
- //结果集
- private List<E> list;
- //查询记录数
- private int totalRecords;
- //每页多少条记录
- private int pageSize;
- //第几页
- private int pageNo;
- public List<E> getList() {
- return list;
- }
- public void setList(List<E> list) {
- this.list = list;
- }
- public int getTotalRecords() {
- return totalRecords;
- }
- public void setTotalRecords(int totalRecords) {
- this.totalRecords = totalRecords;
- }
- public int getPageSize() {
- return pageSize;
- }
- public void setPageSize(int pageSize) {
- this.pageSize = pageSize;
- }
- public int getPageNo() {
- return pageNo;
- }
- public void setPageNo(int pageNo) {
- this.pageNo = pageNo;
- }
- /**
- * 总页数
- * @return
- */
- public int getTotalPages(){
- return(totalRecords+pageSize-1)/pageSize;
- }
- /**
- * 取得首页
- * @return
- */
- public int getTopPageNo(){
- return 1;
- }
- /**
- * 上一页
- * @return
- */
- public int getPreviousPageNo(){
- if(pageNo<=1){
- return 1;
- }
- return pageNo-1;
- }
- /**
- * 下一页
- * @return
- */
- public int getNextPageNo() {
- if (pageNo >= getBottomPageNo()) {
- return getBottomPageNo();
- }
- return pageNo + 1;
- }
- /**
- * 取得尾页
- * @return
- */
- public int getBottomPageNo(){
- return getTotalPages();
- }
- }
这里的重点是这个实体使用了泛型,使用分页显示的数据并不全是同一种实体数据,为了更好的复用分页查询,将结果集定义成泛型,则便于众多信息的查询:
二、页面加载显示查询数据并分页显示(Servlet):
页面加载时调用一个Servlet,通过Servelt来调用分页查询并将查询结果返回到页面:我们先来看Servlet的代码实现:
- public class SearchItemServlet extends AbstractItemServlet {
- /**
- * 覆盖servlet的doGet方法
- */
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- // 定义显示第几页的变量
- int pageNo=0;
- //int pageSize=2;
- //从配置文件读取每页设置的显示数据数量
- int pageSize=Integer.parseInt(this.getServletContext().getInitParameter("page-size"));
- //获取jsp传递过来的显示第几页
- String pageNoString=req.getParameter("pageNo");
- //如果为空则显示第一页
- if(pageNoString==null){
- pageNo=1;
- }else{
- pageNo=Integer.parseInt(pageNoString);
- }
- //取得查询条件条件,条件为空则查询全部
- String condation=req.getParameter("clientIdOrName");
- //调用分页查询方法,返回查询数据
- PageModel pageModel=itemManager.findItemList(pageNo, pageSize, condation);
- ///取得查询页面传递过来的分页实体
- req.setAttribute("pageModel", pageModel);
- //将查询数据在页面显示
- req.getRequestDispatcher("/basedata/item_maint.jsp").forward(req, resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- // TODO Auto-generated method stub
- //super.doPost(req, resp);
- doGet(req,resp);
- }
- }
其中值得注意的是,关于每页显示数据条数的问题,这一部分可以自己写在代码里,也可以将显示的数目写在配置文件中,只需要读取配置文件即可,方便配置:
其中配置文件可以这样写:在WEB-INF下的web.xml中:
- <context-param>
- <param-name>page-size</param-name>
- <param-value>3</param-value>
- lt;/context-param>
这种写法是可以适用于系统中所有的Servlet的,每一个想读取页面显示数量的都可以进行读取。
三、Dao层实现分页查询:
Servlet调用查询方法是通过一个Manager的接口,类似于三层中B层的作用,由于没有复杂的逻辑,所以这里的代码很简单:
- /**
- * 查询物料信息,参数分别为:页码,每页显示数据,查询条件
- */
- public PageModel findItemList(int pageNo, int pageSize, String condation) {
- Connection conn=null;
- try{
- conn=DbUtil.getConnection();
- //调用Dao层的分页查询
- return itemDao.findItemList(conn, pageNo, pageSize, condation);
- }finally{
- DbUtil.close(conn);
- }
- }
真分页查询的重点在于DAO层的实现,下面我们来看一下代码:
- /**
- * 分页查询
- */
- public PageModel findItemList(Connection conn,int pageNo, int pageSize, String condation) {
- StringBuffer sbSql=new StringBuffer();
- sbSql.append("select * ")
- .append("from (")
- .append("select i.*, rownum rn from (")
- .append("select a.item_no, a.item_name, a.spec, a.pattern, a.item_category_id, ")
- .append("b.name as item_category_name, a.item_unit_id, c.name as item_unit_name, a.file_name ")
- .append("from t_items a, t_data_dict b, t_data_dict c ")
- .append("where a.item_category_id=b.id and a.item_unit_id=c.id ");
- if (condation != null && !"".equals(condation)) {
- sbSql.append(" and (a.item_no like '" + condation + "%' or a.item_name like '" + condation + "%') ");
- }
- sbSql.append(" order by a.item_no")
- .append(") i where rownum<=? ")
- .append(") ")
- .append("where rn >? ");
- System.out.println("sql=" + sbSql.toString());
- //通常采用日志组件记录,如log4j, 级别:info,debug,error...
- PreparedStatement pstmt = null;
- ResultSet rs = null;
- PageModel pageModel = null;
- try {
- //为查询条件参数赋值
- pstmt = conn.prepareStatement(sbSql.toString());
- //查询数据库中列在如何条件之间的数据
- pstmt.setInt(1, pageNo * pageSize);
- pstmt.setInt(2, (pageNo - 1) * pageSize);
- int i=pageNo*pageSize;
- int j=(pageNo - 1) * pageSize;
- rs = pstmt.executeQuery();
- //获得符合条件的信息结婚
- List itemList = new ArrayList();
- while (rs.next()) {
- Item item = new Item();
- item.setItemNo(rs.getString("item_no"));
- item.setItemName(rs.getString("item_name"));
- item.setSpec(rs.getString("spec"));
- item.setPattern(rs.getString("pattern"));
- //构造ItemCategory
- ItemCategory ic = new ItemCategory();
- ic.setId(rs.getString("item_category_id"));
- ic.setName(rs.getString("item_category_name"));
- item.setItemCategory(ic);
- //构造ItemUnit
- ItemUnit iu = new ItemUnit();
- iu.setId(rs.getString("item_unit_id"));
- iu.setName(rs.getString("item_unit_name"));
- item.setItemUnit(iu);
- item.setFileName(rs.getString("file_name"));
- itemList.add(item);
- }
- //为分页实体赋值
- pageModel = new PageModel();
- pageModel.setPageNo(pageNo);
- pageModel.setPageSize(pageSize);
- pageModel.setList(itemList);
- //根据条件取得记录数
- int totalRecords = getTotalRecords(conn, condation);
- pageModel.setTotalRecords(totalRecords);
- }catch(SQLException e) {
- e.printStackTrace();
- //记录到日志文件 error
- throw new ApplicationException("分页查询失败");
- }finally {
- DbUtil.close(rs);
- DbUtil.close(pstmt);
- }
- return pageModel;
- }
其实看起来复杂,做起来逻辑并不复杂,很容易实现
四、jsp页面显示
后台获得了数据,传递到页面,页面接收后就可以在页面上进行显示了,其实获得数据的代码一句话就可以搞定:更Servlet的代码是对应的,因为在Servlet中我们已经使用了setAttribute,所以jsp中的代码如下:
PageModel pageModel= (PageModel) request.getAttribute("pageModel");
点击跳到首页的方法如下(其他跳转类似不一一列出):
- //跳转到首页
- function topPage() {
- window.self.location="<%=basePath%>servlet/item/SearchItemServlet?pageNo=<%=pageModel.getTopPageNo()%>&clientIdOrName=<%=clientIdOrName%>";
- }
这是一个完整的分页查询的流程,很多都是封装好的可以复用,只是在DAO层的查询语句需要自己写,不过最近了解了一些NHiernate,关于Hibernate的知识也在学习中,自己要写sql语句的问题也是可以解决的!

浙公网安备 33010602011771号