问题: 什么是动态SQL? 动态SQL有什么作用?
传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题,
其通过 if, choose, when, otherwise, trim, where, set, foreach,可组合成非常灵活的SQL语句,从而提高开发人员的效率。
下述可知道select、insert、update、delete四个操作节点中的标签都是差不多是一样的,insert和update中多了一个selectKey节点(后面会详细的说到),下面介绍一下这些节点的用法:(下述4个标签是<mapper/>节点的子节点)
1. if: 判断
在mybatis中也能用 if :(if标签没有属性)
if节点的test属性是取的参数对象中的成员变量名
1、编写数据访问接口(要创建实体类的哟,这里就不截图了)
2、映射文件中编写:
3、编写测试类:
上面例子: 如果传入的managerAccount 不为空, 那么SQL才拼接managerAccount = #{managerAccount}
下面的代码是要么提供managerAccount 要么提供managerName查询
<if test="managerAccount != null">
managerAccount=#{managerAccount}
</if>
<if test="managerName != null">
managerName=#{managerName}
</if>
那如果我要两个条件都提供才能查询呢?这个时候就可以用and符号来进行拼接:
<if test="managerAccount ! =null">
managerAccount=#{managerAccount}
</if>
<if test="managerName ! =null">
and managerName=#{managerName}
</if>
如果managerAccount不等于空的时候才会执行managerName,如果managerAccount等于空就不会执行managerName,就不能实现需要两个条件才能查询同样单个给定条件也不能查询了。
这个时候就有问题,那传过去的参数为空怎么办?
这时候,mybatis的 where 标签的作用就来了
2、where(where标签没有属性)
这个<where/>标签就告诉我们说看我们的连接运算符,当然你也可以用or'连接,如果查询条件managerAccount是第一个那就会把managerName前面的and符号去掉(去掉之后语句为:select managerAccount,password,managerName from tb_Manager where managerAccount=字段值 and managerName=字段值,因为where后面是不能跟and或者or的),如果查询managerName为第一个那么就会把managerAccount前面的and符号就会去掉。那就可以实现我给两个条件也可以查询,给一个条件也可以查询。如果一个条件都不给,那sql语句中条件关键字where就没有,就会直接执行“ select managerAccount,password,managerName from tb_Manager ” 这条语句。从表面上来看,就是多了个where标签而已, 不过实质上, mybatis是对它做了处理,当它遇到AND或者OR这些,它知道怎么处理。
<where/>标签的作用
1、在使用where标签时,如果没有给条件,SQL语句中的条件关键字where就没有。
2、如果该节点中有条件,则在SQL语句后加上where关键字,以组装条件sql语句
3、在编写条件时,如果有多个的话,多个之间的逻辑运算符一定写在条件的前面,这个标签在执行时,会去掉第一个条件前面的逻辑运算符。
3、 foreach:
java中有for, 可通过for循环, 同样, mybatis中有foreach, 可通过它实现循环,循环的对象当然主要是java容器和数组。
大家应该I都知道查询主键的sql语句是:select * from 表名 where 字段名 in (字段名的值);
foreach标签有6个属性:
collection:表示集合
close:表示结束符
index:表示次序
item:表示集合中的一项
open:表示开始符
separator:表示各项的分隔符
1、在映射文件中编写:我写的语句是通过账号查询,你也可以换成其它字段名验证。
上述 collection=“list” 里面的list,是需要到你写的实体中去添加list这个实体,如下图:
tem="it" 表示你这个集合中的某一项,就是命名。
open="(" :表示你开始的符号为“(”。
separator="," 表示各项的分隔符为“,”。
close=")":表示你结束的符号为“)”
就是拼接sql语句,执行拼接出来的语句是select * from tb_manager where managerAccount in (字段名/主键值,字段名/主键值,.........);
将一个 List 实例或者数组作为参数对象传给 MyBatis,当这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。
2、编写测试类:
4、bind标签
bind标签属性
name属性:表示绑定之后要使用的名称。相当于创建了一个变量,变量名由name属性给出。
value属性:表示绑定时的值
bind标签可以看成是定义一个变量,变量的名称由name属性指定,变量的值由value属性指定
该标签没有子标签
应用场景:使用用户名进行模糊查询
模糊查询,在SQL中的通配符:
%:表示匹配任意多个字符
?:表示匹配0个或1个字符
查询用户名中包涵“o”字母的用户: %o%
select * from tb_user where managerAccount like ‘%o%’;
1、映射文件中编写:
<bind/>标签中的value属性中通过_parameter来获取getManagerAccount,前后加上%以组装sql语句,其中的_parameter是固定的,来获取参数。
2、编写测试接口:查询数据库表中ManagerAccout字段名中值带有“m”字母的数据。
5、set
set标签的作用其实就跟<where/>标签类似,但不代表where就是set哟
1、mapper中编写:
如果我提供通过id修改管理员姓名,拼接的sql语句将是 update to _manager set managerName where managerid=?
2、测试:
6、trim和include
trim节点的属性:
prefix:前缀
prefixOverrides:前缀覆盖
suffix:后缀
suffixOverrides:后缀覆盖
trim一般用在<select/>和<update/>标签中,可代替<where/>标签,但是该标签是比where节点更加复杂的SQL
1、
2、下面图中,同时用了<include/>标签,同时也用了<sql/>,
sql标签的作用:
就是拼接一个可重用的SQL语句。
在<sql/>标签中定义了sql语句之后,后面用<include/>标签参考<sql/>标签中id属性的值,效果和你直接在select标签中写sql语句是一样的。