架构师大咖
架构师大咖,打造有价值的架构师交流平台。分享架构师干货、教程、课程、资讯。架构师大咖,每日推送。 一、MyBatis动态 sql 是什么 动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。
例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。
动态SQL(code that is executed dynamically),它一般是根据用户输入或外部条件动态组合的SQL语句块。动态SQL能灵活的发挥SQL强大的功能、方便的解决一些其它方法难以解决的问题。相信使用过动态SQL的人都能体会到它带来的便利,然而动态SQL有时候在执行性能 (效率)上面不如静态SQL,而且使用不恰当,往往会在安全方面存在隐患 (SQL 注入式攻击)。
1.Mybatis 动态 sql 是做什么的? Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。
2.Mybatis 的 9 种 动 态 sql 标 签有哪些? 3.动态 sql 的执行原理? 原理为:使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。
推荐一个开源免费的 Spring Boot 实战项目:
https://github.com/javastacks/spring-boot-best-practice
二、MyBatis标签 1.if标签:条件判断 MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。
1)不使用动态sql
"selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User" > select * from user where username=#{username} and sex=#{sex}
if 语句使用方法简单,常常与 test 属性联合使用。语法如下:
<if test ="判断条件" > SQL语句if>
2)使用动态sql
上面的查询语句,我们可以发现,如果#{username}
为空,那么查询结果也是空,如何解决这个问题呢?使用 if 来判断,可多个 if 语句同时使用。
以下语句表示为可以按照网站名称(name)或者网址(url)进行模糊查询。如果您不输入名称或网址,则返回所有的网站记录。但是,如果你传递了任意一个参数,它就会返回与给定参数相匹配的记录。
"selectAllWebsite" resultMap="myResult" > select id,name,url from website where 1=1 <if test ="name != null" > AND name like #{name} if> <if test ="url!= null" > AND url like #{url} if>
2.where+if标签 where、if同时使用可以进行查询、模糊查询
注意,
失败后,
关键字只会去掉库表字段赋值前面的and,不会去掉语句后面的and关键字,即注意,
只会去掉
语句中的最开始的and关键字。所以下面的形式是不可取的
"findQuery" resultType="Student" > "selectvp"/> <where > <if test ="sacc != null" > sacc like concat('%' #{sacc} '%') if> <if test ="sname != null" > AND sname like concat('%' #{sname} '%') if> <if test ="sex != null" > AND sex=#{sex} if> <if test ="phone != null" > AND phone=#{phone} if> where>
这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
另外,如果你近期准备面试跳槽,建议在 Java面试库 小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。 3.set标签 set可以用来修改
4.choose(when,otherwise) 语句 有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句
也就是说,这里我们有三个条件,id、username、sex,只能选择一个作为查询条件
如果 id 不为空,那么查询语句为:select * from user where id=?
如果 id 为空,那么看username 是否为空,如果不为空,那么语句为select * from user where username=?;
如果 username 为空,那么查询语句为select * from user where sex=?
5.trim trim标记是一个格式化的标记,可以完成set或者是where标记的功能
①、用 trim 改写上面第二点的 if+where 语句
"selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User" > select * from user "where" prefixOverrides="and | or" > <if test ="username != null" > and username=#{username} if> <if test ="sex != null" > and sex=#{sex} if>
prefixoverride:去掉第一个and或者是or ②、用 trim 改写上面第三点的 if+set 语句
suffixoverride:去掉最后一个逗号(也可以是其他的标记,就像是上面前缀中的and一样) 另外,如果你近期准备面试跳槽,建议在 Java面试库 小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。 ③、trim+if同时使用可以添加
6.MyBatis foreach标签 foreach是用来对集合的遍历,这个和Java中的功能很类似。通常处理SQL中的in语句。
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符
你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
整合案例 推荐一个开源免费的 Spring Boot 实战项目:
https://github.com/javastacks/spring-boot-best-practice
xml
"1.0" encoding="UTF-8" ?> PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >"com.yzx.mapper.StuMapper"> "selectvp"> select * from student "find" resultType="Student" > "selectvp"/> "findbyid" resultType="student" > "selectvp"/> WHERE 1=1 <if test ="sid != null" > AND sid like #{sid} if> "findQuery" resultType="Student" > "selectvp"/> <where > <if test ="sacc != null" > sacc like concat('%' #{sacc} '%') if> <if test ="sname != null" > AND sname like concat('%' #{sname} '%') if> <if test ="sex != null" > AND sex=#{sex} if> <if test ="phone != null" > AND phone=#{phone} if> where> "upd"> update student <set > <if test ="sname != null" >sname=#{sname}, <if test ="spwd != null" >spwd=#{spwd}, <if test ="sex != null" >sex=#{sex}, <if test ="phone != null" >phone=#{phone} sid=#{sid} set> where sid=#{sid} "add"> insert into student "(" suffix=")" suffixOverrides="," > <if test ="sname != null" >sname,if> <if test ="spwd != null" >spwd,if> <if test ="sex != null" >sex,if> <if test ="phone != null" >phone,if> "values (" suffix=")" suffixOverrides="," > <if test ="sname != null" >#{sname}, <if test ="spwd != null" >#{spwd}, <if test ="sex != null" >#{sex}, <if test ="phone != null" >#{phone} "findAll" resultType="Student" parameterType="Integer" > "selectvp"/> WHERE sid in "ids" collection="array" open="(" separator="," close=")" > #{ids} "del" parameterType="Integer" > delete from student where sid in "ids" collection="array" open="(" separator="," close=")" > #{ids}
测试类:
7.sql 在实际开发中会遇到许多相同的SQL,比如根据某个条件筛选,这个筛选很多地方都能用到,我们可以将其抽取出来成为一个公用的部分,这样修改也方便,一旦出现了错误,只需要改这一处便能处处生效了,此时就用到了
这个标签了。
当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。为求结构清晰也可将 sql 语句分解。"selectvp"> select * from student8.include这个标签和是天仙配,是共生的,include用于引用sql标签定义的常量。比如引用上面sql标签定义的常量refid这个属性就是指定标签中的id值(唯一标识)"findbyid" resultType="student"> "selectvp"/> WHERE 1=1 AND sid like #{sid} if>
9.如何引用其他XML中的SQL片段 比如你在com.xxx.dao.xxMapper
这个Mapper的XML中定义了一个SQL片段如下:
"Base_Column_List"> ID,MAJOR,BIRTHDAY,AGE,NAME,HOBBY
此时我在com.xxx.dao.PatinetMapper
中的XML文件中需要引用,如下:
"com.xxx.dao.xxMapper.Base_Column_List">
三、MyBatis关联查询 1.MyBatis一对多关联查询
"myStudent1" type ="student1" > "sid" column="sid" /> "sname" column="sname" /> "sex" column="sex" /> "sage" column="sage" /> "list" ofType="teacher" > "tid" column="tid" /> "tname" column="tname" /> "tage" column="tage" /> "find1" resultMap="myStudent1" > select * from student1 s left join teacher t on s.sid=t.sid
2.MyBatis多对一关联查询
"myTeacher" type ="teacher" > "tid" column="tid" /> "tname" column="tname" /> "tage" column="tage" /> "student1" javaType="Student1" > "sid" column="sid" /> "sname" column="sname" /> "sex" column="sex" /> "sage" column="sage" /> "find2" resultMap="myTeacher" > select * from teacher t right join student1 s on t.sid=s.sid
3.MyBatis多对多关联查询
"find3" resultMap="myStudent1" > select * from student1 s left join relevance r on s.sid=r.sid left join teacher t on r.tid=t.tid
Python入门到精通
Python入门到精通:人生苦短,我用Python!Python每日推送、Python教程、Python资料、Python视频、Python项目、Python学习等。