假如我写了一个单例类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的机制是怎么样的,都封装好了不知道咋写的 谢谢回复的各位了 

解决方案 »

  1.   

    整个项目用一个conn肯定不行,也不能每个原子操作都打开一个独立的连接,让相互有关的几个操作共用一个链接。
      

  2.   

    第一种做法是完全错误的!理由看这些帖子: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
      

  3.   

    并不是说不能把连接对象弄成成员变量,只是不能将其弄成成员变量后,在多线程环境下处于共享这些对象,如果同步处理得不好,那就会产生严重的连接泄漏。为了避免这种情况发生,仅在用时获取连接,用完后马上关掉。我想下面这种 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(); }
        }
    }
      

  4.   


    把conn作为局部变量,conn我是通过dataSource获得的,按照你说的,conn用完后就close掉,
    close之后是不是这个链接就被放回链接池了?
    如果conn是通过DriverManager创建的,close后就断开链接了大哥能给我说一下这两者的区别么,谢谢了
      

  5.   


    我认为我在 2 楼已经说得很明白了,不要把 Connection 弄成成员变量!至于区别,我在 2 楼好像也说了,API 上有说明,而且我还给了个链接,为什么不能去看一下呢?第二个问题:javax.sql.DataSource 是获得 Connection 的首先,详见这个接口的 API 文档。理由的话,我在这个帖子 64 楼第二块灰字中有说明:
    http://topic.csdn.net/u/20101121/23/872c3990-a7a8-42d8-8e5e-ef1de688301d.html
      

  6.   

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

  7.   

    这具体要看 DataSource 的实现是怎么样的,根据 JDBC 规范 DataSource 实现可以有三种方式(详见这个接口的 API),并不一定是要实现连接池功能的。