Как объединить поле псевдонима в Mybatis с помощью параметра #{}

#mysql #mybatis

#mysql #mybatis

Вопрос:

Я использую springboot и mybatis 3.4.4 и Mysql 5.7, в mybatis mapper мне нужно изменить параметр sql ${} на #{} , мой sql такой :

 select * from t1 as record
<if test="orderBy != null and sort != null">
order by
vr.${orderBy} ${sort}
</if>
  

orderBy это одно поле, которое необходимо отсортировать, и sort является desc или asc

Мне нужно изменить ${} #{} , чтобы предотвратить внедрение sql, поэтому я пытаюсь это;

 select * from t1 as record
<if test="orderBy != null and sort != null">
            order by concat('vr.', #{orderBy})
            <if test="'desc'.equalsIgnoreCase(sort)">
                desc
            </if>
            <if test="'asc'.equalsIgnoreCase(sort)">
                asc
            </if>
        </if>
  

Я печатаю sql, и это правильно, скомпилированный sql такой:

 select * from t1 as record
order by
concat('vr.', ?) desc
  

Но это не работает, что он не сортируется по sortBy полю, тогда я провожу тест на простой тестовой таблице в DataGrip, если я ввожу параметр, используя кавычки, это не сработает, я подозреваю, что ввод параметра в mybatis представляет собой строку с кавычками, а не само значение.

введите описание изображения здесь

Вопрос: Как решить это, чтобы разрешить сортировку.

Комментарии:

1. «Но это не работает» — вы получаете сообщение об ошибке?

2. @TheImpaler не ошибка, но результат не отсортирован по целевому полю

Ответ №1:

Драйверы JDBC могут применять параметры к ограниченному числу точек в инструкции SQL, и каждая база данных / драйвер допускает для них разные расположения. Место, где находится параметр, не является типичным местом для параметра, поэтому его поддержка может быть отрывочной.

Чтобы быть в безопасности, я обычно делаю:

 select * 
from t1 as record
<if test="orderBy != null and sort != null">
  order by
  <choose>
    <when test="orderBy = 'id'">id</when>
    <when test="orderBy = 'name'">name</when>
    <when test="orderBy = 'address'">address</when>
    <otherwise>status</otherwise>
  </choose>
  <if test="'desc'.equalsIgnoreCase(sort)">desc</if>
</if>