用完的ResultSet、Statement怎么都不关闭?数据库连接Connection怎么也不关闭?数据库的SQLException就这么抛出去了?

解决方案 »

  1.   

    呵呵
    是啊,怎么对例外一点都不处理啊
    try一下,然后把例外打印出来都可以啦
    关闭resuldset
    关闭statement
    关闭connection
    否则就要等死啊
    数据库会死的
      

  2.   

    告诉你,如果不try能编译过去吗。???哈
      

  3.   

    to:
          xiaohaiz(老土进城,两眼通红)老土哥,那你给一个比较全面的程序吧,关注!
      

  4.   

    呵呵,太抬举俺了.哪有这么高的水平给大家上课.
    不过关于数据库的使用倒是有几点确实应该是多加注意的.
    (1) 第一是"事务(Transaction)"的概念,是一定要掌握的.事务这个东西其实是一个非常基础和重要的概念,当然不仅仅存在于数据库领域.围绕事务展开的业务可以说是多如过江之鲫.
    (2) 第二一定要理解到数据库连接(java.sql.Connection)的释放问题,数据库是一个可以共享的东东,如果你在不使用的情况下长占某种资源可能会导致别人的无法使用.这是一件需要避免的事情.
    (3) 第三需要知道数据库连接对象是重量级的对象,创建的开销比普通对象大得多,所以如果是性能关键的任务,应该考虑对象池技术来处理(也可以理解大家所言之"数据库连接池")俺见到过一种做法,可以和共享一下.其实对于JDBC连接的管理最基本的就是两种功能:
    (1) 申请连接;
    (2) 释放连接;
    所以可以定义如下的接口:
    <<
    public interface ConnectionManager {
        public Connection getConnection() throws Exception;
        public void returnConnection(Connection conn);
    }
    >>
    具体的数据库连接管理可以在其实现类来处理.可以使用数据库连接池技术,也可以不使用.:)比如:
    下面只是一个示例实现而已.BTW,驱动的注册放在静态初始化的地方比较合适,在加载的时候就会注册JDBC驱动,如果发生异常会抛出RuntimeException.
    <<
    final class DefaultConnectionManager implements ConnectionManager {
        private static final String DRIVER = "xxx";
        private static final String URL = "xxx";
        private static final String USER = "xxx";
        private static final String PASS = "xxx";
        static {
            registerDriver();
        }
        private static void registerDriver() {
            try {Class.forName(DRIVER);}
            catch(ClassNotFoundException ex) {throw new RuntimeException(ex);}
        }    DefaultConnectionManager() {}    public Connection getConnectionManager() throws SQLException {
           return DriverManager.getConnection(URL, USER, PASS);
        }    public void returnConnection(Connection conn) {
            if(conn==null) return;
            try {conn.close();}
            catch(SQLException ex) {}
        }
    }
    >>
    另外,为了方便使用ConnectionManager,通常情况下可以使用工厂类来实现,由工厂类来控制ConnectionManager的实例.
    <<
    public final class ConnectionManagerFactory {
        private static final ConnectionManagerFactory INSTANCE = new ConnectionManagerFactory();
        private ConnectionManagerFactory() {}
        public static ConnectionManagerFactory getInstance() {return INSTANCE;}    private final ConnectionManager defaultCM = new DefaultConnectionManager();
        public ConnectionManager getConnectionManager() {
            return defaultCM;
        }
    }
    >>在这样的结构下,其实绝大部分SQL任务都是一样的结构,比如:
    <<
    ConnectionManager cm = ConnectionManagerFactory.getInstance().getConnectionManager();
    Connection conn = null;
    try {
        conn = cm.getConnection();
    } catch(SQLException ex) {
        // 处理异常并且中断流程
    }try {
       // ... DO SQL TASK HERE
    } catch(SQLException ex) {
       // ... HANDLE SQLException
    } finally {
       cm.returnConnection(conn);
    }
    >>
    使用这样的方式来保证申请的连接都一定被释放掉.
    如果是手工执行事务,那么可以修改如下:
    <<
    try {
        conn.setAutoCommit(false);  // Begin transaction.
        
        // ... DO YOUR SQL TASK    conn.commit(); // commit transaction.
    } catch(SQLException ex) {
        try {conn.rollback();} catch(SQLException e) {} // rollback transaction.
        // ...  HANDLE SQL Exception
    } finally {
        cm.returnConnection(conn);
    }
    >>
    不管做什么SQL任务,架子总是和上面的例子相差不远.所以俺见过使用TEMPLATE METHOD来建立SQLTask的方式,把这些步骤都在模板方法中定义死.
    差不多先这些吧.
    :)
      

  5.   

    对啊,尤其是这句:static {
            registerDriver();
        }我理解不了啊。
      

  6.   

    public void returnConnection(Connection conn) {
            if(conn==null) return;
            try {conn.close();}
            catch(SQLException ex) {}
    这个方法的功能是保持连接呢,还是掐掉连接呢?
      

  7.   

    呵呵
    是啊,怎么对例外一点都不处理啊
    try一下,然后把例外打印出来都可以啦
    关闭resuldset
    关闭statement
    关闭connection
    否则就要等死啊
    数据库会死的
    ----------------
    这位大哥说的怎么都没有做呢?不用吗?
      

  8.   

    TO xiaozuidazhi(以前不会用,导致信誉分低_我是好人!):
    这只是一个示例的实现而已.这里实际上是断掉了连接.当然也可以委派数据库连接池的方法来实现returnConnection(Connection)方法.
      

  9.   

    package bbs;
    import java.io.*;
    import java.sql.*;
    import java.util.*;
    public class DbConnection {  Connection conn = null;
      Statement stmt  = null;
      ResultSet rset  = null;  public DbConnection() {  }
      /****************************************************************************
       * 方法名称:openConnection
       * 参数:无
       * 返回值类型:boolean
       * 说明:打开数据库Connection的方法,为了打开Connection,读取位于类路径下的
       * db.properties
       */
      public boolean openConnection(){
        //------------------------------------------------------------------------
        // STEP 1. 载入Properties文件
        //------------------------------------------------------------------------
        Properties prop = new Properties();
        try {
          InputStream is = getClass().getResourceAsStream("/db.properties");
          prop.load(is);
          if(is != null) is.close();
        } catch (IOException e) {
          System.out.println("[DbConnection]打开文件时出现错误");
        }
        //------------------------------------------------------------------------
        // STEP 2. 从Properties文件中读取property
        //------------------------------------------------------------------------
        String jdbc     =  prop.getProperty("driver");
        String url      =  prop.getProperty("url");
        String user     =  prop.getProperty("user");
        String password =  prop.getProperty("password");
        //------------------------------------------------------------------------
        // STEP 3. 将输入的Property输出到Debugging
        //------------------------------------------------------------------------
        System.out.println("jdbc=["+jdbc+"]");
        System.out.println("url=["+url+"]");
        System.out.println("user=["+user+"]");
        System.out.println("password=["+password+"]");
        //------------------------------------------------------------------------
        // STEP 4. 加载JDBC驱动
        //------------------------------------------------------------------------
        try{
          Class.forName(jdbc).newInstance();
        }catch(Exception e){
          System.out.println("加载JDBC驱动程序出错"+e.getMessage());
          return false;
        }
        //------------------------------------------------------------------------
        // STEP 5. 打开数据库驱动
        //------------------------------------------------------------------------
        try{
          this.conn = DriverManager.getConnection(url,user,password);
        } catch(SQLException e) {
          System.out.println("生成Connection过程中出现错误"+e.getMessage());
        }
        return true;
      }
      /***************************************************************************
       * 方法名称:executeQuery
       * 参数:query(sql查询语句)
       * 返回值类型:java.sql.ResultSet
       * 说明:查询方法
       ***************************************************************************/
      public ResultSet myexecuteQuery(String query) throws SQLException {
        this.stmt = conn.createStatement();
        this.rset = stmt.executeQuery(query);
        return rset;
      }
      /***************************************************************************
       * 方法名称:executeUpdate
       * 参数:query
       * 返回值类型:void
       * 说明:修改数据库的方法
       ***************************************************************************/
      public void executeUpdate(String query) throws SQLException {
        this.stmt = conn.createStatement();
        stmt.executeUpdate(query);
        if(stmt != null) stmt.close();
      }
      /***************************************************************************
       * 方法名称:close
       * 参数:无
       * 返回值类型:void
       * 说明:关闭相关的资源
       ***************************************************************************/
      public void close() throws SQLException {
        if(conn != null) conn.close();
        if(stmt != null) stmt.close();
        if(rset != null) rset.close();
      }
      /***************************************************************************
       * 方法名称:finalize
       * 参数:无
       * 返回值类型:void
       * 说明:从服务器回收资源
       ***************************************************************************/
      public void finalize() throws SQLException {
        this.finalize();
      }  }
      

  10.   

    public void finalize() throws SQLException {
        this.finalize();
      }  }
    从服务器回收资源这个方法不用实现吗?
      

  11.   

    下面这个是与sql2000连接的实例
    ----------------------
    已安装了microsoft 驱动程序jdk1.4; win2000 server;  MS sql2000;*/import java.sql.*;
    class sql
    {
     
    public static void main(String[] agrs) 
    {
    Connection  cn=null;
    Statement stmt=null;
    String     sql=null; try
     {
     Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
     }
    catch(ClassNotFoundException ex)
     {
     System.out.println("Not find  the  Driver!");
     }try

    String urls="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=webroot";//webroot 库名.TALBE 是表名;
    String user="sa";
    String password="password";
    cn= DriverManager.getConnection(urls,user,password);//stmt=cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    stmt=cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);sql="select  top 10 * from  TABLE1";
    ResultSet rs= stmt.executeQuery(sql);
    while(rs.next())
    {
     System.out.println(rs.getString(2)+"       "+rs.getString(3)); } rs.first();
     System.out.print(rs.getRow()+"       ");
     System.out.println(rs.getString(2)+" 1      "+rs.getString(3)); rs.last();
     System.out.print(rs.getRow()+"       ");
     System.out.println(rs.getString(2)+" 2      "+rs.getString(3)); rs.previous();
     System.out.print(rs.getRow()+"       ");
     System.out.println(rs.getString(2)+" 3      "+rs.getString(3)); rs.next();
     System.out.print(rs.getRow()+"       ");
     System.out.println(rs.getString(2)+" 4      "+rs.getString(3)); rs.absolute(2);
     System.out.print(rs.getRow()+"       ");
     System.out.println(rs.getString(2)+" 5      "+rs.getString(3));
     
     /*
     rs.afterLast();
     System.out.print(rs.getRow()+"       ");
     System.out.println(rs.getString(2)+"       "+rs.getString(3));
     System.out.print(rs.isAfterLast()); rs.beforeFirst();
     System.out.print(rs.getRow()+"       ");
     System.out.println(rs.getString(2)+"       "+rs.getString(3));
     */ String sql1="update  TABLE1 set 题目=?   where id=? ";
     PreparedStatement stmt1 = cn.prepareStatement(sql1);
     String stat  = new String("盛夏话足部保健");
     String stat1 = UnicodeToGB(stat);//解决中文问题
     stmt1.setString(1,stat1);
     stmt1.setInt(2,3423);
     stmt1.executeUpdate();
     cn.commit(); //System.out.println(stat1);
     //System.exit(0); //cn.setAutoCommit(false);
     
     stmt.addBatch("update  TABLE1 set 题目='盛夏话足部保健1'   where id='3407'");
     stmt.addBatch("update  TABLE1 set 题目='夏季预防中暑膳食1' where id='3408'");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('11','12','13','','')");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('12','12','13','','')");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('13','12','13','','')");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('14','12','13','','')");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('15','12','13','','')");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('16','12','13','','')");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('17','12','13','','')");
     stmt.addBatch("INSERT INTO  TABLE1  VALUES('18','12','13','','')");
     
     int [] updateCounts=stmt.executeBatch();
     cn.commit();
     
     stmt.close();
    cn.close();
    }
    catch(SQLException e)
     {
     System.out.println("The SQLException error!");
     }}
    /*
    */public static String UnicodeToGB(String strIn){
       byte[] b;
       String strOut = null;
       if(strIn == null || (strIn.trim()).equals(""))
       return strIn;
       try{
           b = strIn.getBytes("GBK");
           strOut = new String(b,"ISO8859_1");
       }
       catch(Exception e){
           System.out.println("unicodeToGB exception : " + e.getMessage() + "\n");
       }
       return strOut;

    /*
    */
    }