Правильный способ повторного использования экземпляра PreparedStatement? - PullRequest
5 голосов
/ 10 февраля 2011

Как правильно создать PreparedStatement, повторно использовать его несколько раз, а затем очистить?Я использую следующий шаблон:

Connection conn = null;
PreparedStatement stmt = null;

try {
    conn = getConnection(...);

    // first use
    stmt = conn.prepareStatement("some statement ?");
    stmt.setString(1, "maybe some param");
    if (stmt.execute()) {
        ...
    }

    // second use
    stmt = conn.prepareStatement("some statement ?");
    stmt.setString(1, "maybe some param");
    if (stmt.execute()) {
        ...
    }

    // third use.
    stmt = conn.prepareStatement("some statement");
    stmt.execute();
}
finally {
    if (stmt != null) {
        try {
            stmt.close();
        } catch (Exception sqlex) {
            sqlex.printStackTrace();
        }

        stmt = null;
    }

    if (conn != null) {
        try {
            conn.close();
        } catch (Exception sqlex) {
        sqlex.printStackTrace();
        }

        conn = null;
    }
}

Можем ли мы повторно использовать объект "stmt" или мы должны вызывать stmt.close () между каждым запросом?

Спасибо

---------- Обновление ------------------------

Ах, хорошо, явидите, каждое из моих высказываний будет отличаться.Так это более правильный шаблон?:

Connection conn = null;
PreparedStatement stmt = null;

try {
    conn = getConnection(...);

    // first use
    PreparedStatement stmt1 = null;
    try {
        stmt1 = conn.prepareStatement("some statement ?");
        stmt1.setString(1, "maybe some param");
        if (stmt1.execute()) {
            ...
        }
    }
    finally {
        if (stmt1 != null) {
            try {
                stmt1.close();
            } catch (Exception ex) {}
        }
    }

    // second use
    PreparedStatement stmt2 = null;
    try {
        stmt2 = conn.prepareStatement("some different statement ?");
        stmt2.setString(1, "maybe some param");
        if (stmt2.execute()) {
            ...
        }
    }
    finally {
        if (stmt2 != null) {
            try {
                stmt2.close();
            } catch (Exception ex) {}
        }
    }

    // third use
    PreparedStatement stmt3 = null;
    try {
        stmt3 = conn.prepareStatement("yet another statement ?");
        stmt3.setString(1, "maybe some param");
        if (stmt3.execute()) {
            ...
        }
    }
    finally {
        if (stmt3 != null) {
            try {
                stmt3.close();
            } catch (Exception ex) {}
        }
    }
}
finally {
    if (conn != null) {
        try {
            conn.close();
        } catch (Exception sqlex) {
        sqlex.printStackTrace();
        }

        conn = null;
    }
}

Таким образом, каждый отдельный оператор будет закрыт индивидуально перед выполнением следующего.

1 Ответ

5 голосов
/ 10 февраля 2011

Все наоборот - вам нужно подготовить его только один раз, а затем использовать повторно.

т.е. Это:

// second use
    stmt = conn.prepareStatement("some statement ?");
    stmt.setString(1, "maybe some param");
    if (stmt.execute()) {
        ...
    }

должно стать таким:

// second use
    stmt.setString(1, "maybe some param");
    if (stmt.execute()) {
        ...
    }

Ваше третье использование, которое является другим оператором, должно быть либо новой переменной, либо сначала закрыть ваше подготовленное утверждение. (Хотя обычно с PreparedStatements вы сохраняете их и используете повторно).

...