MyBatis的动态SQL
1-if标签
1-在查询的时候-标签1
-
常用于update或者insert中选择性更新或者插入某个字段的值
-
案例:高级查询:只输入用户名,进行模糊查询,只输入邮箱,进行全匹配查询。两者都输入,进行匹配查询
-
<select id="selectByUserWhere" resultType="sysUser"> select * from sys_user <where> <if test="userName !=null and userName != ''"> and user_name like concat('%',#{userName},'%') </if> <if test="userEmail != null and userEmail != '' "> and user_email = #{userEmail} </if> </where>
-
判断条件 property != null 或者 property ==null 适合任何类型的字段,用于判断属性值是否为空。 判断条件 property !=‘’ 或者property == ‘’ 只适合String类型的字段
-
注意1=1 这个条件:考虑如果两个条件都不满足,则sql语句是不对的
2-在update中的if
-
选择性更新某个字段,通过if实现动态列更新
-
选择性更新命名规范:方法名会以Selective作为后缀
-
update sys_user set <if test="userName != null and userName != '' "> user_name = #{userName}, </if> <if test="userPassword != null and userPassword !='' "> user_password = #{userPassword}, </if> id = #{id} where id = #{id}
-
==注意点:==第一点是每个if元素里面的SQL语句后面的逗号,第二点就是where关键字前面的id=#{id}
-
关于第二点:当全部的查询条件都是null或者空,如果有id=#{id}则为:update sys_user set id =#{id} where id = #{id},没有的话,sql语句则不完整。如果条件只有一个成立,没有id=#{id},sql语句也是不完整的
3-insert中使用if
-
目标:插入数据库中插入某一字段时,若用户输入为空,则使用数据库中的,否则使用用户输入的数据
-
insert into sys_user( user_name, user_password, <if text= " userEmail !=null and userEmail != '' "> user_email </if> )values( #{userName},#{userPassword}, <if test="userEmail != null and userEmail != '' "> #{userEmail} </if> )
在inser中使用时要注意,若在列的部分增加if条件,则values的部分也要增加相同的if条件,必须保证上下可以相互对应。
4-choose用法
if标签提供了基本的条件判断,但是无法实现if…else,的逻辑,要想实现这样的逻辑,就是用到choose 。。。when。。。otherwise标签
-
需求:当id有属性值的时候,优先使用id,当id无的时候判断用户名是否有值,都没有的时候sql无结果
-
select id,userName,userPassword,userEmail,userInfo from sys_user where 1=1 <choose> <when test =" id !=null"> and id = #{id} </when>1 <when test="userName != null and userName != ' '"> and user_name = #{userName} </when> <otherwise> and 1=2 </otherwise> </choose>
-
当且仅当 when全部为false 的时候,执行 otherwise 标签内的语句,所以 在使用 choose标签的时候,要思路清晰,否则会出现意料之外的事情
-
在以上查询中,如果没有otherwise 这个限制条件,所有的用户都会被查询出来,因为我们在对应的接口方法中使用了sysuser作为返回值,所以当实际查询结果是多个时就会报错
5-where 标签对比 标签1
where 和 set和 trim 这三个标签解决了类似的问题,并且where和set都属于 trim的一种具体用法。
-
where标签的作用:如果该标签包含的元素中有返回值,就插入一个where ;如果where后面的字符串是以AND和OR开头的,就将他们剔除
-
select id,userName,userPassword,userEmail from sys_user <where> <if test=" userName != null and userName != ''"> and user_name like concat('%',#{userName},'%') </if> <if test=" userEmail != null and userEmail != ''"> and user_email = #{userEmail} </if> </where>
-
where 标签和if标签同时使用的情况下,可以让sql更加的简洁,不会有where 1=1 这样的条件
6-set 用法对比2
-
set标签的作用:如果给标签包含的元素中有返回值,就插入一个set,如果set后面字符串是以逗号结尾的,就将这个逗号去掉
-
update sys_user <set> <if test = "userName != null and userName != '' "> user_name = #{userName}, </if> <if test="userPassword != null and userPassword != '' "> user_password = #{userPassword}, </if> where id = #{id} </set>
-
注意:在set标签用法中,sql后面的逗号没有问题了,但是如果set元素中没有内容,照样会出现sql错误,所以为了避免错误产生,类似id=#{id} 这样必然存在的赋值依然有保留的必要
7-trim用法
-
where和set标签的功能都可以用trim标签实现,并且在底层就是通过TrimSqlNode实现的
-
trim实现where标签和set标签的功能
-
<trim prefix="where" prefixOverrides="and |or "> .... </trim> -- 这里的and 和or 后面的空格不能省去,避免匹配到andes orders等单词 <trim prefix = "set" suffixOverrides = ","> .... </trim>
-
trim 属性值
- prefix:当trim元素内包含内容时,会给内容增加prefix指定的前缀
- prefixOverrides:当trim元素内包含内容时,会把内容中匹配的前缀字符去掉
- suffix:当trim元素内包含内容的时候,会给内容增加suffix指定的后缀
- suffixOverrides: 当trim元素内包含内容时,会把内容中匹配的后缀字符串去掉
8-foreach实现in集合
-
需求:如何根据用户id集合查询出所有符合条件的用户
-
select id, userPassword, userEmail from sys_user where id in <foreach collection = "list" open="(" close=")" separator ="," item="id" index="i"> #{id} </foreach>
-
注意:当有多个参数的时候,要在dao接口的方法参数前加上@param注解给每个参数指定一个名字,否则的话,在sql中使用参数就会不方便,特别在foreach中
9-foreach实现批量插入
<insert id="insertList">
insert into sys_user(userName,userPassword,userEmail)
values
<foreach collection="list" item="user" separator=",">
( #{userName},#{userPassword},#{userEmail} )
</foreach>
</insert>
- 注意:通过item指定了循环变量名之后,在引用值的时候使用是“属性.属性” 的方式,如 user.userName
10-foreach实现动态update
-
参数类型是map时,foreach如何实现动态update
-
当参数时map类型的时候,foreach标签的index属性值对应的不是索引值,而是map中的key
<update id="updateByMap">
update sys_user set
<foreach collection="_parameter" item="val" index="key" separator=",">
${key} = #{key}
</foreach>
where id= #{id}
</update>
- 注意:这里的key作为列名,对应的值作为该列的值,通过foreach将需要更新的字段拼接在sql语句中
批量操作
批量增加
<insert id="insertBatch" parameterType="list">
insert into zx_client
(
,phone,real_name,age,sex,id_no,id_addr
) values
<foreach collection="list" item="item" open="(" separator="," close=")">
(
,#{phone},#{realName},#{age},#{sex},#{idNo},#{idAddr}
)
</foreach>
</insert>
批量更新
<update id="updateOrderItem" parameterType="java.util.List">
<foreach collection="list" item="item" separator=";">
update order_item
<set>
<if test="item.orderId != null">
order_id = #{item.orderId},
</if>
<if test="item.productId != null">
product_id = #{item.productId},
</if>
<if test="item.count != null">
count = #{item.count}
</if>
</set>
where id = #{item.id}
</foreach>
</update>
批量查询
List<MRailwaystation> listRailwayStationlist( List<String> codeList);
<select id="listRailwayStationlist" resultType="com.ceic.foundation.op.common.model.MRailwaystation">
select * from m_railwaystation where railwaystation_id in
<foreach collection="@Param没有加这个注解就写 list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>