接《
初学JDBC时使用的一个基础DAO类的编写
》,当时那个BaseDao类的功能在初学JDBC时或许功能满足要求,但是随着学习的深入,慢慢会发现,其实大多数的增删改查操作无外乎就是那些代码的组合,所以在此提供一个功能更为强大的类来完善我们的功能,代码如下:
具体如何使用呢,下面是一个查询的例子
package cn.jbit.common.dao;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 扩展的一个数据库操作类,用于操作数据库的增删改查操作<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;//当前的列下标
/**
* 查询操作,值返回true或者false,具体的结果集通过此类的方法来获取
* @param sql,调用者方法中定义好的sql语句,通常是一个DAO类的方法
* @param params 传入的参数,多个参数用逗号隔开即可
* @return
*/
public boolean rowsQuery(String sql, Object... params) {
super.openConn();
rows.clear();
currentRow = -1;
try {
preparedSql(sql, params);
rs = pstmt.executeQuery();
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;
}
/**
* 移到下一行
* @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;
}
}
}
具体如何使用呢,下面是一个查询的例子
//...
DBHelper dbs = new DBHelper();
String sql = "select * from pet";
//判断是否查询成功
if (dbs.rowsQuery(sql)) {
while (dbs.nextRow()) {//移动到下一行,此种是按列名称查询,不区分列名称的大小写
System.out.print("宠物ID:" + dbs.getColumn("id"));
System.out.println("\t\t宠物名称:" + dbs.getColumn("NAME"));
}
}
//另外一种查询方式
sql = "select name, balance, password from petstore where id < ?";
if (dbs.rowsQuery(sql, 10)) {
while (dbs.nextRow()) {//移动到下一列数据上
while (dbs.nextColumn()) {
System.out.print(dbs.getColumn().toString() + "\t");
}
System.out.println();
}
}
//...