Это 3-й день моего участия в ноябрьском испытании обновлений, узнайте подробности события:Вызов последнего обновления 2021 г.
Недавно взялся за старый проект."Радостное настроение" естественно неописуемое.Друзья,которые занимаются разработкой это знают.Больше тут не скажу,все слезы...
Чтобы взяться за старый проект, естественно сначала ознакомиться с бизнес-кодом, однако при чтении файла маппера я обнаружил довольно странную вещь. Вот упрощенный бизнес-код:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="list" resultType="com.example.demo.model.User">
select * from user
where 1=1
<if test="name!=null">
and name=#{name}
</if>
<if test="password!=null">
and password=#{password}
</if>
</select>
</mapper>
Остроумные друзья, возможно, заметили проблему и нашли такое же воображение у многих картографов,Почти все мапперы содержат бесполезную конкатенацию SQL: где 1=1. Как человек, у которого код почти чистый, естественно, что он не может не внести некоторые изменения.
Неправильный способ трансформации
Так как это удаление там, где 1=1, проще всего удалить его непосредственно из кода, как показано в следующем коде:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="list" resultType="com.example.demo.model.User">
select * from user
where
<if test="name!=null">
name=#{name}
</if>
<if test="password!=null">
and password=#{password}
</if>
</select>
</mapper>
Приведенный выше код удаляет 1 = 1 и удаляет и в запросе имени, чтобы предотвратить ошибки SQL-запроса.
Но все ли в порядке? Давайте посмотрим непосредственно на результаты.Когда запрос содержит имя параметра, результаты следующие:Все прошло гладко, полный бардак.
Однако, когда параметр имени опущен (поскольку имя не требуется, его можно опустить), возникает следующее исключение:Или когда делается только запрос пароля, результат тот же:Это неверная информация, что мне делать? Можно ли восстановить 1=1 обратно?
Правильный способ улучшить
На самом деле нет, эта проблема уже продумана в MyBatis, мыВы можете заменить ключевое слово where в SQL на метку в MyBatis и добавить сплайсер и к каждой метке, чтобы проблема была решена., как показано в следующем коде:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="list" resultType="com.example.demo.model.User">
select * from user
<where>
<if test="name!=null">
and name=#{name}
</if>
<if test="password!=null">
and password=#{password}
</if>
</where>
</select>
</mapper>
После завершения преобразования кода протестируем все сценарии запроса.
запрос без параметров
На этом этапе мы не можем передавать параметры (запросить все данные), как показано на следующем рисунке:Сгенерированный оператор SQL выглядит следующим образом:
запрос с передачей 1 параметра
Вы также можете передать 1 параметр для запроса на основе имени, как показано на следующем рисунке:Сгенерированный SQL показан на следующем рисунке:Вы также можете запросить только на основе пароля, как показано на следующем рисунке:Сгенерированный SQL показан на следующем рисунке:
запросить передачу 2 параметров
Вы также можете выполнить совместный запрос на основе имени и пароля, как показано на следующем рисунке:Сгенерированный SQL показан на следующем рисунке:
Анализ использования
Мы были приятно удивлены, обнаружив, что после использования тегов, независимо от сценария запроса, это можно легко сделать, передав один или несколько параметров или просто не передав никаких параметров.
Во-первых, по тегу будет судить, если нет параметров, то запрос where не будет склеен в операторе SQL, иначе будет склеен запрос where, во-вторых, в тегах запроса каждый тег может быть добавлен с ключевым словом and MyBatis автоматически удаляет ключевое слово and перед первым условием, чтобы не вызывать синтаксических ошибок SQL, что также объясняется в официальной документации, как показано на следующем рисунке:
Суммировать
В MyBatis рекомендуется избегать использования бессмысленного SQL для сплайсинга, где 1 = 1. Мы можем использовать теги для замены, где 1 = 1. Такой вид написания краток и элегантен, так почему бы не сделать это? Вышеупомянутое содержание является только моим личным мнением, добро пожаловать, чтобы оставить сообщение в области комментариев для обсуждения.
Подпишитесь на официальный аккаунт «Сообщество китайского языка Java», чтобы увидеть больше серий статей о MyBatis и Spring Boot.