简化JDBC的数据库访问
来源:互联网 发布:南师大软件中心 编辑:程序博客网 时间:2024/05/21 17:08
简化JDBC的数据库访问
问题的产生:
在一些小型应用中,JDBC扮演着一个让人进退两难的角色。
最近我遇到了这样一个问题:项目不大,犯不着使用Hibernate之类的持久化技术,但JDBC带来的大量重复代码着实让维护工作举步维艰。
传统的数据库Query方法是这样的:
构造SQL语句 -> 从连接池中获取Connection -> 创建Statement -> 执行SQL查询请求 -> 处理ResultSet -> 关闭ResultSet以及Statement -> 释放Connection
大致的代码如下:
String SQL = "SELECT name, pass FROM table WHERE id = '"+ id +"'";
Connection conn = ConnectionPool.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.exeQuery(SQL);
while(rs.next()){
//.......
}
rs.close();
stmt.close();
ConnectionPool.release(conn);
这样带来一个问题:由于每次查询都要有这么一个套路,那么一旦改变了获取和释放Connection的策略,维护的工作量是巨大的。
如果你也像我一样想减少Ctrl-c和Ctrl-v的次数,那么请继续看下去吧。
分析:
事实上我们所关注的只有两个地方
1. 构造SQL语句
2. 处理ResultSet过程
其余部分都是简单的重复,按照重构的原则,因该尽量减少重复的代码,而把更多的注意力集中在对ResultSet的处理上。
假设我们有一个叫做doQuery的函数,用来统一处理 Query过程。
也许你会想到把构造好的SQL传递给doQuery,然后返回一个ResultSet,再另行处理ResultSet,这样的doQuery看起来会是这样:
public ResultSet doQuery (String SQL){
Connection conn = ConnectionPool.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.exeQuery(SQL);
stmt.close(); //ResultSet也同时被关闭了
ConnectionPool.release(conn);
return rs;
}
看起来不错,但是这样做你是无法处理ResultSet的,因为在Statement关闭的同时ResultSet也被关闭了。所以必须在同一个函数里创建、处理并关闭ResultSet。
解决方案:
解决方案是把构造好的SQL和处理ResultSet的过程同时传递给doQuery。可是,怎么实现呢?别忘了Java可是OO的。OO的第一大特性是什么?对,封装。我们可以把ResultSet的处理过程封装起来。
具体方法如下:
首先我们需要为每一次查询请求定义一个Query接口。接口里面定义两个方法:
interface Query{
public String getSQL(); // 获得这个查询的SQL
public Object doProcess(ResultSet rs); // 封装了对ResultSet的处理过程
}
下面轮到我们传说中的doQuery函数出场了:
class DBTool{
public static Object doQuery (Query query){
Connection conn = ConnectionPool.getConnection();
Statement stmt = conn.createStatement();
String SQL = query.getSQL(); // 获得这次查询的SQL
ResultSet rs = stmt.exeQuery(SQL); // 在这里创建了ResultSet实例
Object o = query.doProcess(rs); // 完成对ResultSet的处理
rs.close(); // 这里关闭ResultSet就不会有任何问题了 :)
stmt.close();
ConnectionPool.release(conn);
return o;
}
}
为了表达清楚,上面是一个简单的框架,省略了try – catch 以及一些容错判断的部分。
万事具备了,怎么使用呢?难道每次查询还要写一个实现了Query的类吗?
当然不用!要不然岂不是多此一举。还记得Swing里面处理Listener的方法吗。我们可以用匿名内部类来实现:
Object o = DBTool. doQuery (
new Query(){ // 一个实现了Query接口的匿名内部类
public String getSQL(){
String SQL = "SELECT name, pass FROM table WHERE id < '"+ id +"'";
return SQL;
}
public Object doProcess(ResultSet rs){
Vector vector = new vector();
User user = null;
while(rs.next()) {
user = new User ();
user.setName (rs.getString ("name"));
user.setPass (rs.getString("pass"));
vector.add(user);
}
return vector;
}
} // End new Query()
);
// 虽然有可能 抛出 ClassCastException 但这里 返回值的 类型 应该是明确的
Vector vector = (Vector)o;
代码中只剩下我们所关心的构造SQL和处理ResultSet的部分,是不是清爽多了:)
小结:
doQuery里采用了一个“Don’t call us, we will call you”的模版方法模式,这样就可以把我们所关心的代码部分独立出来了。
同样,我们还可以在DBTool里实现doUpdate()和doExecute()这两个方法,由于不牵涉到ResultSet,所以实现起来要简单得多。这里就不多说了。
这样我们用一个DBTool来帮助我们简化所有的数据库操作,省去了大量重复的代码,快哉快哉 :)
.蓝山咖啡.
2004.8.21 夜
- 简化JDBC的数据库访问
- C#源码: 数据库访问的简化封装
- JDBC 访问数据库的流程
- JDBC访问数据库的步骤
- JDBC访问数据库的步骤
- JDBC与数据库的访问
- jdbc访问数据库的步骤
- JDBC访问数据库的步骤
- JDBC-ODBC访问数据库,JDBC访问数据库
- JDBC访问所有数据库的完整步骤
- jdbc访问各数据库的方法
- JDBC 的 HelloWorld 程序, 数据库访问MySQL
- 基本的JDBC数据库访问流程
- JDBC访问所有数据库的完整步骤
- JDBC访问所有数据库的完整步骤
- JDBC访问所有数据库的完整步骤
- 基本的JDBC数据库访问流程
- JDBC 访问数据库的基本步骤(
- 查询第X页,每页Y条记录
- 北欧的Michael Learns To Rock的一首清澈见底的【Take Me To Your Heart】
- 项目初步发布完成,终于可以休息一下了
- 关于面试
- 北欧的Michael Learns To Rock的一首清澈见底的【Take Me To Your Heart】
- 简化JDBC的数据库访问
- 开始学习MFC了,我不想再浪费时间了!
- 改变2004
- 8月23日(星期一)
- 使用图片制作网页滚动条
- .net调用别人的http页面,返回结果,url中有中文的处理,get和post两种方法
- 今天开张,自己庆祝一下 嘿嘿 :)
- 紧急求助“短信服务”模块制作人员1名!!!
- 中日韩三国并非推Linux产品 而是开发基础层