我的平台是:Eclipse3.2 MyEclipse5.5 Tomcat5.5 MySql5.0
第一步:创建数据库:
这没什么难的,用下面的脚本就OK了。
CREATE DATABASE page;use page;CREATETABLE `product` (`id` varchar(11) NOTNULL,`sortid` varchar(11) NOTNULL,`name` varchar(50) NOTNULL,`price` doubleNOTNULL,`saleprice` doubleNOTNULL,`descript` text NOTNULL,`contents` text NOTNULL,`saledate` varchar(255) NOTNULL,`salecount` int(11) defaultNULL,`image` text,PRIMARYKEY (`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了。基本是默认的。
action org.apache.struts.action.ActionServlet config /WEB-INF/struts-config.xml debug 3 detail 3 0 action *.do index.jsp
struts-config.xml的内容如下:
attribute="productShowForm" input="/index.jsp" name="productShowForm" path="/productShow" scope="request" type="com.yourcompany.struts.action.ProductShowAction">
第三步:创建包和数据库连接
在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
修改 删除 第页/共 页. 首页 上一页 下一页 尾页
总结:
这个分页看起来很简单,做起来也很简单。只是对SQL语句做了一下过滤而已。这个分页功能很简单,但重在抛砖引玉!
自己选择的路,跪着也要把它走完。