首页 | IT新闻 | 硬件 | 操作系统 | 开发 | 网络编程 | 数据库 | 热门框架 | 网络安全 | 组网 | 建站指南 | 网页制作 | 特效 | 实用技巧 | 服务器 | 办公 | QQ | 探索 | 社区

  • 技术部落
  • 部落首页 > 热门框架 > Struts框架应用 > 正文
  • 我的struts分页算法的实现
      2007-2-26  来源:网络资源  编辑:Jsbulo  热度:

    说到分页算法,一般WEB开发都会用到,我只是在我的实现技术上用了struts框架,其实原理都一样的。看了网上相当多的分页算法,有对的也有好多是错的,更有好多是不太优化的。还有以前自己在augmentum做的一个分页算法,总结了一些不足。决定重新再写一个分页算法。

    首先,应该写个bean来记录存储一些页面的属性。

    分页大致需要如下属性:

    private int currentPage = 1; // 当前页

    private int totalPages = 0; // 总页数

    private int pageRecorders = 5;// 每页5条数据

    private int totalRows = 0; // 总数据数

    private int pageStartRow = 0;// 每页的起始数

    private int pageEndRow = 0; // 每页显示数据的终止数

    private boolean hasNextPage = false; // 是否有下一页

    private boolean hasPreviousPage = false; // 是否有前一页

    private int nextPage = 0;//下一页的页码

    private int previousPage = 0;//上一页的页码

    然后这些属性之间是有联系的,我们可以在构造函数的时候就初始化一些属性有两种方法:

    一、根据总的页数,(假设当前页为1)

    public PageBean(int totalRows){

    this.totalRows = totalRows;

    this.currentPage = 1;

    hasPreviousPage = false;

    if ((totalRows % pageRecorders) == 0) {

    totalPages = totalRows / pageRecorders;

    } else {

    totalPages = totalRows / pageRecorders + 1;

    }

    if (totalRows >= pageRecorders) {

    hasNextPage = true;

    nextPage = 2;

    this.pageEndRow = pageRecorders;

    } else {

    this.pageEndRow = totalRows;

    hasNextPage = false;

    nextPage = 1;

    }

    this.pageStartRow = 0; 

    previousPage = 1;

    }

    然后在按下一页或者上一页的时候需要如下函数处理:

    public void nextPage() {

    if(hasNextPage == true)

    currentPage = currentPage + 1;

    if ((currentPage - 1) > 0) {

    hasPreviousPage = true;

    } else {

    hasPreviousPage = false;

    }

    if (currentPage >= totalPages) {

    hasNextPage = false;

    this.nextPage = currentPage;

    } else {

    hasNextPage = true;

    nextPage = currentPage+1;

    }

    this.pageStartRow = (currentPage -1) * pageRecorders;

    if(hasNextPage == true)

    this.pageEndRow = pageStartRow + 5;

    else{

    this.pageEndRow =this.totalPages;

    }

    previousPage = currentPage - 1;

    }



    public void previousPage() {

    if(hasPreviousPage == true)

    currentPage = currentPage - 1;

    if (currentPage == 0) {

    currentPage = 1;

    }

    if (currentPage >= totalPages) {

    hasNextPage = false;

    } else {

    hasNextPage = true;

    }

    nextPage = currentPage + 1;

    if ((currentPage - 1) > 0) {

    hasPreviousPage = true;

    previousPage = currentPage - 1;

    } else {

    hasPreviousPage = false;

    previousPage = currentPage;

    }



    this.pageStartRow = (currentPage -1) * pageRecorders;

    if(hasNextPage == true)

    this.pageEndRow = pageStartRow + 5;

    else{

    this.pageEndRow =this.totalPages;

    }

    }

    在HTML中按下一页或者上一页的时候有如下代码:

    <logic:equal name="page" property="hasNextPage" value="true">

    <html:link page="/List.do?action=nextPage">

    nextPage

    </html:link>

    </logic:equal>

    <logic:equal name="page" property="hasPreviousPage" value="true">

    <html:link page="/List.do?action=previousPage">

    PreviousPage

    </html:link>

    </logic:equal>

    然后在Action中作如下处理: 

    String currentPage = request.getParameter("currentPage");

    HttpSession session = request.getSession();

    EmployeeForm employeeForm = (EmployeeForm) form;

    String queryString = null;

    String queryCon = null;

    String action = employeeForm.getAction();

    List list = new ArrayList();

    PageBean pb = null;

    EmployeeDao employeeDao = new EmployeeDao();

    if(action == null || action.equals("null")){

    int totalRows = employeeDao.getTotalRows();



    pb = new PageBean(totalRows);

    session.removeAttribute("page");

    queryString = employeeForm.getQueryString();

    queryCon = employeeForm.getQueryCon();

    session.setAttribute("queryString",queryString);

    session.setAttribute("queryCon",queryCon);  

    list = employeeDao.getAllEmployee(queryString, queryCon,

    String.valueOf(pb.getPageStartRow()),

    String.valueOf(pb.getPageRecorders()));



    }else if(action.equals("nextPage")){

    queryString = (String)session.getAttribute("queryString");

    queryCon = (String)session.getAttribute("queryCon");     

    employeeForm.setQueryString(queryString);

    employeeForm.setQueryCon(queryCon);

    pb = (PageBean)session.getAttribute("page");

    pb.nextPage();

    list = employeeDao.getAllEmployee(queryString, queryCon,

    String.valueOf(pb.getPageStartRow()),

    String.valueOf(pb.getPageRecorders()));

    }else if(action.equals("previousPage")){

    queryString = (String)session.getAttribute("queryString");

    queryCon = (String)session.getAttribute("queryCon");

    employeeForm.setQueryString(queryString);

    employeeForm.setQueryCon(queryCon);

    pb = (PageBean)session.getAttribute("page");  

    pb.previousPage();

    list = employeeDao.getAllEmployee(queryString, queryCon,

    String.valueOf(pb.getPageStartRow()),

    String.valueOf(pb.getPageRecorders()));

    }



    pb.description();

    session.setAttribute("page",pb);       

    request.setAttribute("admin", "admin");

    request.setAttribute("employee", list);

    return mapping.findForward("showlist");

    然后在数据库查询中有如下代码:

    /**

    *查询总记录数

    */

    public int getTotalRows() {

    int totalRows = 0;

    String sql = "select count(*) from employee";//假设是员工表

    Database db = new Database();

    ResultSet rs = db.executeQuery(sql);

    try {

    while (rs.next()) {

    String id = (String) rs.getString(1);

    totalRows = Integer.parseInt(id);

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }

    db.close();

    return totalRows;

    }



    /*

    *查询每一页需要查询的页码

    */

    public List getAllEmployee(String queryString, String queryCon,

    String startRow,String num) {

    List list = new ArrayList();

    String sql = null;

    if (queryString == null || queryString.equals("")) {

    sql = "select * from employee,dept " +

    "where dept.Id = employee.deptId " +

    "order by employee.id asc"+ " limit "+startRow+","+num;

    } else {

    sql = "select * from employee,dept " +

    "where dept.Id = employee.deptId order by employee."

    + queryString + " " + queryCon + " limit "+startRow+","+num;

    }

    Employee employee = null;

    Database db = new Database();

    ResultSet rs = db.executeQuery(sql);

    try {

    while (rs.next()) {

    String id = (String) rs.getString("employee.id");

    String name = (String) rs.getString("employee.name");

    String deptId = (String) rs.getString("employee.deptId");

    String deptName = (String) rs.getString("dept.deptName");

    employee = new Employee();

    employee.setId(id);

    employee.setName(name);

    employee.setDeptId(deptId);

    employee.setDeptName(deptName);

    list.add(employee);

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }

    db.close();

    return list;

    }

    这里我用了hibernate进行数据库操作,你也可以用jdbc进行操作,情况类似。

    二、根据总的页数,当前页

    这样的话构造函数应该写成:

    public PageBean(int totalRows,int currentPage) {

    this.totalRows = totalRows;

    this.currentPage = currentPage;

    if(currentPage < 2)

    hasPreviousPage = false;

    else

    hasPreviousPage = true;

    if ((totalRows % pageRecorders) == 0) {

    totalPages = totalRows / pageRecorders;

    } else {

    totalPages = totalRows / pageRecorders + 1;

    }

    if (currentPage < totalPages) {

    hasNextPage = true;

    nextPage = currentPage + 1;

    pageStartRow = (currentPage - 1)*pageRecorders;

    this.pageEndRow = pageStartRow + pageRecorders;

    } else if(currentPage == totalPages){

    pageStartRow = (currentPage - 1)*pageRecorders;

    this.pageEndRow = totalRows;

    hasNextPage = false;

    nextPage = currentPage;

    }

    if(currentPage < 2){

    previousPage = currentPage;

    hasPreviousPage = false;

    }else if(currentPage > 1){

    previousPage = currentPage-1;

    hasPreviousPage = true;

    }

    }

    在action中应该写成:

    if(currentPage == null){

    pb = new PageBean(totalRows);

    session.removeAttribute("page");

    queryString = employeeForm.getQueryString();

    queryCon = employeeForm.getQueryCon();

    session.setAttribute("queryString",queryString);

    session.setAttribute("queryCon",queryCon);  

    list = employeeDao.getAllEmployee(queryString, queryCon,

    String.valueOf(pb.getPageStartRow()),

    String.valueOf(pb.getPageRecorders()));

    }

    else{

    pb = new PageBean(totalRows,Integer.parseInt(currentPage));

    queryString = employeeForm.getQueryString();

    queryCon = employeeForm.getQueryCon();

    session.setAttribute("queryString",queryString);

    session.setAttribute("queryCon",queryCon);  

    list = employeeDao.getAllEmployee(queryString, queryCon,

    String.valueOf(pb.getPageStartRow()),

    String.valueOf(pb.getPageRecorders()));

    }

    session.setAttribute("page",pb);       

    request.setAttribute("admin", "admin");

    request.setAttribute("employee", list);

    return mapping.findForward("showlist");

    在jsp中应该写成:

    <logic:equal name="page" property="hasNextPage" value="true">

    <a href="List.do?currentPage=<bean:write name="page" property="nextPage"/>">

    nextPage

    </a>

    </logic:equal>

    <logic:equal name="page" property="hasPreviousPage" value="true">

    |

    <a href="/test/List.do?currentPage=<bean:write name="page" property="previousPage"/>">

    PreviousPage

    </a>

    </logic:equal>

    数据库查询部分依然适用。

    尽管洋洋洒洒贴了一部分代码,不过好像不太想看,包括我,也比较讨厌看一些烦琐的代码,所以如果你想要源代码进行探讨研究的话,欢迎随时找我。那就总结一下这两种方法吧!

    首先这两种方法都是取需要显示的数据显示,这样,在数据库庞大的情况下,比一次性把所有数据都取出来的效率要高。



    第一种方法是把PageBean存在了一个HttpSession中,在进入到显示列表的时候就进行了初始化,在jsp页面传递的参数action是固定的三个值:null,nextPage,previousPage.这样虽然比较容易理解,但是我发现一个BUG,就是如果你按刷新,他也会翻页,因为他的url就是 .do?aciton=nextPage,这样的话你传进去的action还是有一个值,这样就会导致翻页。



    第二种方法是考虑了第一种方法的BUG,在Jsp页面传递的参数currentPage的值是bean中的nextPage的值或者previousPage里的值,用了struts标签库嵌套,把值赋予currentPage,这样的话currentPage的值是:1,2,3,4...totalPages之间。这样的话你即使按刷新按钮,他也是当前页,因为他的url就是.do?currentPage=someNumber(someNumber是1到totalPages中的一个值)。但是这样的话Pagebean在每次访问的时候都要重新生成一个对象,该对象也是根据totalRows(总数据数),currentPage(当前页数)进行构造,从而设置其他的一些属性。个人比较推荐第二种方法。