質問

を考慮するコード:

PreparedStatement ps = null;
ResultSet rs = null;
try {
  ps = conn.createStatement(myQueryString);
  rs = ps.executeQuery();
  // process the results...
} catch (java.sql.SQLException e) {
  log.error("an error!", e);
  throw new MyAppException("I'm sorry. Your query did not work.");
} finally {
  ps.close();
  rs.close();
}

上記にないコンパイルしているため、 PreparedStatement.close()ResultSet.close() 捨てる java.sql.SQLException.いていただいておりまtry/catchブロックのfinally?又は移動の諸表のtry?はまぁいいんじゃない呼び出し圏?

役に立ちましたか?

解決

ファイルI / Oの場合、通常はtry / catchをfinallyブロックに追加します。ただし、finallyブロックから例外をスローしないように注意する必要があります。例外が発生すると、元の例外(存在する場合)が失われるためです。

データベース接続のクローズのより具体的な例については、この記事を参照してください。

>

他のヒント

Java7のいずれもないあって明示的にも利用 自動的資源管理資源 が閉まっている例外を適切に取扱います。例外処理の作品のようになります:

Exception in try | Exception in close | Result
-----------------+--------------------+----------------------------------------
      No         |        No          | Continue normally
      No         |        Yes         | Throw the close() exception
      Yes        |        No          | Throw the exception from try block
      Yes        |        Yes         | Add close() exception to main exception
                 |                    |  as "suppressed", throw main exception

今意いたしました。ですかコードのようになります:

private void doEverythingInOneSillyMethod(String key)
  throws MyAppException
{
  try (Connection db = ds.getConnection()) {
    db.setReadOnly(true);
    ...
    try (PreparedStatement ps = db.prepareStatement(...)) {
      ps.setString(1, key);
      ...
      try (ResultSet rs = ps.executeQuery()) {
        ...
      }
    }
  } catch (SQLException ex) {
    throw new MyAppException("Query failed.", ex);
  }
}

前のJava7のでご利用入れ子の最後にブロックにより検査の参考のためのnullになります。

の例は、私のようになってい醜いに深くネストしたが、実際に、コードしょうがなくなるわけではありません接続を作成し、結果はすべて同じ方法しばしば、各レベルの営巣は通のリソースが別の方法を用いた工場としても資源です。このアプローチから例外がスローされる場合 close() はマスクの例外からの try ブロックです。ことを乗り越えることができると思うが、その結果としても汚コード、カスタム例外クラスを提供する"抑制"の例外チェーン現在のJava7.

Connection db = ds.getConnection();
try {
  PreparedStatement ps = ...;
  try {
    ResultSet rs = ...
    try {
      ...
    }
    finally {
      rs.close();
    }
  } 
  finally {
    ps.close();
  }
} 
finally {
  db.close();
}

本当に自分のjdbcを手で回しているのなら、間違いなく面倒です。最後のclose()は、独自のtryキャッチでラップする必要がありますが、これは少なくともatいです。クローズをスキップすることはできませんが、接続がクローズされるとリソースがクリアされます(プールを使用している場合は、すぐに終了しない場合があります)。実際、フレームワーク(たとえば、休止状態)を使用してdbアクセスを管理する主なセールスポイントの1つは、接続と結果セットの処理を管理することです。

このような簡単なことができます。これにより、少なくとも混乱が隠され、何かを忘れないことが保証されます。

public static void close(ResultSet rs, Statement ps, Connection conn)
{
    if (rs!=null)
    {
        try
        {
            rs.close();

        }
        catch(SQLException e)
        {
            logger.error("The result set cannot be closed.", e);
        }
    }
    if (ps != null)
    {
        try
        {
            ps.close();
        } catch (SQLException e)
        {
            logger.error("The statement cannot be closed.", e);
        }
    }
    if (conn != null)
    {
        try
        {
            conn.close();
        } catch (SQLException e)
        {
            logger.error("The data source connection cannot be closed.", e);
        }
    }

}

そして

finally {
    close(rs, ps, null); 
}

低レベルの例外管理のコーディングに時間を無駄にしないでください。Spring-JDBCのような高レベルのAPI、またはconnection / statement / rsオブジェクトのカスタムラッパーを使用して、乱雑なtry-catchに乗ったコードを隠してください。

また注意:

" Statementオブジェクトが閉じられると、現在のResultSetオブジェクト(存在する場合)も閉じられます。 "

http:// java.sun.com/j2se/1.5.0/docs/api/java/sql/Statement.html#close()

最終的に、まだ閉じられていない場合にのみ、PreparedStatementを閉じるだけで十分です。本当に細かくしたい場合は、PreparedStatementを閉じた後ではなく、最初にResultSetを閉じます(この例のいくつかの例のように、それを閉じると、例外が既に閉じられているため、実際に例外が保証されます)。

通常、null参照で何もしようとしないように注意するなど、このようなことを閉じることができるユーティリティメソッドがあります。

通常、 close()が例外をスローした場合、実際には気にしないので、例外をログに記録して飲み込むだけです。 / code>。どちらの方法でも、呼び出しが簡単なユーティリティメソッドで行うことをお勧めします。多くの場所でこれを行う必要があります。

PreparedStatementのクローズに失敗した場合、現在のソリューションはResultSetをクローズしないことに注意してください。ネストされたfinallyブロックを使用することをお勧めします。

Java 7を使用している場合、 AutoCloseable (つまり、 PreparedStatement Resultset

この質問は興味深いものです。 Java 7でResultSetを閉じる

これは古い質問ですが、誰かが答えを探している場合に備えて、javaにはtry-with-resouceソリューションがあります。

static String readFirstLineFromFile(String path) throws IOException {
      try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

closeの呼び出しを省略しないでください。問題を引き起こす可能性があります。

最後にtry / catchブロックを追加することを好みます。

おそらく(単純ではあるが)古いやり方ですが、それでも機能します:

public class DatabaseTest {

    private Connection conn;    
    private Statement st;   
    private ResultSet rs;
    private PreparedStatement ps;

    public DatabaseTest() {
        // if needed
    }

    public String getSomethingFromDatabase(...) {
        String something = null;

        // code here

        try {
            // code here

        } catch(SQLException se) {
            se.printStackTrace();

        } finally { // will always execute even after a return statement
            closeDatabaseResources();
        }

        return something;
    }

    private void closeDatabaseResources() {
        try {
            if(conn != null) {
                System.out.println("conn closed");
                conn.close();
            }

            if(st != null) {
                System.out.println("st closed");
                st.close();
            }

            if(rs != null) {
                System.out.println("rs closed");
                rs.close();
            }

            if(ps != null) {
                System.out.println("ps closed");
                ps.close();
            }

        } catch(SQLException se) {
            se.printStackTrace();
        }               
    }
}

@ericksonの答えに基づいて、なぜこのような1つの try ブロックでそれをしないのですか?

private void doEverythingInOneSillyMethod(String key) throws MyAppException
{
  try (Connection db = ds.getConnection();
       PreparedStatement ps = db.prepareStatement(...)) {

    db.setReadOnly(true);
    ps.setString(1, key);
    ResultSet rs = ps.executeQuery()
    ...
  } catch (SQLException ex) {
    throw new MyAppException("Query failed.", ex);
  }
}

ResultSet ResultSet が自動的に閉じられるため、 try ブロック内に ResultSet オブジェクトを作成する必要はありません。 code> PreparedStatement オブジェクトは閉じられています。

  

ResultSetオブジェクトは、Statementオブジェクトが   生成されたものは閉じられ、再実行されるか、次の   複数の結果のシーケンスからの結果。

参照: https://docs.oracle .com / javase / 7 / docs / api / java / sql / ResultSet.html

focus finally節、

finally {
   try {
      rs.close();
      ps.close();
   } catch (Exception e) {
      // Do something
   }
}

2つのポイントを変更する必要があると思います。

まず、try&を使用しますわずかな節でもう一度キャッチします。

次に、ps.close()を実行する前にrs.close()を実行します。

fly1997@naver.com

これを使用します。

finally
{
    if (ps != null) ps.close();
    if (rs != null) rs.close();
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top