那么,问题来了: 什么是动态SQL? 动态SQL有什么作用?
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。
拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。
Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,不仅提高开发人员的效率,而且可以摆脱这种痛苦。
下面就去感受Mybatis动态SQL的魅力吧。
【if】 你们能判断,我也能判断!
作为程序猿,谁不懂 if ! 在mybatis中也能用 if 啦
【where】 有了我,SQL语句拼接条件神马的都是浮云!
【tirm】 我的地盘,我做主!
【set】信我,不出错!
【foreach】你有for, 我有foreach, 不要以为就你才屌!
【choose】我选择了你,你选择了我!
[sql]
<< span="">select id="selectUserList" resultType="com.shop.domain.User" parameterType="com.shop.domain.User" >SELECT * from tb_user where << span="">if test="name!=null and name!=''"> `name` LIKE #{name}if><< span="">if test="age!=null and age!=0"> and age = #{age}if>select> |
---|
lIf标签的test属性中的判断条件的名称必须要和用户传入的占位符中 #{变量名}保持一致
否则
l字符串的判断 除了判断 String 变量名 = null 还应该判断 String 变量名 = “”,因为空字符串,在sql语句中也会被当做条件去进行查询
思考:以上程序代码是否完美呢?
<< span="">select id="selectUserList" resultType="com.shop.domain.User" parameterType="com.shop.domain.User" >SELECT * from tb_user << span="">where><< span="">if test="name!=null and name!=''"> `name` LIKE #{name}if><< span="">if test="age!=null and age!=0"> and age = #{age}if>where> |
---|
Where 标签作用:
1.会帮你自动添加上一个大写的WHERE
2.会自动剔除多余的and 或者or
【思考】:如果用户角色id也不传,那么会怎么样呢?
最终生成的sql语句
lIf标签主要用于根据用户是否传入条件,根据条件动态拼接指定的sql语句
lWhere会在我们写where标签的地方帮我们添加一个where关键字
lWhere 会根据条件自动帮我们剔除多余的and或者or关键字
lIf可以单独使用,where也可以单独使用
l但是开发中单独使用where情况很少,意义不大,都是使用if+where组合
【需求】:根据用户的id来修改用户的个人信息
更新数据前:
更新数据后:
思考:对于以上问题该如何解决呢?
<< span="">update id="updateUserById" parameterType="com.shop.domain.User"> UPDATE tb_user SET << span="">if test="name!=null and name!=''">`name` = #{name},if> << span="">if test="age!=null and age!=0">age = #{age}if> WHERE id = #{id} update> |
---|
Mapper文件如下:
<< span="">update id="updateUserById" parameterType="com.shop.domain.User"> UPDATE tb_user << span="">set> << span="">if test="name!=null and name!=''">`name` = #{name},if> << span="">if test="age!=null and age!=0">age = #{age}if> set> WHERE id = #{id} update> |
---|
控制台sql语句如下:
数据库表中数据前后对比:
【小结】:
1.set标签会自动帮你处理多余的 逗号分隔符
2.set标签会自动帮我们添加一个SET关键字
【思考】:如果是每一个字段后面的逗号分隔符都去掉了,set能不能帮我们处理吗?
Prefix 前缀 ,在开头加上什么关键字 where set
Suffix 后缀 ,在末尾加上什么关键字 and or
suffixOverrides 动态去除末尾的多余的分隔符
prefixOverrides 动态去除前面的多余的分隔符
有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为 true,就会执行 if 标签中的条件。MyBatis 提供了 choose 元素。if标签是与(and)的关系,而 choose 是或(or)的关系。
choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
<< span="">select id="selectUserList2" resultType="com.shop.domain.User" parameterType="com.shop.domain.User"> SELECT * from tb_user << span="">where> << span="">choose> << span="">when test="name!=null and name!=''"> and `name` LIKE #{name} when> << span="">when test="age!=null and age!=0"> and age = #{age} when> << span="">otherwise> and gender =#{gender} otherwise> choose> where> select> |
---|
lIf标签根据条件是否为true,动态拼接sql,choose也一样
lIf标签中如果有多个条件,并且多个条件都满足,那么if会将这些条件都拼接上
l,形成一个and的关系,如果都不成立,就不拼接任何条件。
lchoose标签在做判断的时候,如果第一个条件就满足了,那么后续的条件就都不会拼接上,简单的说,choose会形成一个or的关系。
lchoose标签如果所有的条件都不满足,那么就会执行otherwise中的。
SELECT *from tb_user WHERE id = 14 or id = 17 or id = 21;
SELECT * from tb_user WHERE id in(14,17,21); |
---|
<< span="">select id="selectUserList3" parameterType="com.shop.domain.User" resultType="com.shop.domain.User"> SELECT * from tb_user << span="">where> << span="">if test="ids!=null"> << span="">foreach collection="ids" item="id" open="id in (" close=")" separator=","> #{id} foreach> if> where> select> |
---|