0

親関数を使用して、接続プール内のすべての厄介な catch/finally を処理することに問題はありますか?

public Connection getConnection() {
    try {
        return this.dataSource.getConnection();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

public ResultSet executeQuery(Connection connection, PreparedStatement stmt) {
    try {
        return stmt.executeQuery();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    return null;
}
4

3 に答える 3

3

例外をスローするのではなく、食べているという事実を除いて問題はありません。呼び出し元のメソッドが適切なアクションを実行できるようにするには、例外をスローすることをお勧めします。

: Java 7 に移行して、try with resource を使用できる場合は、そのような混乱を大幅に軽減できます。詳細については、http: //docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.htmlをご覧ください。

于 2013-08-10T01:26:06.450 に答える
2

これはFacade パターンの例です。

これらのメソッドを作成する必要があることを除いて、問題はありませんstatic。したがって、それらは (ステートレス) ユーティリティ メソッドです。

于 2013-08-10T01:25:49.400 に答える
0

try-with-resourcesパターンを使用し、リソースの範囲を最小限に抑えることに重点を置くと、コードがよりクリーンになります。特に、閉じる動作とは別にリソース (接続とステートメント) を開くという問題があります。分割すると、ミスを犯したり、非効率的なコードを作成したりしやすくなります。たとえば、おそらくクエリの実行後に接続を閉じるべきではありません。

代わりに、通常、同じ場所でリソースを開いたり閉じたりする必要があります。また、これらのリソースを信頼して渡す (不変条件を作成する) 場所はどこでも、それらが開いたままになり、開いたままになる必要があります。これにより、リソースを取得する動作がリソースを使用する動作から明確に区分され、これらのリソースが開かれている範囲を明確に制限できます。

コードを比較します。

Connection conn = getConnection();
PreparedStatement ps = ...; // construct PreparedStatement
ResultSet rs = executeQuery(conn, ps);
// use ResultSet

/* now secretly your Connection and PreparedStatement are closed (even if you wanted
   to use them again) though your result set is still open and needs to be closed.

   Admittedly it's concise, but what's actually going on is very unclear. */

私のコードに:

public static void main(String[] args) {
    try(Connection conn = this.dataSource.getConnection()) {
        // All calls in this block, and only calls in this block, can use the connection
        buildObjectWithDBData(conn); // method does exactly what the name implies
        // do more calls against our connection as needed
    }
}

public static void buildObjectWithDBData(Connection conn) {
    try(PreparedStatement ps = /* generate prepared statement */;
        ResultSet rs = ps.executeQuery()) {
        // do work with result set, populate the data we need
    }
    // at this point we know the connection is alive in a clean, stable state,
    // the resources opened here are closed, and we've done the work we need
}

私は認めます、私のものはもう少し冗長です。しかし、それが何をしているのかははるかに明確であり、プロセスのすべてのステップで、任意のメソッド呼び出しの副作用に頼って密かにオブジェクトを閉じてそのままにしておくのではなく、オブジェクトとリソースの範囲を可能な限り小さく制限しています。まだ範囲内ですが、使用できません。

于 2013-08-10T01:57:52.333 に答える