MyBatis-动态SQL
(1)极大的简化拼装SQL的操作。
(2)动态SQL 元素和使用JSTL 或其他类似基于XML 的文本处理器相似。
(3)MyBatis 采用功能强大的基于OGNL 的表达式来简化操作。
通过以下标签实现动态SQL:
1.if:判断
例如1:实现动态筛选查询,根据单个或多个条件:员工id,姓名,部门…
实现接口:public List getEmpByConditions(Employee conditions);
<select id="getEmpByConditions" resultType="com.mybatis.entity.Employee">
select * from test
<where>
<if test="id != null">
id=#{id}
</if>
<if test="last_name != null and last_name !=''">
and last_name like CONCAT(CONCAT('%', #{last_name}), '%')
</if>
<if test="email !=null and email.trim()!=null">
and email = #{email}
</if>
<!-- <if test="gender=='M'.toString() or gender=='F'.toString()"> -->
<if test='gender =="M" or gender =="F"'>
and gender = #{gender}
</if>
</where>
</select>
例如2:实现动态更新,指定修改单个或多个属性:员工id,姓名,部门…
实现接口:public void updateByConditions(Employee employee);
<update id="updateByConditions">
update test
<set>
<if test="last_name!=null and last_name !='' ">
last_name = #{last_name},
</if>
<if test='gender=="F" or gender =="M" '>
gender = #{gender},
</if>
<if test="email!=null and email !='' ">
email = #{email}
</if>
</set>
where id= #{id}
</update>
注意:(1)两个字符串比较是否相等
<if test="gender=='M'.toString() or gender=='F'.toString()">
或者
<if test=' gender =="M" or gender =="F" '>
and gender = #{gender}
</if>
(2)关于字符串与数字的比较
ognl会进行字符串与数字的转换判断 “0”==0
<if test=" gender==0 or gender==1 ">
and gender=#{gender}
</if>
(3)判断字符串是否为空
<if test=" last_name != null and last_name !='' ">
and last_name like CONCAT(CONCAT('%', #{last_name}), '%')
</if>
或者
<if test=" email !=null and email.trim()!=null ">
and email = #{email}
</if>
(4)查询的时候如果某些条件没带可能sql拼装会有问题
1、给where后面加上1=1,以后的条件都and xxx.
<select id="getEmpByConditions" resultType="com.mybatis.entity.Employee">
select * from test where and 1=1
<if>and ...</if>
2、mybatis使用where标签来将所有的查询条件包括在内。mybatis就会将where标签中拼装的sql,多出来的and或者or去掉.但是where只会去掉第一个多出来的and或者or。
<select id="getEmpByConditions" resultType="com.mybatis.entity.Employee">
select * from test
<where>
<if>and...</if>
<if>and ...</if>
<where>
3.使用trim标签自定义字符串的截取规则
<select id="getEmpByConditions" resultType="com.mybatis.entity.Employee">
select * from test
<trim prefix="where" suffixOverrides="and">
<!--prefix给拼串后的整个字符串加一个前缀 where,suffixOverrides去掉整个字符串后面多 余的字符and-->
<if >...and</if>
<if >...and</if>
</trim>
</select>
2.trim 字符串截取(where(封装查询条件), set(封装修改条件))
trim标签体中是整个字符串拼串后的结果
- prefix="":前缀prefix给拼串后的整个字符串加一个前缀
- prefixOverrides="":前缀覆盖: 去掉整个字符串前面多余的字符
- suffix="":后缀suffix给拼串后的整个字符串加一个后缀
- suffixOverrides=""后缀覆盖:去掉整个字符串后面多余的字符 例如1:实现动态筛选查询,根据单个或多个条件:员工id,姓名,部门…
实现接口:public List getEmpByConditionsTrim(Employee employee);
<select id="getEmpByConditionsTrim" resultType="com.mybatis.entity.Employee">
select * from test
<!-- 自定义字符串的截取规则 -->
<trim prefix="where" suffixOverrides="and">
<if test="id != null">
id=#{id} and
</if>
<if test="last_name != null and last_name !=''">
last_name like CONCAT(CONCAT('%', #{last_name}), '%') and
</if>
<if test="email !=null and email.trim()!=null">
email = #{email} and
</if>
<if test='gender =="M" or gender =="F"'>
gender = #{gender} and
</if>
</trim>
</select>
例如2:实现动态更新,指定修改单个或多个属性:员工id,姓名,部门…
实现接口:public void updateByConditionsTrim(Employee employee);
<update id="updateByConditionsTrim">
update test
<trim prefix="set" suffixOverrides=",">
<if test="last_name!=null and last_name !='' ">
last_name = #{last_name},
</if>
<if test='gender=="F" or gender =="M" '>
gender = #{gender},
</if>
<if test="email!=null and email !='' ">
email = #{email},
</if>
</trim>
where id= #{id}
</update>
3.choose (when, otherwise):分支选择;
choose标签形式:(类似于带break的switch-case)
<choose>
<when test="">...</when>
<when test="">...</when>
<otherwise>..</otherwise>
</choose>
注意:如果带了id就用id查,如果带了lastName就用lastName查;同时满足多个条件时,只会进入其中一个分支
例如:实现动态筛选查询,根据单个或多个条件:员工id,姓名,部门…
实现接口:public List getEmpByConditionsChoose(Employee employee);
<select id="getEmpByConditionsChoose" resultType="com.mybatis.entity.Employee">
select * from test
<where>
<choose>
<when test="id != null">
id=#{id}
</when>
<when test="last_name != null and last_name !=''">
last_name like CONCAT(CONCAT('%', #{last_name}),'%')
</when>
<when test="email !=null and email.trim()!=null">
email = #{email}
</when>
<when test=' gender=="M" or gender=="F" '>
gender = #{gender}
</when>
<!-- <otherwise>gender = #{gender}</otherwise> -->
</choose>
</where>
</select>
注意:1.可选是否存在 2.不能加test条件
4.foreach 遍历集合
foreach标签中属性:
- collection:指定要遍历的集合:list类型的参数会特殊处理封装在map中,map的key就叫list
- item:将当前遍历出的元素赋值给指定的变量
- separator:每个元素之间的分隔符
- open:遍历出所有结果拼接一个开始的字符
- close:遍历出所有结果拼接一个结束的字符
- index:索引。
遍历list的时候是index就是索引,item就是当前值,遍历map的时候index表示的就是map的key,item就是map的值标签体中:
#{变量名}就能取出变量的值也就是当前遍历出的元素
例如:动态查询:同时传入多个id,根据id查询员工信息
实现接口:public List getEmpByIdsForeach(@Param(“empIds”)List empIds);
<select id="getEmpByIdsForeach" resultType="com.mybatis.entity.Employee">
select * from test where id in
<foreach collection="empIds" item="item_id" separator="," open="(" close=")">
#{item_id}
</foreach>
</select>
注意:1.接口参数需要使用@Param(“empIds”)为参数命名,否则 collection="empIds"会出现not found错误,原因未知