转自:http://hi.baidu.com/zzcc_8/blog/item/ddbcc42ed767d25b4fc226bd.html
作者:爱题巴.爱技术.小川哥
近期看到在某贴里有一个小程序,内涉到连库的技术,所以发个帖子讨论一下。
首先,连库语句和关闭连接的部分都应该单独提取出来放在一个类里,有可能的话,连库语句还能以输入或从文件中读取的形式做出来,这是因为连库的语句有可能会出现变化,比如:今天连mysql,明天可能因为升级或其他原因换成了oracle,如果你有50个类都涉及到连库那你就要改50个地方,而把连库语句放在一个类中,由其他类去调用它,那么改的时候则只需要改这一个地方,而对关闭连接语句的改动情况可能不会很多但是,由于连一次库就需要有一次关闭连接,连50次库就需要写50遍几乎一模一样的关闭连接语句,写代码即麻烦又不够漂亮。像这样以让结果不发生改变为前提,通过修改代码结构来减少以后修改的麻烦,让代码写的更漂亮的技术就是“重构”,关于重构问题参与过项目的人其实都很清楚其重要性,我在这里就不多说了,为那些还在受到大学里连命名都用a,b,c的无良教育的兄弟们推荐“重构--改善既有代码的设计”这本书,马丁大师的杰作,建议这本书要买下来,而不是去图书馆借。
由于我重点想说的是关闭连接,所以对连库方面就说这么多,下面重点说说关闭连接的写法,以下是我看到的那个帖子里写的关闭连接方法(命名可能不同),
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
conn = XXX;
ps = conn.XXX;
rs = ps.XXX;
下面是重点
rs.close();
ps.close();
conn.close();
看到上面的关闭语句了吗?只有3行,但看到这里的人不知道有多少看出这3行中的问题?至少我认为,那些正在接受大学过时教育的学生们都不会看出这里有什么样的问题。那么下面我们就分析一下:
首先conn,ps,rs的初值为null,就是说还没有连接的情况,那么如果在你的程序中,这3个中有1个,2个甚至3个都没有用到或在之前被置空怎么半?比如你有可能没有用到rs,那么就会出现这种情况:
rs = null;
rs.close();
很明显,没有打开的东西为什么还要关闭?所以只在这个问题上正确的写法如下:
if(ps != null){
ps.close();
ps = null;
}
上面的写法就比最开始那个3行关闭要好的多,但这个的写法依然存在问题,每个人都知道在写数据库的操作时会用到下面这个语法:
try{
...
}catch(SQLException e){
e.printStackTrace();
}finally{
...
}
每个人还都知道这是为了应付中途出现数据库错误而调用的一段错误处理,然后try剩余的部分会终止并从finally开始运行。所以,关闭连接的语句的问题就出现在了这里,我知道肯定有人把关闭语句写在try里因而省掉了finally的部分,但这么做的话,中途出现错误就会导致关闭语句没有被执行,所以关闭语句必须要写在finally里,另外,万一rs,ps中有一个出错,那么conn怎么办?比如说:rs.close()出错,ps和conn的close怎么办?这点也必须考虑进去,因而关闭语句的正确的写法应该是下面这个样子:
try{
if(result != null){
result.close();
result = null;
}
}catch(SQLException e){
e.printStackTrace();
}finally{
try{
if(ps != null){
ps.close();
ps = null;
}
}catch(SQLException e){
e.printStackTrace();
}finally{
try{
if(conn != null){
conn.close();
conn = null;
}
}catch(SQLException e){
e.printStackTrace();
}finally{
return "数据库连接已关闭";
}
}
}
然后把上面那段代码放在下面这个总的finally中就行了,由于还要对格式我就不写了
try{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
conn = XXX;
ps = conn.XXX;
...
rs = ps.XXX;
}catch(SQLException e){
e.printStackTrace();
}finally{
//这里放那段关闭代码
}
不要觉得这段关闭代码多余,如果你去应聘公司,面试官让你写出关闭连接的代码,写成3行的那种和写成最后这种明显是不同的,虽然相比多出很多代码,不过你把这些关闭代码提取到一个类中去,通过参数传递conn,ps,rs,只需要写这一遍就可以用一辈子了。如果谁还知道我这种写法还存在什么漏洞也请指教。
最后还是忍不住再说两句,根据重构法则,要尽量消除重复的代码,所以如果conn,ps和rs在你的一个类中出现了不只一次(比如2个方法都用到了它们),则可以考虑把他们变成类的私有属性提出来,如下:
private Connection conn = null;
private PreparedStatement ps = null;
private ResultSet rs = null;
另外还有一点,上次看到的那个小程序中把存取函数(set和get方法)单独提了出来,这种做法很不错,但是如果不需要外界调用的话,则可以不用写,因为多加一个存取函数就相当于对外多开放了一个接口,有的时候你多写一个存取函数无所谓,但有时候则会出现安全性的问题哦。
分享到:
相关推荐
在Java编程中,JDBC(Java Database Connectivity)是用于与各种数据库进行交互的标准接口。它允许Java应用程序通过Java代码来...在实际开发中,还需要注意处理可能的异常,并确保正确关闭数据库连接以避免资源泄漏。
正确的写法应该是`float t = (float) 5.84d;` 或者 `float t = 5.84f;`。 #### 三、运算符和表达式 1. **switch语句能否作用在byte、char、short、long、String上?** - 在Java 7及以上版本中,`switch`语句支持`...
在Microsoft Access中,可以通过快捷键Alt+F+X来关闭当前数据库。因此,正确答案是: - 正确答案 **A. Alt+F+X** ### 22. Visual FoxPro中的参照完整性规则 在Visual FoxPro中,参照完整性规则用于确保表间关系的...
在Java中,创建数组的正确方式是使用new关键字。选项A和B是正确的创建方式,而C使用了初始化列表创建数组。选项D错误,因为数组声明和初始化应该分开,或者在声明时直接赋值,正确的写法应为`int intArray[] = new ...
- **知识点概述**:本题考查了MySQL中关于完整性约束的基本概念。 - **详细解析**: - **选项A**:“实体完整性可由主键约束或候选键约束来实现”。这是正确的。实体完整性是指保证表中的每一条记录都唯一可识别,...
- **结论**:正确答案为正确,即集合中不能直接存放基本数据类型,如int、double等,而只能存放引用数据类型。 #### 题目6:JavaScript中的取整操作 - **题目解析**:本题考查JavaScript中获取接近指定数字的整数的...
7. **实际项目中的适应性**:在实际项目中,可能需要根据数据库类型和具体需求调整分页SQL的写法,例如Oracle支持ROWNUM,而MySQL则可以使用LIMIT和OFFSET。 **优化技巧**: 1. **缓存**:对于不经常变动的数据,...
这是一种在关系数据库中非常常见的操作,主要用于从大型数据集中提取特定列的信息。 **知识点解析**: - 选择:根据某些条件选择满足条件的行。 - 投影:选择指定的列。 - 连接:组合两个或多个表中的行。 - 自然...
正确的写法是使用`<a>`标签,并通过`href`属性指定链接的目标地址。例如,`<a href="http://www.w3schools.com">W3Schools</a>`。因此,正确答案是**B**。 ### 15. 哈希表操作 **知识点**:哈希表是一种数据结构,...
正确的写法是将所需的标题文本放在`<title>`和`</title>`标签之间。例如,要将页面标题设为“HTML练习”,正确的代码应该是`<title>HTML练习</title>`。 #### 参数查询的理解 - **知识点解析**:参数查询允许用户...
- **快捷方式**:是Windows操作系统中用于快速访问文件或程序的一种方式,它本质上是指向目标对象的链接。 - **特征**:快捷方式图标通常会在左下角显示一个小箭头,以区别于实际的目标文件。 ### 15. 计算机指令...
- 在Java中,接口可以继承多个父接口。 - 接口继承使用extends关键字,并且可以继承多个父接口。 #### 题目7: 字段数据类型 - **题目描述**:考察不同数据类型的适用场景。 - **知识点解析**: - `字符型`(如...
正确写法: Select last_name,title,salary*NVL(commission_pct,0)/100 COMM From s_emp;--把提成是空值的转化为0 DISTINCT:过滤重复 把重复的行过滤掉;多个字段组合时,只排除组合重复的。 DISTINCT必须使用...