05 MyBatis强大特性 动态SQL

MyBatis 的强大特性之一便是它的动态 SQL,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态SQL 这一特性可以彻底摆脱这种痛苦

动态SQL都是应用在映射文件中的
我这里使用的是mybatis-config.xml全局配置文件,里面添加映射mapper文件,来操作Order这个类.
这是全局配置文件

1.使用了别名,这样子在映射文件中填写返回类型的时候就比较方便简洁.在其他地方需要填完全限定名的时候也比较方便
2.默认的环境,最基本的配置使用POOLED
3.mappers,我这里使用的是从resources文件中获取mapper.xml文件
在这里插入图片描述
要操作的数据库,这是一个Orders(table)
在这里插入图片描述
对应的java类为
在这里插入图片描述

一、动态SQL之if

最简单的查询一下,所有Orders中user_id为1的,对应的SQL映射语句,在OrdersMapper接口中,该方法传入的是Object,返回类型为List<Orders>

    <select id="getOrdersByID" resultType="Orders" >
        select * from orders where user_id = #{userID}
    </select>

在这里插入图片描述
但是当需求变了的时候,不仅仅通过userID来进行查询,还要通过number或者其他字段来查询的时候,
不必重新写一个方法,只需要修改SQL映射即可.
例如:查询user_id为1并且订单号为1000011的订单

<select id="getOrdersByID" resultType="Orders" >
        select * from orders where 1=1
        <if test="user_id != null">
            and user_id = #{user_id}
        </if>
        <if test="number != null">
            and number = #{number }
        </if>
    </select>

if里面的为true,就表示传入的object存在这个属性的时候,在SQL语句后面就会自动添加上 and user_id = ?;
在这里插入图片描述

二、动态SQL之where

在上面if的使用时,如果user_id和number都不传入,
写出来的语句就是
select* from orders where 1=1
有时候你设置的条件可能也就会变成
select* from orders where and userid= 1;
这样也会有错

这时候只需要在前面添加上<where>标签即可

		select * from orders
        <where>
            <if test="user_id != null">
                and user_id = #{user_id}
            </if>
            <if test="number != null">
                and number = #{number }
            </if>
        </where>

where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除

三、动态SQL之set

set用在修改的时候,在修改时候,需要判断要修改的内容,对应的SQL映射是

			<if test="username != null and username!= ''">
                username = #{username},
            </if>
            <if test="number != null and number != ''">
                number = #{number},
            </if>

但是后面有逗号‘,’ 添加set的目的就在于,如果标签包含的元素有返回值,就插入一个逗号,如果set后面是以逗号结尾的,就将逗号去掉.达到人工编写正确SQL的目的

四、动态SQL之choose/when/otherwise

这个就像switch case default,
比如 <where>的作用在于去除后面的and,choose标签中,他会直接返回第一个成功的when,后续的不再执行,和switch case 一样.也有一个default,也就是otherwise.

		select * from orders
        <where>
            <choose>
                <when test="user_id != null">
                    and user_id = #{user_id}
                </when>
                <when test="number != null">
                    and number = #{number}
                </when>
                <otherwise>
                    and 1=0
                </otherwise>
            </choose>
        </where>

在当前情况下,如果传入了userid就按照userid查询,如果只传入了number就按number查询,如果同时传入了,按照顺序应该是按照userid来进行查询.

五、动态SQL之for each

foreach标签实现批量数据处理,遍历集合对象
foreach包含属性如下:
collection:必填,
当参数为数组时,collection属性为array
当参数为map时,collection属性为_parameter
当参数为list时,collection属性为list
item:变量名,从collection中拿出的每个元素的名称,自己起
index:索引的属性名,在集合数组下取值为当前索引值,当对象时map时,值为map的key.
open:整个循环开始的字符串
close:整个循环内容结束的字符串
separator:每次循环的分隔符

例子:批量插入时

XML映射SQL:
   <insert id="batchAddOrders">
        insert into orders(user_id, number, createtime, note) values
        <foreach collection="list" item="orders" separator=",">
            (#{orders.user_id},#{orders.number},#{orders.createtime},#{orders.note})
        </foreach>
    </insert>
  对应的java接口:
public void batchAddOrders(List<Orders> list);

例子:查询时,使用foreach

xml映射SQL:
<select id="getOrdersByID" resultType="Orders">
        select * from orders where user_id in 
        <foreach collection="list" item = "orders" index = "index"
                 open="(" separator="," close=")">
            #{orders.user_id}
        </foreach>
    </select>
java接口:
public List<Orders> getOrdersByID(Object o);

六、动态SQL之like模糊匹配

%可以替代任意个字符
_只能替代一个字符 这是我们在模糊匹配中要用到的

1.可以在参数中直接加入 %
mapper.getOrdersByNumber(“1%”);

<select id="getOrdersByNumber" 
    select * from orders where number like #{number}
</select>

2.使用concat:concat()函数用于将多个字符串连接成一个字符串

select * from orders where number like concat(concat('%', #{number}),'%')

3.使用bind标签
bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文
这样就解决了带like的模糊查找问题了

<select id="getOrdersByID" 
  <bind name="pattern" value="'%' + _parameter.getNumber() + '%'" />
  select* from orders where number like#{pattern}
</select>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值