2013-06-19 2 views
1

Я выполняю запрос и помещаю результат в JSONObject, чтобы вернуть его на страницу EXTJS. Код работает, но я не уверен, что это лучший или самый эффективный способ сделать это. Я отправлю свой код, пожалуйста, посмотрите, нужно ли мне улучшить его и где. Я свежий программист, поэтому оправдываю очевидные ошибки. Заранее спасибо.Это хороший способ выполнить запрос в java?

public JSONObject execQuery(String invoice, String id){ 

    StringBuffer sb = new StringBuffer(); 
    JSONObject json = new JSONObject(); 
    JSONObject data = new JSONObject(); 
    JSONArray jsArray = new JSONArray(); 

    try{ 
     // get conn 
     conn = DBConnect.getInstance().dbOracleConnect(); 

     // create query 
     sb = new StringBuffer("SELECT * FROM table "); 
     sb.append("WHERE rtrim(invoice) = ? AND "); 
     sb.append("id = ? "); 

     ps = conn.prepareStatement(sb.toString()); 
     ps.setString(1, invoice); 
     ps.setString(2, id); 

     rs = ps.executeQuery(); 

     while(rs.next()){ 
      json = new JSONObject(); 

      json.put("invoice", rs.getString("invoice")); 
      json.put("id", rs.getString("id")); 
      json.put("name", rs.getString("name")); 
      json.put("gender", rs.getString("gender")); 

      jsArray.put(json); 
      // out put will be like [{"invoice":"111", "id":"123", "name":"sam", "gender":"male"}, {...}]    
     } 
     data.put("data", jsArray); 
     // out put will be like {"data":[{"invoice":"111", "id":"123", "name":"sam", "gender":"male"}, {...}]} 
    } 
    catch(Exception e){ 
     System.out.println("Error: " + e.toString()); 
    } 
    finally { 
     JDBCHelper.close(rs); 
     JDBCHelper.close(ps); 
     JDBCHelper.close(conn); 
    } 

    return data; 
} 
+1

Является ли ваше соединение полем? Вы создаете его и закрываете каждый запрос. – Blindy

+1

Если 'DBConnect # dbOracleConnect()' каждый раз создает новое соединение (вместо повторного использования одного из пула), вы накладываете огромное количество накладных расходов на каждый запрос. –

+0

Не относится к самому вопросу, но я бы предпочел объявлять переменные, когда они нужны, а не все наверху. например 'JSONObject json = new JSONObject();' можно удалить. Вы даже создаете экземпляр, чтобы игнорировать его. Этот стиль значительно снижает читаемость по мере роста вашего метода. –

ответ

2

Несколько вещей, которые необходимо учитывать в коде:

  1. Вы закрываете соединение через JDBCHelper, это означает, что должно быть способом, в JDBCHelper, чтобы абстрагироваться от деталей получать подключение.

  2. Поскольку вы не создаете запрос динамически, вам не нужно использовать StringBuffer/StringBuilder. Регулярная строка эффективна для вашего случая.

  3. Переменные sb и json инициализируются два раза, один раз вверху и затем снова в блоке try. Просто объявите эти переменные вверху и инициализируйте их там, где они используются.

+0

Я хотел использовать StringBuffer, чтобы иметь возможность добавлять, а не делать +. Фактический запрос, если намного дольше я упростил его для этой публикации. – JS11

+0

Спасибо всем за очень действительные баллы, если есть больше, пожалуйста, опубликуйте его. – JS11

1

Без контекста, выглядит хорошо для меня основывается на двух предположениях:

1) Соединение получается из пула соединений. Образец использования, похоже, указывает на то, что это так. Но вам нужно прочитать документацию DBConnect и проверить это.

2) Запрос параметризуется. Вы делаете NOT хотите, чтобы значение было объединено непосредственно в SQL. Это неэффективно и небезопасно. Ваш запрос настроен параметризованным.

Некоторые незначительные комментарии:

1) Это выглядит как 'Конн', 'RS', 'пс' все поля класса. Я не вижу нужды. Если вы настроите их как локальную переменную, вы станете апатридом - легче читать и поддерживать. Еще лучше объявить переменные, где они используются, как это было предложено другими.

2) StringBuffer (или StringBuilder) здесь переполнен.

+0

Добавление детали ко второму # 2: Компилятор javac оптимизирует «начало» + «средний» + «конец» до «startmiddleend», когда все части являются литералами. –

+0

neurite, спасибо за комментарий. Можете ли вы рассказать мне больше о втором комментарии. «2) Запрос параметризуется. Вы НЕ хотите, чтобы значение было объединено непосредственно в SQL. Это неэффективно и небезопасно. Ваш запрос настроен параметризованным». Является ли использование подготовленного оператора помещать значения параметров в SQL-запрос, конкатенируя непосредственно в SQL? – JS11

+0

Если параметр не параметризован, он будет неэффективным, поскольку каждое уникальное значение объединяется в уникальную строку SQL. База данных будет выполнять запрос «на лету» и не будет возможности оптимизировать. В то время как параметризованный запрос рассматривается как * один * запрос для всех разных значений в базе данных. Еще лучше база данных компилирует ее и оптимизирует ее для повышения производительности. Конкатенационный запрос также небезопасен из-за возможности SQL-инъекции (т. Е. Значение является частичным SQL, а строка конкатенированных запросов больше не нужна). – neurite

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