JDBC connection 讨论

wanglei_1989 2011-01-26 08:45:38
假如我写了一个单例类TestDao
1.
public class TestDao
{
// 用之前初始化
private Connection conn;

public void add()
{
// 调用conn操作数据库,但不关闭conn
}

}

2.
public class TestDao
{

public void add()
{
Connection conn = ...;
// 调用conn操作数据库
conn.close();
}

}

1是整个项目用一个conn,2是每操作数据库时创建conn,用完了就关闭
大家评论下这两种形式的哪种好,效率怎样

用数据源创建conn的机制是怎么样的,都封装好了不知道咋写的

谢谢回复的各位了
...全文
145 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Leeezk 2011-01-26
  • 打赏
  • 举报
回复
第一种方法不可取,在对数据库操作完后要养成及时关闭的好习惯,这一点很重要!
  • 打赏
  • 举报
回复
这具体要看 DataSource 的实现是怎么样的,根据 JDBC 规范 DataSource 实现可以有三种方式(详见这个接口的 API),并不一定是要实现连接池功能的。
  • 打赏
  • 举报
回复
把conn作为局部变量,conn我是通过dataSource获得的,按照你说的,conn用完后就close掉,
close之后是不是这个链接就被放回链接池了?
如果conn是通过DriverManager创建的,close后就断开链接了

如果 DataSource 是采用连接池实现的话,那么 close 后肯定是放回连接池而不是关闭的。DriverManager 也没有其他的实现,只有一个,它是不带池功能的,所以 close 后会关闭与数据库之间的物理连接。
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wanglei_1989 的回复:]
把conn作为局部变量,conn我是通过dataSource获得的,按照你说的,conn用完后就close掉,
close之后是不是这个链接就被放回链接池了?
如果conn是通过DriverManager创建的,close后就断开链接了

大哥能给我说一下这两者的区别么,谢谢了
[/Quote]

我认为我在 2 楼已经说得很明白了,不要把 Connection 弄成成员变量!

至于区别,我在 2 楼好像也说了,API 上有说明,而且我还给了个链接,为什么不能去看一下呢?

第二个问题:

javax.sql.DataSource 是获得 Connection 的首先,详见这个接口的 API 文档。

理由的话,我在这个帖子 64 楼第二块灰字中有说明:
http://topic.csdn.net/u/20101121/23/872c3990-a7a8-42d8-8e5e-ef1de688301d.html
coolbamboo2008 2011-01-26
  • 打赏
  • 举报
回复
谢谢火龙果的教程
wanglei_1989 2011-01-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 bao110908 的回复:]
并不是说不能把连接对象弄成成员变量,只是不能将其弄成成员变量后,在多线程环境下处于共享这些对象,如果同步处理得不好,那就会产生严重的连接泄漏。

为了避免这种情况发生,仅在用时获取连接,用完后马上关掉。

我想下面这种 JDBC 的代码套路应该都知道吧,老老实实地按照套路来,不要自作聪明。


Java code
public void query() {
Connect……
[/Quote]

把conn作为局部变量,conn我是通过dataSource获得的,按照你说的,conn用完后就close掉,
close之后是不是这个链接就被放回链接池了?
如果conn是通过DriverManager创建的,close后就断开链接了

大哥能给我说一下这两者的区别么,谢谢了
  • 打赏
  • 举报
回复
并不是说不能把连接对象弄成成员变量,只是不能将其弄成成员变量后,在多线程环境下处于共享这些对象,如果同步处理得不好,那就会产生严重的连接泄漏。

为了避免这种情况发生,仅在用时获取连接,用完后马上关掉。

我想下面这种 JDBC 的代码套路应该都知道吧,老老实实地按照套路来,不要自作聪明。

public void query() {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = ConnectionFactory.getConnection();
String sql = "xxxx";
ps = con.preparedSatement(sql);
ps.setXxxxx(1, xxx);
rs = ps.executeQuery();
while(rs.next()) {
Xxxx xxx = rs.getXxxx();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }
if (ps != null) try { ps.close(); } catch (SQLException e) { e.printStackTrace(); }
if (con != null) try { con.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}



  • 打赏
  • 举报
回复
第一种做法是完全错误的!

理由看这些帖子:

tomcat连接池,重复多次调用方法出错: Connection is closed
http://topic.csdn.net/u/20090206/23/fcb94d20-c996-4e00-9951-966a509c849d.html

并发时出现的 java.sql.SQLException: 关闭的 Resultset: next
http://topic.csdn.net/u/20100815/16/ecca6662-feb6-4942-8495-6dd67260dc22.html

关于连接池的问题
http://topic.csdn.net/u/20081216/22/ff2d17d9-0722-4c0e-8656-7e8aa3e2ccb2.html

再重申第 102 次,如果对并发编程不是非常熟练的话,严禁将 JDBC 中的 Connection, PreparedStatement, ResultSet 对象弄成成员变量!更不能弄成静态的。

第二个问题:

javax.sql.DataSource 是获得 Connection 的首先,详见这个接口的 API 文档。

理由的话,我在这个帖子 64 楼第二块灰字中有说明:
http://topic.csdn.net/u/20101121/23/872c3990-a7a8-42d8-8e5e-ef1de688301d.html
三心不可得 2011-01-26
  • 打赏
  • 举报
回复
整个项目用一个conn肯定不行,也不能每个原子操作都打开一个独立的连接,让相互有关的几个操作共用一个链接。

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧