Struts1.2实现MySQL数据库分页

  应一位朋友的要求。今晚也是我的周末,所以做了个分页。虽然网上相似文章比较多,不过我做分页的时候,看网上的文章也难做得出来。第一次写博客,希望看了我这篇《Struts1.2实现MySQL数据库分页》的还不能做出一个分页的朋友拍我砖头。没办法,文章写作太差了。
   我的平台是:Eclipse3.2    MyEclipse5.5 Tomcat5.5 MySql5.0
 
    第一步:创建数据库:
   这没什么难的,用下面的脚本就OK了。
CREATE DATABASE page ;
use page ;
CREATE TABLE `product` (
 `id` varchar (11) NOT NULL ,
 `sortid` varchar (11) NOT NULL ,
 ` name ` varchar (50) NOT NULL ,
 `price` double NOT NULL ,
 `saleprice` double NOT NULL ,
 `descript` text NOT NULL ,
 `contents` text NOT NULL ,
  `saledate` varchar (255) NOT NULL ,
 `salecount` int (11) default NULL ,
 `image` text,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
第二步:创建一个项目
创建一个项目 , 项目名为 ”strutsPage”, 导入 Struts1.2 Struts 的包采用默认,引用 MySql 的驱动,要是没有驱动的话,请到 http://download.csdn.net/source/400716 这下载。
下面设置 web.xml struts-config.xml 配置文件,我觉得直接 COPY 我的就好了。
web.xml :文件里的内容如下,直接换上就 OK 了。基本是默认的。
<? xml version = "1.0" encoding = "UTF-8" ?>
< web-app xmlns = "http://java.sun.com/xml/ns/j2ee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" version = "2.4" xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
  < servlet >
    < servlet-name > action </ servlet-name >
    < servlet-class > org.apache.struts.action.ActionServlet </ servlet-class >
    < init-param >
      < param-name > config </ param-name >
      < param-value > /WEB-INF/struts-config.xml </ param-value >
    </ init-param >
    < init-param >
      < param-name > debug </ param-name >
      < param-value > 3 </ param-value >
    </ init-param >
    < init-param >
      < param-name > detail </ param-name >
      < param-value > 3 </ param-value >
    </ init-param >
    < load-on-startup > 0 </ load-on-startup >
  </ servlet >
  < servlet-mapping >
    < servlet-name > action </ servlet-name >
    < url-pattern > *.do </ url-pattern >
  </ servlet-mapping >
  < welcome-file-list >
    < welcome-file > index.jsp </ welcome-file >
  </ welcome-file-list >
</ web-app >
 
 
struts-config.xml 的内容如下:
<? xml version = "1.0" encoding = "UTF-8" ?>
<! DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd" >
 
< struts-config >
  < data-sources />
  < form-beans />
  < global-exceptions />
  < global-forwards />
  < action-mappings >
   < action
      attribute = "productShowForm"
      input = "/index.jsp"
      name = "productShowForm"
      path = "/productShow"
      scope = "request"
      type = "com.yourcompany.struts.action.ProductShowAction" >
      < forward name = "success" path = "/index.jsp" />
    </ action >
  </ action-mappings >
  < message-resources parameter = "com.yourcompany.struts.ApplicationResources" />
</ struts-config >
 
第三步:创建包和数据库连接
SRC 下创建 dao , dbtool, vo,factory 四个包
dbtool 包里主要放访问 JDBC 数据库的连接类等。下面提供我用的 JavaBean 类。
 
DBConnection.java 的内容如下:
package com.yourcompany.dbtool;
 
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
 
/**
 * 这是一个连接数据的单模式
 * @author 树下无影
 *
 */
public class DBConnection {
      private static DBConnection instance;
     
      private String driver;
      private String url;
      private String user;
      private String password;
     
      private DBConnection() throws Exception{
       
       InputStream in=getClass().getClassLoader().getResourceAsStream(
               "com/yourcompany/dbtool/database.properties");
       Properties prop=new Properties();
       prop.load(in);
       driver=prop.getProperty("driver");
       url=prop.getProperty("url");
       user=prop.getProperty("user");
       password=prop.getProperty("password");
       try{
           Class.forName(driver);
       }catch(Exception e)
       {
           System.out.println(" 数据库初始化出错 ");
             throw e;
       }
       System.out.println(driver+" "+url+" "+user+" "+password);
      }
      public static DBConnection getInstance(){
       try{
           if(instance==null){
               instance=new DBConnection();
           }
           return instance;
       }catch(Exception e){
           System.out.println(" 实例化单模子出错 ");
          
           return null;
       }
      }
     
      public Connection getConnection()throws SQLException{
       Connection con;
       try{
           con=DriverManager.getConnection(url, user, password);
           
       }catch(SQLException e){
          System.out.println("Connection 连接出错 ");
            throw e;
       }
       return con;
      }
     
      public void closeConnection(Connection con){
     
       if(con!=null){
           try{
               con.close();
           }catch(SQLException e)
           {
               System.out.println(" 关闭 Connection 连接出错 ");
            
           }
           
       }
      }
}
 
这里用一个配置文件, database.properties 里面存放数据库的 URL Driver Username Password 等,修改成你本机的相应数据,能打开数据库就好。
database.properties 内容如下:
driver=org.gjt.mm.mysql.Driver
url=jdbc:mysql://localhost:3306/page
user=root
password=1234
 
下面是我用的数据库增删改查的 Bean-> DBbusiness.java
 
package com.yourcompany.dbtool;
 
import java.sql.*;
 
/**
 * 这是一个连接数据库具有增删改查的 Bean
 * @author 树下无影
 *
 */
public class DBbusiness {
/*
 * 定义连接参数等
 */
Connection conn = null;
 
PreparedStatement psps = null;
 
ResultSet rs = null;
public DBbusiness (){
    
}
/*
 * 定义公用的 Connection
 */
public Connection getConn() {
 
     try {
        DBConnection db=DBConnection.getInstance();
        Connection conx = db.getConnection();
        return conx;
     } catch (Exception e) {
         System.out.println("Connection 连接出错 ");
        
     }
     return null;
 
}
/*
 * 获取数据 ( 查询 ) 方法
 */
public ResultSet getData(String sql) {
     try {
 
        conn = getConn();
        psps = conn.prepareStatement(sql);
        rs = psps.executeQuery();
     } catch (Exception e) {
         System.out.println(" 查询数据库操作出错 ");
     }
     return rs;
    
    
}
    /*
     * 定义插入数据和更新的方法
     */
public boolean insert(String sql) {
     try {
        conn = getConn();
        psps = conn.prepareStatement(sql);
        psps.executeUpdate();
        return true;
     } catch (Exception e) {
         System.out.println(" 数据库更新出错 ");
      
     }
     return false;
 
}
/*
 * 定义创建数据库和表的方法
 */
public boolean create(String sql) {
     try {
        conn = getConn();
        psps = conn.prepareStatement(sql);
        psps.execute();
        return true;
     } catch (Exception e) {
 
     }
     return false;
 
}
 
/*
 * 定义关闭连接的方法
 */
public void allClose() {
     try {
       if (rs != null)
            rs.close();
        if (psps != null)
            psps.close();
        if (conn != null)
        {
            DBConnection db=DBConnection.getInstance();
            db.closeConnection(conn);
        }
     } catch (Exception e) {
         System.out.println(" 数据库关闭操作出错 ");
           
    }
}
 
}
第四步:创建实体类
vo 包里,创建一个实体类,这步 COPY 过去就是。
Product.java
package com.yourcompany.vo;
 
public class Product {
String id;
String sortid;
String name;
String price;
String saleprice;
String descript;
String contents;
String saledate;
String salecount;
String image;
public Product(){}
    public Product(String id,String sortid,String name,String price,
         String saleprice,String descript,String contents,
         String saledate,String salecount,String image){
     this.id=id;
     this.sortid=sortid;
     this.name=name;
     this.price=price;
     this.saleprice=saleprice;
     this.descript=descript;
     this.contents=contents;
     this.saledate=saledate;
     this.salecount=salecount;
     this.image=image;
     
    }
public String getContents() {
     return contents;
}
 
public void setContents(String contents) {
     this.contents = contents;
}
 
public String getDescript() {
     return descript;
}
 
public void setDescript(String descript) {
     this.descript = descript;
}
 
public String getId() {
     return id;
}
 
public void setId(String id) {
     this.id = id;
}
 
public String getImage() {
     return image;
}
 
public void setImage(String image) {
     this.image = image;
}
 
public String getName() {
     return name;
}
 
public void setName(String name) {
     this.name = name;
}
 
public String getPrice() {
     return price;
}
 
public void setPrice(String price) {
     this.price = price;
}
 
public String getSalecount() {
     return salecount;
}
 
public void setSalecount(String salecount) {
     this.salecount = salecount;
}
 
public String getSaledate() {
     return saledate;
}
 
public void setSaledate(String saledate) {
     this.saledate = saledate;
}
 
public String getSaleprice() {
     return saleprice;
}
 
public void setSaleprice(String saleprice) {
     this.saleprice = saleprice;
}
 
public String getSortid() {
     return sortid;
}
 
public void setSortid(String sortid) {
     this.sortid = sortid;
}
 
}
 
第五步:创建接口,并创建相应的实现类
PageDao.java 接口里有两个方法 , 第一个方法是读取指定数据表的行数;第二个方法是读取数据表,并把信息放入一个 ArrayList 返回。看代码
package com.yourcompany.dao;
 
import java.util.ArrayList;
import java.util.List;
 
 
 
public interface PageDao {
    public int getCount(String counSql);
    public ArrayList getProduct(String sql);
 
}
创建接口好后,当然要创建实现类,
如下: PageDaoImpl.java
 
package com.yourcompany.dao;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
 
 
import com.yourcompany.dbtool.DBbusiness;
import com.yourcompany.vo.Product;
 
 
/**
 * 这是接口的实现类
 * @author 树下无影
 *
 */
 
 
public class PageDaoImpl implements PageDao {
    /*
     * 获取数据行数
     * @see com.yourcompany.dao.PageDao#getCount(java.lang.String)
     */
 public int getCount(String counSql){
      int result=0;
      DBbusiness db=new DBbusiness();
      ResultSet rs= db.getData(counSql);
      try {
             rs.next();
             result=rs.getInt(1);
        /*while(rs.next()){
            result=rs.getInt(1);
         }*/
     } catch (SQLException e) {
        // TODO Auto-generated catch block
        System.out.println(" 读取数据总数失败 ");
     }finally{
        db.allClose();
     }
      return result;
 }
 /*
 * 读取数据表
 */
 public ArrayList getProduct(String sql){
        ArrayList arrayList=new ArrayList();
       
        DBbusiness db=new DBbusiness();
        ResultSet rs=db.getData(sql);
        try {
       
            while(rs.next()){
              
               String id=rs.getString(1);
               String sortid=rs.getString(2);
               String name=rs.getString(3);
               String price=rs.getString(4);
               String saleprice=rs.getString(5);
               String descript=rs.getString(6);
               String contents=rs.getString(7);
               String saledate=rs.getString(8);
               String salecount=rs.getString(9);
               String image=rs.getString(10);
               Product productForm=new Product( id,sortid ,name, price,
                     saleprice ,descript, contents,
                     saledate,salecount,image);
               arrayList.add(productForm);
            }
           
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            System.out.println(" 数据库读取出错 ");
        }finally{
            db.allClose();
        }
        return arrayList;
     }
 
}
 
第六步:创建映射的工厂类:
这个类没什么解释,放在 factoyr 的包里
PageDaoFactory.java
 
package com.yourcompany.factory;
 
import com.yourcompany.dao.PageDao;
import com.yourcompany.dao.PageDaoImpl;
 
public class PageDaoFactory {
    public static PageDao getPageDaoIntanse(){
     return new PageDaoImpl();
    }
}
第七步:分页处理类
呵呵,这么多步骤了还没进入正题,下面就开始讲和分页相关的。
dbtool 包里创建如下类:
PageBean.java
package com.yourcompany.dbtool;
 
import com.yourcompany.factory.PageDaoFactory;
 
 
public class PageBean {
/**
 * 这是一个分页的类,因为 MySQL 数据库检索可以使用分页的 SQL 指令
 * 所在在这里主要是处理出这样的指令
 * 并获得相应的页数信息
 *MySql 语句如下 :select * from test limit 10; 这句是从 1 10 的信息条数
 *select * from test limit 10,5;   这句是第十条以后的五条
 */
int curr; // 当前页
 
int count; // 总页数
 
int size; // 每页显示数据数
 
int rows=0; // 数据的所有行数
   
boolean last; // 是否是最后一页
/**
 * 构造器
 * @param counSql
 */
public PageBean(String counSql) {
     if (this.rows == 0) {// 获取所有的数据条数
        this.rows = PageDaoFactory.getPageDaoIntanse().getCount(counSql);
     }
     this.curr=getCurr();
     this.size = 5;// 设定页面显示数据大小
     this.count = (int) Math.ceil((double) this.rows / this.size);// 获得页数
     this.last=isLast();
}
    public PageBean(String counSql,int size){
     if (this.rows == 0) {// 获取所有的数据条数
        this.rows = PageDaoFactory.getPageDaoIntanse().getCount(counSql);
     }
     this.curr=getCurr();
     this.size = size;// 设定页面显示数据大小
     this.count = (int) Math.ceil((double) this.rows / this.size);
     this.last=isLast();
    }
    public PageBean(String counSql,int curr,int size){
     if (this.rows == 0) {// 获取所有的数据条数
        this.rows = PageDaoFactory.getPageDaoIntanse().getCount(counSql);
     }
     this.curr=curr;
     this.size = size;// 设定页面显示数据大小
     this.count = (int) Math.ceil((double) this.rows / this.size);
     this.last=isLast();
    }
/**
 * 页面指令处理及返回相应的查询 SQL 语句
 */
public String pageDeal(String pageDo, String sql) {
     String str = " limit ";
     // 首页
     if (pageDo.equals("first")) {
        setCurr(1);
        str += "" + getSize();
     }
     // 尾页
     if (pageDo.equals("end")) {
        setCurr(getCount());
        str += "" + ((getCount() - 1) * getSize());
        str += "," + (getRows() - (getCount() - 1) * getSize());
     }
     // 下一页
     if (pageDo.equals("next")) {
       
        if(getCurr()<getCount()){
            str += "" + (getCurr() * getSize());
            str += "," + getSize();
            setCurr(getCurr() + 1);
        }else{
            setCurr(getCount());
            str += "" + ((getCount() - 1) * getSize());
            str += "," + (getRows() - (getCount() - 1) * getSize());
        }
       
     }
    // 上一页
     if (pageDo.equals("prv")) {
        setCurr(getCurr() - 1);
        str += "" + (getCurr() * getSize() - getSize());
        str += "," + getSize();
       
     }
     return sql + str;
}
 
 
public static void main(String[] args) {
 
}
 
// 返回总页数,总页最小也等于 1
public int getCount() {
     return (count == 0) ? 1 : count;
}
 
// 设置总页数
public void setCount(int count) {
     this.count = count;
}
 
// 返回当前页 , 当前页最小也等于 1
public int getCurr() {
     return (curr == 0) ? 1 : curr;
}
    // 设置当前页
public void setCurr(int curr) {
     this.curr = curr;
}
 
public int getRows() {
     return rows;
}
 
public void setRows(int rows) {
     this.rows = rows;
}
 
public int getSize() {
     return size;
}
 
public void setSize(int size) {
     this.size = size;
}
/**
 * 如果是最后一页的返回 true
 * @return
 */
public boolean isLast() {
     return (curr==count)?true:false;
}
public void setLast(boolean last) {
     this.last = last;
}
 
 
}
 
这个类写了很多的注释,不过还是要讲解一下。由于在 Struts Action 里用到第三个构造器,那就先讲这个吧。构造器里主要的功能是,通过 Factory 映射的接口类调用读取数据表的行数,获得表的所有行数。然后和传进来的页面显示信息数除一下,就获得页数的总数了。
   当前页的定义,要是第一次读取,当前页当然是第一页了,要是点了下一页,当前页就加一页,点上一页,当前页就减一面,嘿嘿。我这里主要由页面传当前页进来,再根据传进来的动作进行处理当前页。所以“下一页”这样的动作除了要传一个动作外还要传当时的当前页。
Action 里通过调用 pageDeal (“”,“”)这方法就就可以获取相应的分页处理了,当然还要加上 ”select * from table” 这样的语句才能实现。
好了,看下一步 Action 里是怎样处理的。
 
第八步: Action 的处理:
struts.action 的包里创建如下类:
package com.yourcompany.struts.action;
 
import java.util.ArrayList;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
 
import com.yourcompany.dbtool.PageBean;
import com.yourcompany.factory.PageDaoFactory;
import com.yourcompany.vo.Product;
 
 
 
public class ProductShowAction extends Action {
 
    public ActionForward execute(ActionMapping mapping, ActionForm form,
           HttpServletRequest request, HttpServletResponse response) {
 
       ArrayList aList = new ArrayList();
 
       /*
        * 定义页面传过来的动作,如点 " 下一页 " 并因为这动作而决定处理
        */
       String pageDo = request.getParameter("pageDo");
      
      
   
           /*
            * 定义获取页面传过来的当前页 getCurr
            */
           int getCurr;
           String curr_page = request.getParameter("curr_page");
           if (curr_page == null || curr_page.equals("")) {
              getCurr = 1;
           } else {
              getCurr = Integer.parseInt(request.getParameter("curr_page"));
              System.out.println(getCurr);
           }
           /*
            * 实例化 PageBean 对象
            * PageBean 有几个构造器,不过都要传送一句获取数据库行数的 SQL 语句
            * getCurr 是传送一个当前页给 PageBean 的构造器,
            * 2 是定义每页显示几行数据
            */
           PageBean pb = new PageBean("select count(*) from product", getCurr,
                  2);
           // 定义查询数据库的 SQL 语句,格式如下
           String sql;
           sql = pb.pageDeal(pageDo, "select * from product ");
           // 定义 ArrayList 获取数据库所查询得到的数据
 
           aList = PageDaoFactory.getPageDaoIntanse().getProduct(sql);
           // 把值传给客户端
           request.setAttribute("pageInfo", pb);
           request.setAttribute("data", aList);
 
           return mapping.findForward("success");
       }
}
 
  这个 Action 里也写了好多的注释,相信一看就明白。
步骤主要是: 1. 定义两个参数,获取前台传进来的动作和当前页
            2. 实例化分页的处理类, PageBean.java 。在它的构造器里传进查询数据库行数的 SQL 语句、当前页、要在表里显示的规格。
            3. 获取处理好的分页 SQL 语句,主要是调用 PageBean 里的 pageDeal 方法。给它传进的是页面传进来的动作和查询数据表的 SQL 语句。
            4. 用处理好的分布 SQL 语句去查询数据。
            5. 把值传给前台。主要返回 PageBean 的对象和所查询得的数据 ArrayList
 
第九步: 前台处理页面。
   由于后台传回来的是一个 ArrayList 的数据表,所以把它读出来就是。
  还返回一个 PageBean 的对象,这里包含的数据是当前页、总页、是否为最后一页。
   所以要是想弄不同的“上一页”、“下一页”这样的导航条的话,修改传回的参数,再在 Jsp 页面里做相应的处理就 OK 了。
看我的 Jsp 页面: index.jsp
 
<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>
<% if(session.getAttribute("getData")==null)
             {// 这里只是一个跳转,没什么
             session.setAttribute("getData","ok");
             response.setHeader("refresh",
                     "1;url=/strutsPage/productShow.do?pageDo=first&curr_page=1");
             }
 %>
<html>
             <head>
              <title>JSP for ProductShowForm form</title>
             </head>
             <body><font color="#0000ff">
                这里仅演示分页,操作部分已经做到获取 ID 了,相信直接调用就可以弄修改和删除 </font>
              <table width="80%" border="1">
                  <tr>
                     <th>
                         商品名称
                     </th>
                     <th>
                         价格
                     </th>
                     <th>
                         商品描述
                     </th>
                     <th>
                         商品详细信息
                     </th>
                     <th >
                         上架日期
                     </th>
                     <th colspan="2" align="center">
                         操作
                     </th>
                  </tr>
 
                  <logic:present name="data" scope="request">
                     <logic:iterate id="show" name="data"
                         type="com.yourcompany.vo.Product">
                         <tr>
                            <td>
                                <bean:write name="show" property="name" />
                            </td>
                            <td>
                                <bean:write name="show" property="saleprice" />
                            </td>
                            <td>
                                <bean:write name="show" property="descript" />
                            </td>
                            <%--<td>
                                <bean:write name="show" property="contents" />
                            </td>
                            --%><td >
                                <bean:write name="show" property="saledate" />
                            </td>
                            <td>
                             <html:link action="/productShow.do?pageDo=updata"
                    paramId="up_page" paramName="show" paramProperty="id">
                           修改 </html:link>
                            </td>
                            <td>
                             <html:link action="/productShow.do?pageDo=dele"
                    paramId="dele_page" paramName="show" paramProperty="id">
                           删除 </html:link>
                            </td>
                         </tr>
                     </logic:iterate>
                  </logic:present>
              </table>
              <logic:present name="pageInfo">
                      <bean:write name="pageInfo" property="curr" /> /
                 <bean:write name="pageInfo" property="count" /> .
                    <html:link action="/productShow.do?pageDo=first"
                    paramId="curr_page" paramName="pageInfo" paramProperty="curr">
                       首页 </html:link>
                  <logic:notEqual name="pageInfo" property="curr" value="1">
                         <html:link action="/productShow.do?pageDo=prv"
                         paramId="curr_page" paramName="pageInfo" paramProperty="curr">
                         上一页 </html:link>
                      </logic:notEqual>
                      <logic:equal name="pageInfo" property="last" value="false">
                         <html:link action="/productShow.do?pageDo=next"
                         paramId="curr_page" paramName="pageInfo" paramProperty="curr">
                         下一页 </html:link>
                     </logic:equal>
                    <html:link action="/productShow.do?pageDo=end"
                    paramId="curr_page" paramName="pageInfo" paramProperty="curr">
                    尾页 </html:link>
                
          </logic:present>
         
             </body>
</html>
 
 
总结:
   这个分页看起来很简单,做起来也很简单。只是对 SQL 语句做了一下过滤而已。这个分页功能很简单,但重在抛砖引玉!!
      想要源代码的朋友和我联系。
                                                                                                      作者:树下无影
                                                                                                            2008-04-27
注:转载要经本人同意!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值