Как создать динамический подготовленный оператор в Java? - PullRequest
2 голосов
/ 30 марта 2012

Я знаю, что использование подготовленных операторов помогает избежать SQL-инъекций. Моя проблема в том, что подготовленное утверждение обычно очень статично. У меня есть проблема, когда я строю выражение where SQL-запроса во время выполнения, в зависимости от ввода пользователя. В зависимости от того, какие поля ввода заполнены, я должен добавить соответствующие операторы к предложению where. Как это можно реализовать с помощью готовых заявлений?

Ответы [ 5 ]

3 голосов
/ 30 марта 2012

Если вы строите операторы where / и в вашем запросе на основе того, какие параметры выбрал пользователь, то, я полагаю, вы уже знаете, какие изменения нужно будет внести в запрос, чтобы желаемые данные. Если это так, то вы можете создать метод, который принимает опцию, которую пользователь запросил в качестве параметра метода, метод создает запрос и возвращает этот запрос.

//something similar to the following
public String buildQuery(int option){
  StringBuilder sb = new StringBuilder();
  sb.append("select fields from table");
  switch(option){
    case 1:
     //build query and append to sb
     sb.append("where clause for option1");
    case 2:
     //build query and append to sb
     sb.append("where clause for option2");
    default:
    // build query using default
    sb.append("default where clause");
  }

  return sb.toString();
}
// create the stored procedure
PreparedStatement ps = conn.prepareStatement(buildQuery(2));
ResultSet rs = ps.executeQuery();

Теперь, если вам нужно использовать введенные пользователем значения в запросе, вы можете временно сохранить их в списке или на карте, а затем установить их.

ps.setString(1,list.get(0));
ps.setString(2,list.get(1));
ResultSet rs = ps.executeQuery();

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

3 голосов
/ 30 марта 2012

Полагаю, вы могли бы динамически создавать свои подготовленные операторы на основе того, какие столбцы они хотят запросить, то есть использовать StringBuffer и цикл для их построения на основе требуемых столбцов.

Для эффективности вы должны хранить их вкакой-то поиск в памяти.Таким образом, вы получите Map или другую коллекцию подготовленных операторов, ключом поиска которых являются столбцы, к которым они предназначены для запроса.

2 голосов
/ 30 марта 2012

Если вам нужна только защита от sql-инъекций, то создание запроса во время выполнения - это нормально, если вы не вставляете ничего, отправленного пользователем в запрос (но добавляется предложение, если пользователь отправил хотя бы что-то в поле, нормально).

Производительность - я не знаю.Возможно, БД будет кешировать подготовленные операторы, поэтому, если вы создадите точно то же самое снова, это будет быстрее или не будет.Я не знаю, как это выяснить.

0 голосов
/ 30 марта 2012

Объявите один метод и передайте пользовательский ввод через этот метод. Затем используйте setString или setLong в зависимости от вашего типа входных данных в подготовленном объекте.

0 голосов
/ 30 марта 2012

Если вы используете Hibernate, Criteria Queries API - хороший инструмент для избежания конкатенации строк при построении SQL-запросов.С простым JDBC вам придется использовать StringBuffer, как сказал @Jhonatan.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...