(Как) я могу использовать «LIKE» в SQL-запросах с MyBatis безопасно и без учета БД? - PullRequest
15 голосов
/ 21 сентября 2011

В MyBatis вы отмечаете места, где параметры должны быть вставлены в ваш SQL, следующим образом:

SELECT * FROM Person WHERE id = # {id}

Этот синтаксис активирует правильное экранирование и т. Д., Чтобы избежать, среди прочего, атак внедрения SQL-кода.Если вы доверяете вводу и хотите пропустить экранирование, вы можете вставить параметры дословно:

SELECT * FROM {tableName} WHERE id = # {id}

Теперь я хочу выполнить LIKE-поиск по небезопасным данным, поэтому я хочу сделать следующее:

SELECT * FROM Person, ГДЕ имя LIKE # {beginOfName}||'%'

К сожалению, , однако важные серверы БД не поддерживают синтаксис || для объединения :

MSSQL - нарушает стандарт, используя оператор «+» вместо «||».

...

MySQL - серьезно нарушает стандарт, переопределяя ||означать ИЛИ.

Итак, я мог бы сделать либо

ВЫБРАТЬ * ОТ ЛИЦА, ГДЕ НРАВИТСЯ имя CONCAT (# {beginOfName}, '%')

и в этом случае ограничиться MySQL, или я мог бы сделать

SELECT * FROM Person, ГДЕ имя LIKE '{beginOfName}%'

и придется самостоятельно очищать ввод.

Есть ли более элегантное решение?

Ответы [ 6 ]

11 голосов
/ 21 сентября 2011

Обычно это делается путем добавления % к самому параметру перед его передачей на любом языке, который вы используете вне SQL.Тем не менее, обратите внимание, что в любом случае вам все равно может потребоваться выполнить шаг экранирования, если ваш поисковый запрос может содержать _ или %.См., Например, этот вопрос для справки.)

Чтобы исправить проблему конкатенации в целом, поместите MySQL в ANSI sql_mode , и вы получите надлежащую поддержку оператора ||, а также правильная обработка двойных кавычек для имен схем, а не строковых литералов.

(Если вы не можете этого сделать, вам нужно создать функцию для построения оператора из || илиCONCAT(), абстрагируясь от разницы.)

10 голосов
/ 19 мая 2015

Вы можете использовать bind синтаксис

Цитирование Официальная документация

Элемент bind позволяет вам создать переменную из выражения OGNL и связать это с контекстом. Например:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>
4 голосов
/ 19 мая 2017

привязка включает в себя если

<select id="select" parameterType="java.util.Map" resultType="ViajeDTO">

SELECT A.ID_VIAJE ID, A.NOMBRE, A.DESCRIPCION, A.FINICIO, A.FFIN, A.LOGO, A.URL, 
        A.ID_CLIENTE IDCLIENTE, B.NOMBRE CLIENTE
FROM VIAJE A
INNER JOIN CLIENTE B ON (A.ID_CLIENTE = B.ID_CLIENTE)
WHERE A.ESTATUS = 1 

<if test="P_NOMBRE != null">
    <bind name="pattern" value="'%' + P_NOMBRE + '%'" />
      AND A.NOMBRE LIKE #{pattern}
</if>
</select>
3 голосов
/ 30 июля 2018

если вы используете mybatis, вы можете написать это для s

SELECT(" * ");
FROM(" student ");
WHERE(" ten LIKE '%' #{ten} '%' ");
0 голосов
/ 21 февраля 2017

Мы можем использовать Bind . Элемент bind позволяет вам создать переменную из выражения и связать ее с контекстом. Например:

<select id="select" parameterType="java.util.Map" resultType="ViajeDTO">

    <bind name="pattern" value="'%' + P_NOMBRE + '%'" />

    SELECT A.ID_VIAJE ID, A.NOMBRE, A.DESCRIPCION, A.FINICIO, A.FFIN, A.LOGO, A.URL, 
            A.ID_CLIENTE IDCLIENTE, B.NOMBRE CLIENTE
    FROM VIAJE A
    INNER JOIN CLIENTE B ON (A.ID_CLIENTE = B.ID_CLIENTE)
    WHERE A.ESTATUS = 1 

    <if test="P_NOMBRE != null">
        AND A.NOMBRE LIKE #{pattern}
    </if>
</select>

Принимая во внимание, что параметр для поиска - P_NAME.

0 голосов
/ 24 января 2012

|| оператор работал у меня в IBatis, но не в Mybatis.

В MyBatis мне пришлось использовать оператор +.

SELECT *
FROM Employee
WHERE
name like '%' + #{searchName,jdbcType=NVARCHAR} + '%'
...