接《数据库操作的助手类的编写(可以完成功能复杂的查询和增删改操作)》,这个类的功能还不算多,无法满足分页的功能操作,所以现在提供一个类用于处理分页,所有的注释均已写好,由3个类组成,分别是BaseDao.java,DBHelper.java,PageBean.java
BaseDao.java
package cn.hlin.common.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 作为所有数据库访问的父类<br/>
* 适当的提供一些数据库的操作功能
*
* @author Administrator
*/
public class BaseDao {
protected Connection conn = null;
protected PreparedStatement pstmt = null;
protected ResultSet rs = null;
private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORACLE10";
private static final String UNAME = "student";
private static final String UPASS = "accp";
protected void preparedSql(String sql, Object... params)
throws SQLException {
openConn();
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
protected void query(String sql, Object... params) throws SQLException {
preparedSql(sql, params);
rs = pstmt.executeQuery();
}
/**
* @param sql
* ,调用者方法中定义好的sql语句,通常是一个DAO类的方法
* @param params
* 传入的参数,多个参数用逗号隔开即可
* @return
*/
public int update(String sql, Object... params) {
int count = 0;
try {
preparedSql(sql, params);
count = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeAll();
}
return count;
}
protected void openConn() {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(URL, UNAME, UPASS);
} catch (SQLException e) {
e.printStackTrace();
}
}
protected void closeAll() {
try {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//DBHelper.java
package cn.hlin.common.dao;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 扩展的一个数据库操作类,用于操作数据库的增删改查操作<br/>
* 目的是为了提供更为良好的开发体验,尽量少使用JDBC原生API操作 <br/>
* 创建作者:黄林<br/>
* 创建日期:2012-4-16
*/
public class DBHelper extends BaseDao {
private int currentRow = -1;
private List<List<NameValuePair>> rows = new ArrayList<List<NameValuePair>>();
private int currentColumn = -1;// 当前的列下标
/**
* 分页查询方法 分2部分组成,第一部分是计算总记录数,第二部分是查询分页内容
* 传入参数在原来的基础上加上2个参数,一个起始记录和结束记录
* @param pb
* @param sql
* @param params
* @return
*/
public boolean pagedQuery(PageBean pb, String sql, Object... params) {
pb.setTotal(this.queryCount(sql, params));
String pagedSql = "select * from (select rownum as rn, t__.* from ("
+ sql + ") t__) where rn >= ? and rn <= ?";
Object[] p = new Object[params.length + 2];
p[params.length] = pb.getFirstResult();
p[params.length + 1] = pb.getMaxResult();
return rowsQuery(pagedSql, p);
}
/**
* 由于order by消耗资源相当大,统计行数时不需要
* <br/>本例使用正则表达式处理掉order by子句
* @param hql
* @return
*/
private String removeOrders(String hql) {
Pattern pattern = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*",
Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(hql);
StringBuffer buf = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(buf, "");
}
matcher.appendTail(buf);
return buf.toString();
}
/**
* 统计当前sql语句在数据库表中的总记录数
* @param sql
* @param params
* @return
*/
private int queryCount(String sql, Object... params) {
sql = "select count(1) from (" + removeOrders(sql) + ")";
try {
query(sql, params);
if (rs.next()) {
return rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
/**
* 查询操作,值返回true或者false,具体的结果集通过此类的方法来获取
*
* @param sql
* ,调用者方法中定义好的sql语句,通常是一个DAO类的方法
* @param params
* 传入的参数,多个参数用逗号隔开即可
* @return
*/
public boolean rowsQuery(String sql, Object... params) {
rows.clear();
currentRow = -1;
try {
query(sql, params);
ResultSetMetaData rsmd = rs.getMetaData();
int columnsCount = rsmd.getColumnCount();
while (rs.next()) {
List<NameValuePair> row = new ArrayList<NameValuePair>();
for (int i = 1; i <= columnsCount; i++) {
String columnName = rsmd.getColumnName(i);
row.add(new NameValuePair(columnName, rs
.getObject(columnName)));
}
rows.add(row);
}
} catch (SQLException e) {
e.printStackTrace();
return false;
} finally {
super.closeAll();
}
return true;
}
/**
* 移到下一行,如果没有则返回false
* @return
*/
public boolean nextRow() {
currentRow++;
currentColumn = -1;// 每移到一行,列都重头开始
if (currentRow < rows.size()) {
return true;
} else {
return false;
}
}
/**
* 判断当前是否还有列未遍历完成
*
* @return
*/
public boolean nextColumn() {
currentColumn++;
if (currentColumn < rows.get(currentRow).size()) {
return true;
} else {
return false;
}
}
/**
* 返回当前列的值<br/>
* 下标按当前下标值
*
* @return
*/
@SuppressWarnings("unchecked")
public <V> V getColumn() {
return (V) rows.get(currentRow).get(currentColumn).getValue();
}
/**
* 按列小表获取列数据
*
* @param columnIndex
* @return
*/
@SuppressWarnings("unchecked")
public <V> V getColumn(int columnIndex) {
return (V) rows.get(currentRow).get(columnIndex).getValue();
}
/**
* 获得当前列的值 由于列的数量相对来说不多,一般不超过几十列,所以用集合遍历也没问题
*
* @param column
* @return
*/
@SuppressWarnings("unchecked")
public <V> V getColumn(String column) {
for (NameValuePair nvp : rows.get(currentRow)) {
if (nvp.getName().equals(column.toUpperCase())) {
return (V) nvp.getValue();
}
}
return null;
}
/**
* 存放列名称和值的对象
*
* @author 黄林
*/
class NameValuePair {
private String name;
private Object value;
public NameValuePair(String name, Object value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
}
PageBean.java
package cn.hlin.common.dao;
public class PageBean {
private int pageSize = 10;//默认的每页条数
private int pageNum = 1;//起始记录
private int total;
/**
* 获取第一条记录开始处
*
* @return
*/
public int getFirstResult() {
return (pageNum - 1) * pageSize + 1;
}
public int getMaxResult() {
return pageNum * pageSize;
}
/**
* 获取下一页的页码
*
* @return
*/
public int getNext() {
if (pageNum < this.getTotalPages()) {
return pageNum + 1;
} else {
return pageNum;
}
}
/**
* 获取上一页的页码
*
* @return
*/
public int getPreview() {
if (pageNum > 1) {
return pageNum - 1;
} else {
return pageNum;
}
}
/**
* 获取总页数
*
* @return
*/
public int getTotalPages() {
if (total % pageSize == 0) {
return total / pageSize;
} else {
return total / pageSize + 1;
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
}
此三个类共同完成具有分页查询功能的操作以及其他数据库的操作类型,本代码为测试使用,实际使用请勿照搬,按实际情况修改或者重构。