Статьи по Теме
Краткое содержание серии MyBatis:Серия MyBatis
предисловие
-
Динамический SQL — одна из мощных функций MyBatis. Если вы использовали JDBC или другие подобные фреймворки, вы должны понимать, насколько болезненно объединять операторы SQL на основе разных условий, например, не забывать добавлять необходимые пробелы при объединении, а также обращать внимание на удаление запятой из имя последнего столбца списка. С помощью динамического SQL эту проблему можно полностью устранить.
-
Над этим предложением официальный сайт MaBatis сказал! Эта статья очень важна! Незаменим в работе!
-
Сначала создадим несколько тестовых библиотек. Следующие примеры построены на этой таблице для тестирования!
-
класс сущности
-
@Data @AllArgsConstructor @NoArgsConstructor public class Blog { private Integer id; private String title; private String autor; private Date creat_time; private Integer reads; }
-
-
С помощью динамических тегов можно написать некоторую базовую логику на xml, то есть sql. Очень удобно и просто в использовании!
-
Создайте некоторые данные для легкого тестирования.
1. если и где теги
-
xml
-
<select id="getBlogInfo" resultType="Blog" parameterType="map"> select * from myblog where 1 = 1 <if test="title!='' and title!=null"> and title like concat(concat('%',#{title}),'%') </if> </select>
-
-
mapper
-
List<Blog> getBlogInfo(Map<String,Object> map);
-
В реальной разработке работы значения, которые мы передаем, обычно используют карту. Это будет удобнее и легче расширять.
-
而返回的result,我们一般使用实体类来实现,因为Swgger,前后端联调无敌方便! ! настоятельно рекомендуется!
-
Если есть небольшой партнер, который хочет узнать swGger, добро пожаловать, чтобы оставить сообщение, блоггер решит, открывать ли отдельное, чтобы объяснить Swgger по мере необходимости. ! !
-
-
Junit Test
-
@Test public void getMyBlog(){ SqlSession session = MybatisUtils.getSession(); MyBlogMapper mapper = session.getMapper(MyBlogMapper.class); Map<String,Object> map = new HashMap<>(); map.put("title","Mybatis"); List<Blog> myBlogMappers = mapper.getBlogInfo(map); for (Blog myBlogMapper : myBlogMappers) { System.out.println(myBlogMapper); } session.close(); }
-
-
Результаты:
- Идеально изолированы.
-
Некоторые люди могут спросить, зачем добавлять этот ярлык?
- Прежде всего, тег if может сделать наш sql более гибким. Если значение этого заголовка передано, оно представляет собой условный запрос. Если оно не передано, это неверный код. Запросить все!
- Тогда реализовать этот эффект в сервисе можно, но очень громоздко. Так что на практике чаще всего используется тег if!
- Наконец, студенты заметили, что в приведенном выше sql
1=1
, зачем писать это?В реальной разработке мы обычно используем мягкое удаление (логическое удаление), поэтому обычно есть флаг удаления, чтобы определить, существуют ли эти данные! Это добавлено исключительно для имитации реального кода разработки!
-
Итак, когда используется тег where?
-
xml
-
<select id="getBlogInfo1" resultType="Blog" parameterType="map"> select * from myblog where <if test="title!='' and title!=null"> title like concat(concat('%',#{title}),'%') </if> <if test="id!='' and id!=null"> and id = #{id} </if> </select>
-
Если наш оператор такой, то если заголовок пустой, эквивалентен ли оператор sql добавлению и непосредственно после где?
-
Демо:
-
@Test public void getMyBlog1(){ SqlSession session = MybatisUtils.getSession(); MyBlogMapper mapper = session.getMapper(MyBlogMapper.class); Map<String,Object> map = new HashMap<>(); map.put("id","2"); List<Blog> myBlogMappers = mapper.getBlogInfo1(map); for (Blog myBlogMapper : myBlogMappers) { System.out.println(myBlogMapper); } session.close(); }
-
Сообщение об ошибке выглядит следующим образом
-
org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'and id = '2'' at line 8 ### The error may exist in com/dy/dynamic/mapper/MyBlogMapper.xml ### The error may involve com.dy.dynamic.mapper.MyBlogMapper.getBlogInfo1-Inline ### The error occurred while setting parameters ### SQL: select * from myblog where and id = ? ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'and id = '2'' at line 8
-
-
-
-
использовать где тег
-
<select id="getBlogInfo1" resultType="Blog" parameterType="map"> select * from myblog <where> <if test="title!='' and title!=null"> title like concat(concat('%',#{title}),'%') </if> <if test="id!='' and id!=null"> and id = #{id} </if> </where> </select>
-
Исполнение
-
Идеальное решение!
-
-
Что делать, если нет условия соответствия? В итоге SQL будет выглядеть так:
-
SELECT * FROM BLOG WHERE
-
-
Это приведет к сбою запроса. Что, если бы было выполнено только второе условие? SQL будет выглядеть так:
-
SELECT * FROM BLOG WHERE AND id = 2
-
Этот запрос также не будет выполнен. Эту проблему нельзя решить просто с помощью условных элементов.
-
-
Роль тега where очевидна!
- Когда условие имеет и, он может определить, является ли условие первым условием, и если оно есть, оно будет автоматически удалено.
- whereЭлемент будет вставлять предложение «WHERE», только если дочерний элемент ничего не возвращает. Кроме того, если предложение начинается с «И» или «ИЛИ»,whereэлементы также удалят их.
-
еслиwhereЭлемент не тот, что вы ожидаете, вы также можете настроить его, настроив элемент обрезки.whereфункцию элемента. Например, иwhereПользовательский элемент обрезки, эквивалентный элементу:
-
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
-
Эта отделка будет рассмотрена позже.
-
Два, выбирай, когда, иначе теги
-
Иногда мы не хотим использовать все условия, а просто хотим использовать одно из нескольких условий. Для этой ситуации MyBatis предоставляет элемент выбора, который немного похож на оператор switch в Java.
-
Если вы закончили, помните ли вы, что есть еще один вид условия суждения?
- Правильно, переключите регистр (в JAVA)
- В динамическом sql выбирают
- Давай сыграем в эту игру
-
xml
-
<select id="getBlogInfoWhoose" resultType="Blog" parameterType="map"> select * from myblog <where> <choose> <when test="title!='' and title!=null"> title like concat(concat('%',#{title}),'%') </when> <when test="id!='' and id!=null"> and id = #{id} </when> <otherwise> AND `reads` > 10000 </otherwise> </choose> </where> </select>
-
-
mapper
-
List<Blog> getBlogInfoWhoose(Map<String,Object> map);
-
-
Junit Test
-
@Test public void getMyBlog1(){ SqlSession session = MybatisUtils.getSession(); MyBlogMapper mapper = session.getMapper(MyBlogMapper.class); Map<String,Object> map = new HashMap<>(); map.put("title","Spring"); List<Blog> myBlogMappers = mapper.getBlogInfoWhoose(map); for (Blog myBlogMapper : myBlogMappers) { System.out.println(myBlogMapper); } session.close(); }
-
-
Результаты
-
Когда условия выбора не выполняются
-
Junit Test
-
@Test public void getMyBlog1(){ SqlSession session = MybatisUtils.getSession(); MyBlogMapper mapper = session.getMapper(MyBlogMapper.class); Map<String,Object> map = new HashMap<>(); // map.put("title","Spring"); List<Blog> myBlogMappers = mapper.getBlogInfoWhoose(map); for (Blog myBlogMapper : myBlogMappers) { System.out.println(myBlogMapper); } session.close(); }
-
-
Результаты
- Таким образом, будут найдены только данные с readis (объемом чтения) более 10 000.
-
-
Суммируйте эти теги
- Для таких ключевых слов, как чтение, вам нужно добавить плавающий знак `
- Если все условия не соблюдены, выводится содержимое в противном случае.
- Элемент when указывает, что когда выполняются условия в when, содержимое выводится.Подобно эффекту переключения в JAVA, порядок соответствует условиям.
Три, обрезать, установить теги
- Так много было сказано выше, все это говорит о select (запросе), поэтому теперь поговорим о тегах в обновлении.
set
- Я не буду здесь повторять основной оператор обновления, вам нужно только обратить внимание на этот динамический оператор. В реальной работе разработка вообще такая, ведь она более гибкая!
①、установить метку
-
xml
-
<update id="updateBlogName" parameterType="map"> update myblog <set> <if test="title!=null and title!=''"> title = #{title}, </if> <if test="autor!=null and autor!=''"> autor = #{autor}, </if> <if test="reads!=null and reads!=''"> `reads` = #{reads} </if> </set> where id = #{id} </update>
-
-
mapper
-
Integer updateBlogName(Map<String,Object> map);
-
-
Junit Test
-
@Test public void updateBlogName(){ SqlSession session = MybatisUtils.getSession(); MyBlogMapper mapper = session.getMapper(MyBlogMapper.class); Map<String,Object> map = new HashMap<>(); map.put("id","3"); map.put("title","富婆让我陪她逛街"); map.put("autor","大大大大鱼"); map.put("reads","100000"); Integer num = mapper.updateBlogName(map); System.out.println("一共更新了:"+num+"条数据"); session.commit();//更新不要忘记提交事务哦 session.close(); }
-
-
Результаты
-
Вы заметили, что мы пишем запятую после оператора set to death в sql?
-
Ну, если мы просто пройдем
title
иautor
Шерстяная ткань? -
Теоретически разве это не утверждение?
-
update myblog set title = #{title}, autor = #{autor}, where id = #{id}
-
-
давайте попробуем
-
Обновление прошло успешно, оригинал
set
этикетки иwhere
Как лейбл, такой умный! -
set
Метка может автоматически помочь мне определить запятую в конце инструкции и обработать ее! -
Является ли оператор sql, который мы пишем, более гибким? Очень удобно и просто в использовании!
②, декоративная этикетка
-
Из приведенного выше примера мы знаем, что
where
,set
Теги могут удалять запятые , и , или такие соединители. -
trim
Этикетки тоже могут! -
xml
-
<insert id="insertBlogName" parameterType="map"> insert into myblog ( <if test="title!=null and title!=''"> title, </if> <if test="autor!=null and autor!=''"> autor, </if> <if test="reads!=null and reads!=''"> `reads`, </if> <if test="creat_time!=null"> `creat_time` </if> ) values( <if test="title!=null and title!=''"> #{title}, </if> <if test="autor!=null and autor!=''"> #{autor}, </if> <if test="reads!=null and reads!=''"> #{reads}, </if> <if test="creat_time!=null"> #{creat_time} </if> ) </insert>
-
-
mapper
-
Integer insertBlogName(Map<String,Object> map);
-
-
Junit Test
-
@Test public void insetBlogInfo(){ SqlSession session = MybatisUtils.getSession(); MyBlogMapper mapper = session.getMapper(MyBlogMapper.class); Map<String,Object> map = new HashMap<>(); map.put("title","如何榜上富婆?"); map.put("autor","大鱼"); map.put("reads","1000"); map.put("creat_time",new Date()); Integer num = mapper.insertBlogName(map); System.out.println("一共新增了:"+num+"条数据"); session.commit(); session.close(); }
-
-
Результаты
-
Помните, что session.commit(); для отправки транзакции~
-
Если мы не пропустим весь этот sql, не возникнут ли вышеперечисленные проблемы? Это несколько запятых, которые вызывают ошибки выполнения sql?
-
мы можем использовать
trim
теги для завершения автоматического удаления запятых и других соединителей -
XML-преобразование
-
<insert id="insertBlogName1" parameterType="map"> insert into myblog <trim prefix="(" suffix=")" suffixOverrides=","> <if test="title!=null and title!=''"> title, </if> <if test="autor!=null and autor!=''"> autor, </if> <if test="reads!=null and reads!=''"> `reads`, </if> <if test="creat_time!=null"> `creat_time` </if> </trim> <trim prefix="values(" suffix=")" suffixOverrides=","> <if test="title!=null and title!=''"> #{title}, </if> <if test="autor!=null and autor!=''"> #{autor}, </if> <if test="reads!=null and reads!=''"> #{reads}, </if> <if test="creat_time!=null"> #{creat_time} </if> </trim> </insert>
-
Результаты
-
Идеальное решение проблемы!
-
Ключевой анализ
- префикс: что нужно добавить в начале
- суффикс: добавить обязательно в конец
- suffixOverrides: что нужно добавить в конце каждого оператора строки
- prefixOverrides: что нужно добавить в начале каждой строки оператора
-
будь осторожен
-
Когда в базе данных установлено время datetime, мы
if
Не судите, что ярлык не пустой -
Просто нужно судить, что это не null
-
-
В-четвертых, тег foreach
-
Каково это писать цикл for в sql?
-
Давайте сыграем требование: запросите данные блога с идентификаторами 1, 2, 4 и 5.
-
Узнал здесь, не используйте это и это
捞
письма.-
select * from myblog where id = 1 or id = 2 or id = 4 or id = 5
①, foreach простое использование
-
-
xml
-
<select id="getBlogInfos" parameterType="map" resultType="Blog"> select * from myblog <where> <foreach collection="ids" item="id" open="and (" close=")" separator="or"> id=#{id} </foreach> </where> </select>
-
-
mapper
-
List<Blog> getBlogInfos(Map<String,Object> map);
-
-
Junit Test
-
@Test public void getBlogInfos(){ SqlSession session = MybatisUtils.getSession(); MyBlogMapper mapper = session.getMapper(MyBlogMapper.class); Map<String,Object> map = new HashMap<>(); List<String> ids = new ArrayList<>(); ids.add("1"); ids.add("2"); ids.add("4"); ids.add("5"); map.put("ids",ids); List<Blog> list = mapper.getBlogInfos(map); for (Blog blog : list) { System.out.println(blog); } session.close(); }
-
-
Результаты
-
тег foreach
- коллекция: это коллекция, которую нам нужно пройти по метке, то есть ключ, помещенный в карту.
- item : Ключ, который мы назначаем пройденному значению
- open : параметры добавлены в начале
- close : закрыть добавленный параметр
- разделитель: параметр добавляется в середине каждого значения
②, где с использованием foreach
-
xml
-
<select id="getBlogInfos1" parameterType="map" resultType="Blog"> select * from myblog <where> id in <foreach collection="ids" item="id" open="(" close=")" separator=","> #{id} </foreach> </where> </select>
-
-
Не нужно менять в другом месте
-
Окончательный эффект от этого
-
select * from myblog WHERE id in ( ? , ? , ? , ? )
-
-
Просто чтобы перечислить эти два примера, как их использовать, зависит от конкретных потребностей.
-
Длина sql ограничена, и если в этом id слишком много значений, он не может быть запрошен.
-
Максимальная длина sql: максимальная длина конкатенации SQL по умолчанию составляет 2000 параметров.
Пять, sql, включить теги
-
Поиграв с таким количеством тегов выше, вы обнаружите проблему, то есть в одном и том же бизнесе может быть много дублирующегося контента, например, каждый запрос имеет
title
,autor
и так далее. -
Итак, есть ли у нас метод, похожий на класс инструмента в java?
-
В настоящее время нам нужно использовать наш sql и включать теги~
-
xml
-
<sql id="if-key-info"> <if test="title!=null and title!=''"> title = #{title} </if> <if test="autor!=null and autor!=''"> and autor = #{autor} </if> <if test="reads!=null and reads!=''"> and `reads` = #{reads} </if> </sql> <select id="getBlogInfo" resultType="Blog" parameterType="map"> select * from myblog <where> <include refid="if-key-info"></include> </where> </select>
-
Результаты
-
С этим мы можем собрать то же самое, разве это не намного удобнее?
-
sql id= "" : Именование здесь произвольное, если оно уникально в текущем mapper.xml.
-
Включите: просто обратитесь к вышеупомянутым именам!
-
Впереди долгий путь, и я обязательно буду его искать вдоль и поперёк~
Если вы думаете, что я блогеры хорошо пишу! Писать нелегко, пожалуйста, ставьте лайки, подписывайтесь и комментируйте, чтобы поощрять блоггеров ~ хахах