2014-08-27 4 views
3

У меня есть следующий класс запроса с двумя методами, метод insert() используется часто, а deleteRecord() - нет.Когда создавать/инициализировать подготовленное заявление

public class Query1 { 

private final static String INSERT = "insert into info values (?, current_timestamp)"; 
private final static String DELETE_RECORD = "delete from info where stamp = ?"; 

private static final Connection con = DatabaseConnection.getInstance(); 

//This method is used frequently 
public static void insert(List<String> numList) throws SQLException { 
    try (PreparedStatement st_insert = con.prepareStatement(INSERT)) { 
     for (int i = 0; i < numList.size(); i++) { 
      st_insert.setString(1, numList.get(i)); 
      st_insert.addBatch(); 
     } 
     st_insert.executeBatch(); 
    } 
} 

// This method is NOT used frequently 
public static void deleteRecord(Timestamp stamp) throws SQLException { 
    try (PreparedStatement st = con.prepareStatement(DELETE_RECORD)) { 
     st.setTimestamp(1, stamp); 
     st.execute(); 
    } 
} 

я преобразовал класс QUERY1 ниже, в котором PreparedStatement используется метод insert() инициализирован в статическом блоке, так как она часто используется.

public class Query2 { 
private final static String INSERT = "insert into info values (?, current_timestamp)"; 
private final static String DELETE_RECORD = "delete from info where stamp = ?"; 

private static final Connection con = DatabaseConnection.getInstance(); 

// Frequently used statements 
private static PreparedStatement st_insert; 
static { 
    try { 
     st_insert = con.prepareStatement(INSERT); 
    } catch (SQLException ex) {    
    } 
} 

//This method is used frequently 
public static void insert(List<String> numList) throws SQLException {   
    for (int i = 0; i < numList.size(); i++) { 
     st_insert.setString(1, numList.get(i));    
     st_insert.addBatch(); 
    } 
    st_insert.executeBatch(); 
} 

// This method is NOT used frequently 
public static void deleteRecord(Timestamp stamp) throws SQLException { 
    try (PreparedStatement st = con.prepareStatement(DELETE_RECORD)) { 
     st.setTimestamp(1, stamp); 
     st.execute(); 
    } 
} 

Это оптимизирует код с учетом использования подготовленных заявлений или это не является хорошей практикой? если не как это сделать? (Я новичок в JDBC и не сталкивался с такими примерами кода, как это.)

Любые предложения были бы весьма благодарны.

+2

Может зависеть от того, как часто вы вызываете свой метод, но я предлагаю придерживаться первого, чтобы вы периодически гарантировали, что ресурсы очищены. В последнем (статическом) подходе у вас нет возможности когда-либо очищать ресурсы. Ни один из них не обрабатывает обновления подключений, но это будет другой причиной для использования первой, поэтому лучше справляться с другими проблемами с БД. – user1676075

+1

из этой книги http://oreilly.com/catalog/jorajdbc/chapter/ch19.html Я думаю, что PreparedStatement, если вы не используете его повторно для многих операторов, на самом деле немного медленнее обычного Statement. Конечно, PreparedStatement - хороший подход, чтобы избежать внедрения SQL. – Leo

ответ

1

Ваши аргументы верны. Часто используемый запрос может выиграть от использования PreparedStatement. Точно, какие компромиссы будут варьироваться между БД. Вы отметили javadb, и если это то, что вы используете, PreparedStatements никогда не будет медленнее, поскольку регулярные утверждения проходят один и тот же процесс компиляции.

Это, я согласен с теми, кто советует не готовить заявление в статическом блоке. Обычно я пытаюсь подготовить утверждения в конструкторе или методе init, чтобы я мог повторно использовать ps в часто вызываемых методах.

отметить также, что даже пс может быть повторно «за спину» из-за изменений, которые могут повлиять, как запрос должен/должна быть выполнена (добавление индексов, изменение статистики, изменение в привилегиях и т.д.)

Смежные вопросы