一、基本概念
- 动态SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作。动态SQL元素的使用和使用JSTL或其他类似基于XML的文本处理器相似。
- MyBatis采用功能强大的基于OGNL的表达式来简化操作。包括if、choose (when, otherwise)、trim (where, set)、foreach。
二、基本使用
1. if标签的使用
<!-- if 判断-->
<!-- 查询员工,要求携带了哪个字段查询条件,就带上哪个字段的值 -->
<!-- public List<Employee> getEmpByCoditionIf(Employee employee); -->
<select id="getEmpByCoditionIf" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
<!-- where -->
<where>
<!-- test:判断表达式(OGNL) OGNL表达式的使用参照PPT或官方文档 ,它是从参数中取值进行判断的 ,遇见特殊符号应该写转义字符-->
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null && lastName!=""">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=""">
and email=#{email}
</if>
<!-- OGNL会进行字符串与数字的转换判断 -->
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</where>
</select>
<if>
的使用说明:<if>
标签可以根据传入的条件来动态的生成SQL语句,我们只需要在<if>
标签的test
属性上写入条件,并在标签内部写入需要根据条件添加的语句即可。<if>
标签可以直接跟在where
关键字之后,也可以放在其他的标签内部。
2. where标签的使用
<where>
的使用说明: 我们可以将<if>
标签放在<where>
标签的内部,<where>
主要是用来防止动态生成SQL语句时,由于拼接顺序问题,导致SQL语句中出现多余的and
和or
关键字。<where>
会且只会去掉组合成的SQL语句中第一项前面多出来的and
或者or
关键字,因此这就要求我们的拼接的SQL条件句要把and
或者or
关键字写在每个条件的最前面。
3. trim标签的使用
<!-- 查询员工,要求携带了哪个字段查询条件,就带上哪个字段的值 -->
<!-- public List<Employee> getEmpByCoditionTrim(Employee employee); -->
<select id="getEmpByCoditionTrim" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
<!-- trim标签体中是整个字符串拼串后的结果 -->
<!--
prefix:前缀,给拼串后的整个字符串加一个前缀
prefixOverrides:前缀覆盖,去掉整个字符串前面多余的字符
suffix:后缀,给拼串后的整个字符串加一个后缀
suffixOverrides:后缀覆盖,去掉整个字符串后面多余的字符
-->
<!-- 后面多出的and或者or where标签解决不了 -->
<!-- 自定义截取字符串的规则 -->
<trim prefix="where" suffixOverrides="and">
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null && lastName!=""">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=""">
email=#{email} and
</if>
<if test="gender==0 or gender==1">
gender=#{gender}
</if>
</trim>
</select>
<trim>
标签的使用说明:可以将<if>
标签放入<trim>
标签的内部,同样可以通过相应设置动态的根据条件得到SQL语句,<trim>
标签包含四个属性:prefix
代表前缀,给拼串后的整个字符串加一个前缀;prefixOverrides
代表前缀覆盖,去掉整个字符串前面多余的字符;suffix
代表后缀,给拼串后的整个字符串加一个后缀;suffixOverrides
代表后缀覆盖,去掉整个字符串后面多余的字符。
4. choose标签的使用
<!-- choose(when otherwise) 分支选择,带了break的switch-case -->
<!-- 如果带了id就用id查,如果带了lastName就用lastName查,只会进入其中一个(同时带多个只会进入第一个) -->
<!-- public List<Employee> getEmpByCoditionChoose(Employee employee); -->
<select id="getEmpByCoditionChoose" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="lastName!=null">
last_name like #{lastName}
</when>
<when test="email!=null">
email = #{email}
</when>
<otherwise>
gender = 0
</otherwise>
</choose>
</where>
</select>
<choose>
标签的使用说明:<choose>
标签要和<when>
标签与<otherwise>
标签联合使用,<when>
标签内部书写可能拼接的语句,<when>
标签的test
属性用于指定拼接需要满足的条件,<otherwise>
标签内部书写可能拼接的语句。
5. set标签的使用
<!-- 更改员工信息,传入了哪个参数就更改哪个参数 -->
<!-- public void updateEmp(Employee employee); -->
<update id="updateEmp">
update tbl_employee
<!-- set标签 -->
<!--
<set>
<if test="lastName!=null">
last_name = #{lastName},
</if>
<if test="email!=null">
email=#{email},
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</set>
-->
<!-- trim标签 -->
<trim prefix="set" suffixOverrides=",">
<if test="lastName!=null">
last_name = #{lastName},
</if>
<if test="email!=null">
email=#{email},
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</trim>
where id = #{id}
</update>
<set>
标签的使用说明:<set>
标签使用在修改语句中,其具体使用见上述样例即可,该标签可以自动去除语句中多出的,
,该标签可以使用<trim>
标签进行替换,同样见上述样例。
6. foreach标签的使用
<!-- foreach -->
<!-- 遍历实现查询数据 -->
<!-- public List<Employee> getEmpByConditionForeach(@Param("ids") List<Integer> ids); -->
<select id="getEmpByConditionForeach" resultType="com.atguigu.mybatis.bean.Employee">
<!-- select * from tbl_employee where id in (1,2,3) -->
select * from tbl_employee
<!--
collection:指定要遍历的集合,list类型的参数会特殊处理封装在map中,map的key就叫list
item:将遍历出的元素赋值给指定的变量
separator:每个元素之间的分隔符
open:遍历出的所有结果拼接一个开始的字符
close:遍历出的所有结果拼接一个结束的字符
index:遍历list的时候index就是索引,item就是当前值;遍历map的时候index就是map的key,item就是map的值
#{变量名}:可以取出变量的值也就是当前遍历出的元素
-->
<foreach collection="ids" item="item_id" separator="," open="where id in(" close=")">
#{item_id}
</foreach>
</select>
<!-- 遍历实现批量添加数据 -->
<!-- public void addEmps(@Param("emps") List<Employee> emps); -->
<!-- MySQL下批量保存可以foreach遍历,mysql支持values(),(),()语法 -->
<!-- 方式一 -->
<insert id="addEmps">
insert into tbl_employee(last_name,email,gender,d_id)
values
<foreach collection="emps" item="emp" separator=",">
(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
</foreach>
</insert>
<!-- 方式二: 需要在jdbc的配置文件中配置数据库连接属性allowMultiQueries为true(在一条语句中允许使用";"来分隔多条查询)->
<insert id="addEmps">
<foreach collection="emps" item="emp" separator=";">
insert into tbl_employee(last_name,email,gender,d_id)
values(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
</foreach>
</insert>
<foreach>
标签的使用说明:见上述样例即可。