IBatis2 Dynami c выполнение запросов на обновление - PullRequest
0 голосов
/ 27 мая 2020

Я работаю над выполнением набора запросов на обновление, которые динамически генерируются для выполнения на SQL сервере с использованием iBatis2. Я написал элемент обновления в sqlMap, как показано ниже, который выполняется в рамках транзакции:

<update id="updateDepartments" parameterClass="Office">
  declare @sql nvarchar(400);
  <iterate property="departmentList">
  <!-- form the update query and store in @sql-->
  exec sp_executesql @sql
  </iterate>
</update>

У меня есть пара вопросов, связанных со способом выполнения вышеуказанных запросов.

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

Есть ли лучший способ сделать это с помощью iBatis2?

Пример формирования запросов на обновление Dynami c: :

update Department set cost1=1000 where department_name='sales'
update Department set cost2=2000 where department_name='finance'
update Department set cost3=3000 where department_name='marketing'

Параметры, переданные как часть paramterClass, представляют собой список объектов, содержащих:

 1. Department name
 2. Column name to be updated 
 3. Value to be updated for column in 2. 

example,
['sales', 'cost1', 1000]
['finance', 'cost2', 2000]

1 Ответ

0 голосов
/ 27 мая 2020

Возможно, это возможно выполнить как пакетное выполнение, но я не уверен, что это возможно. Я давно не использую iBatis 2.

Я уверен, что каждый оператор SQL будет работать отдельно. При многократном вызове практически нет накладных расходов, если только вы не выполняете тысячи обновлений одновременно. Вы?

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

class updateDptParams {
  String name;
  String column;
  String value;
  // setters & getters omitted for brevity
}

Тогда преобразователь мог бы выглядеть так:

<update id="updateDepartment" parameterClass="updateDptParams">
  update Department set ${column}=${value} where department_name=#{name}
</update>

Примечание что column и value - это введенные как строки (с использованием ${}), поскольку они должны иметь типы переменных. Однако name - это стандартный параметр iBatis JDB C (с использованием #{}), так как это всегда VARCHAR. Убедитесь, что введенные параметры поступают из известного источника, а не из пользовательского интерфейса или другого внешнего источника; в противном случае ваш код будет уязвим для SQL Injection.

Наконец, если вы обновляете тысячи строк, это решение может быть хорошим. Это может быть улучшенная пакетная обработка обновлений или одновременное выполнение нескольких обновлений с использованием сложных операторов SQL. Однако я не уверен, насколько простой или подверженной ошибкам может быть эта потенциальная оптимизация.

...