这里要实现分页,我们的思路是从后台开始,先从数据库获取数据开始,那么首先我们要准备SQL语句select code,name,layer from area;这里我们查出了所有的数据
通过select count(1) from area;查出所有的数据,发现在area表里面一共有742717条数据,如果我们每页显示10条数据,那么就需要查出前十条数据
这里如果获取到前十条的数据,那么就需要借助到伪列rownum来实现
select rownum , code,name,layer from area where rownum<=10;
这个就是需要我们在第一页显示的数据
那么第二页rownum 就是从11-20
select rownum,code,name,layer from area where rownum>=11 and rownum<=20;
但是由于rownum只有<=或者<的属性,所以这里我们对rownum进行重命名
select r,code,name,layer
from (select rownum as r,code,name,layer from area) t
where r>=11 and r<=20;
那么第二页的数据就查出来了
接下来就是查找第三页的数据,rownum需要从21-30
select r,code,name,layer
from (select rownum as r,code,name,layer from area) t
where r>=21 and r<=30;
从这里开始我们就已经可以发现规律了,这里的SQL语句变成动态的语句
对于rownum的下限是(当前的页数-1)*10 +1 ,然后对于rownum的上限是当前页数*10
select r,code,name,layer
from (select rownum as r,code,name,layer from area) t
where r>=(curPage-1)*10+1 and r<=curPage*10;
这里我们把每页显示的条数也作为一个变量pageSize
select r,code,name,layer
from (select rownum as r,code,name,layer from area) t
where r>=(curPage-1)*pageSize+1 and r<=curPage*pageSize;
那么现在我们后台的SQL语句就已经拿到了
现在接下来就是连接数据库进行数据库的操作了
首先建立一个util的包连接数据库
建立一个数据库连接的配置文件jdbc.properties,添加驱动名称driver,数据库的连接地址,数据库名字,密码
添加驱动之前还需要添加Oracle下面的jdbc下面的jar包,由于这里是一个web项目,所以我们将所有的资源包都先加载在WEB-INF下面的lib,然后eclipse会自动添加web app libraries里面,所以我们就不用再通过buildpath来加载jar包了
一定注意再properties里面的参数都没有引号,也没有分号,尽量不要打空格,否则容易出错
写好了配置文件之后接下来就是连接数据了util
这里连接数据库我们采用数据源C3P0来进行连接,C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。所以我们还需要添加一个C3P0的配置文件
C3P0-config.xml
<default-config>
<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
<property name="jdbcUrl">jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="user">scott</property>
<property name="password">tiger</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">60</property>
<property name="maxPoolSize">20</property>
<property name="minPoolSize">5</property>
</default-config>
这里再C3P0里面的默认配置会直接设置连接的数据库的信息,包括需要加载的驱动,数据库连接地址,user,pwd。所以我们就不再需要建立刚才的jdbc.properties来配置数据库的连接信息了
使用C3P0来配置数据连接的配置信息的好处是可以自己设置数据的最大连接数,以及新增连接数等,以及空闲时间的等待时间。以及初始化的连接数等等。
这样就不会浪费数据库的资源。
下面我们建立一个JDBCUtils来获取连接
由于C3P0里面内置了加载驱动的函数,所以这里我们不用再通过resourcebundle来加载驱动了,而是直接在datasource里面拿到连接
public class JDBCUtil {
static ComboPooledDataSource DataSource = new ComboPooledDataSource();
public static Connection getConnection(){
Connection con = null;
try {
con = DataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
}
那么现在我们就可以写数据库的操作方法areaDAO
这里我们需要先创建area的实体
package com.cr.entity;
public class Area {
private String code;
private String name;
private int layer;
public Area() {
super();
// TODO Auto-generated constructor stub
}
public Area(String code, String name, int layer) {
super();
this.code = code;
this.name = name;
this.layer = layer;
}
@Override
public String toString() {
return "Area [code=" + code + ", name=" + name + ", layer=" + layer + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.hashCode());
result = prime * result + layer;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Area other = (Area) obj;
if (code == null) {
if (other.code != null)
return false;
} else if (!code.equals(other.code))
return false;
if (layer != other.layer)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLayer() {
return layer;
}
public void setLayer(int layer) {
this.layer = layer;
}
}
创建好实体之后就是创建areaDAO
由于SQL语句里面需要有两个参数,所以这里我们需要传递两个参数进去
由于这里我们导入一个commons-dbutils-1.3.jar的jar包。commons-dbutils是Apache组织提供的一个开源 JDBC工具类库,能让我们更简单的使用JDBC。它是一个非常小的类包,核心只是两个类 org.apache.commons.dbutils.DbUtils、org.apache.commons.dbutils.QueryRunner和一个接口org.apache.commons.dbutils.ResultSetHandler
DbUtils类
DbUtils是一个用来做一些如关闭连接、装载JDBC驱动程序之类的常规工作提供有用方法的类,它里面所有的方法都是静态的。
所以我们在JDBCUtils里面就不用加载驱动和关闭连接了,而是直接通过combopooleddatasource来获取连接
QueryRunner类
这个类简单化了执行SQL查询,它与ResultSetHandler组合在一起使用就可能完成大部分的数据库操作,它能够大大减少你所的编码量。
QueryRunner类提供了两个构造方法:一个是默认的构造方法;另一个需要一个 javax.sql.DataSource 来作为参数。因此,在你不用为一个方法提供一个数据库连接的情况下,提供给构造器的DataSource)被用来获得一个新的连接并将继续进行下去。
resultSetHandler接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)。因此任何ResultSetHandler 的执行需要一个结果集(ResultSet)作为参数传入,然后才能处理这个结果集,再返回一个对象。因为返回类型是java.lang.Object,所以除了不能返回一个原始的Java类型之外,其它的返回类型并没有什么限制。
由于jar包里面有一个QueryRunner.class可以用来执行查询,所以这里我们先new一下这个class类,然后直接调用他的查询方法
public class AreaDAO {
private QueryRunner qr = new QueryRunner();
/**
* 获取area的所有信息
* @param pageSize 页面显示的条数
* @param CurPage 当前的页数
* @return 返回查询后的结果集
*/
public List<Area> getAreaInfo(int pageSize,int CurPage){
String sql = "select r,code,name,layer "
+ " from (select rownum as r,code,name,layer from area) t "
+ " where r between ? and ? ";
try {
qr.query(JDBCUtil.getConnection(), sql, new ArrayListHandler(),(CurPage-1)*pageSize+1,CurPage*pageSize);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
这里通过util里面的queryrunner的查询方法来直接查询
不用先获取连接,和new arraylist()等创建对象装取结果集,以及预处理等繁琐的过程,而是直接准备SQL语句,然后调用qr.query()方法执行SQL语句
返回一个arraylisthandler的类型,同时也不用setint等方法来设置传递进来的参数,而是直接可以放在qr.query()的后面,有多少个参数就直接放在后面就可以了。
ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
new ArrayListHandler()这里查询的结果集放在class 类ArrayListHandler里面的
那么这里我们还要新建一个handler,用来处理返回的结果集
where r between ? and ? 一定注意在SQL语句中没有r>=? and r <=?
而是要写成between and 的形式