Mybatis复习(四)动态sql

动态sql

主要用于解决查询条件不确定的情况:在程序运行期间,根据提交的查 询条件进行查询。
通过MyBatis提供的各种标签对条件作出判断以实现动态拼接SQL语句。
MyBatis的动态SQL是基于OGNL表达式的。

使用动态SQL的原因
提供的查询条件不同,执行的SQL语句不同。若将每种可能的情况均逐一 列出,就将出现大量的SQL语句。

MyBatis中用于实现动态SQL的元素主要有:
if语句
where
trim
set
foreach
choose(when,otherwize)

if标签
就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。

where标签
会在写入where元素的地方输出一个where,
不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的 处理
如果所有的条件都不满足,那么MyBatis就会查出所有的记录
如果输出后是and开头的,MyBatis会把第一个and忽略
如果是or开头的,MyBatis也会把它忽略
在where标签中不需要考虑空格的问题,MyBatis会智能的加上

 <select id="selectByNamePassword" parameterType="user" resultType="user">
        select * from user
        <where>
            <if test="name!=null and name!=''">
                and name like concat('%',#{name},'%')
            </if>
            <if test="password!=null and password!=''">
                and password=#{password}
            </if>
        </where>
    </select>

trim标签的主要功能是可以在自己包含的内容前加上某些前缀,也可 以在其后加上某些后缀,与之对应的属性是prefix和suffix;
可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些 内容覆盖,对应的属性是prefixOverrides和suffixOverrides;

<insert id="insertSelective" parameterType="user">
        insert into user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id!=null">
                id,
            </if>
            <if test="name!=null ">
                name,
            </if>
            <if test="password!=null">
                password,
            </if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id!=null">
                #{id},
            </if>
            <if test="name!=null ">
                #{name},
            </if>
            <if test="password!=null">
                #{password},
            </if>
        </trim>
    </insert>

set标签主要是用在更新操作的时候,它的功能和where标签差不多。
当update语句中没有使用if标签时,如果有一个参数为null,都会导 致错误。
当在update语句中使用if标签时,如果前面的if没有执行,则会导致 逗号多余错误。
使用set标签可以在包含的语句前输出一个set,然后如果包含的语句 是以逗号结束的话将会把该逗号忽略。

<update id="updateByPrimaryKeySelective" parameterType="com.zx.domain.User">
    update user
    <set>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="password != null">
        password = #{password,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>

foreach 标签
foreach标签主要用在构建in条件中,它可以在SQL语句中进行迭代一 个集合。
foreach标签的属性主要有 item,index,collection,open, separator,close。
item表示集合中每一个元素进行迭代时的别名
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置
open表示该语句以什么开始
separator表示在每次进行迭代之间以什么符号作为分隔符
close表示以什么结束

foreach标签的collection属性是必须指定的,但是在不同情况下, 该属性的值是不一样的,
主要有以下3种情况:
1.如果传入的是单参数且参数类型是一个List的时候,collection属性值 为list
2.如果传入的是单参数且参数类型是一个array数组的时候,collection的 属性值为array
3.如果传入的参数是多个的时候,需要把它们封装成一个Map,当然单参数 也可以封装成Map
4.实际上如果在传入参数的时候,在MyBatis里面也是会把它封装成一个 Map的,Map的key就是参数名,所以这个时候collection属性值就是传入 的List或Array对象在自己封装的Map里面的key

<select id="selectPostIn" resultType="domain.blog.Post">
    SELECT *
    FROM POST P
    WHERE ID in
    <foreach item="item" index="index" collection="list"
        open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

choose 标签
choose标签 按顺序判断其内部when标签中的test条件出否成立,如果有一个成立, 则 choose 结束。
当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的 sql。
类似于Java 的 switch 语句,choose 为 switch,when 为 case, otherwise 则为 default。

<select id="findActiveBlogLike"
     resultType="Blog">
    SELECT * FROM BLOG WHERE state = ‘ACTIVE’
    <choose>
        <when test="title != null">
            AND title like #{title}
        </when>
        <when test="author != null and author.name != null">
            AND author_name like #{author.name}
        </when>
        <otherwise>
            AND featured = 1
        </otherwise>
    </choose>
</select>

关于动态SQL的接口和类

SqlNode接口,简单理解就是xml中的每个标签,比如上述sql的update,trim,if标签:

public interface SqlNode {
    boolean apply(DynamicContext context);
}

SqlSource Sql源接口,代表从xml文件或注解映射的sql内容,主要就是用于创建BoundSql,有实现类DynamicSqlSource(动态Sql源),StaticSqlSource(静态Sql源)等:

public interface SqlSource {
    BoundSql getBoundSql(Object parameterObject);
}

BaseBuilder接口及其实现类(属性,方法省略了),这些Builder的作用就是用于构造sql:

XMLConfigBuilder:解析mybatis中configLocation属性中的全局xml文件,内部会使用XMLMapperBuilder解析各个xml文件。

XMLMapperBuilder:遍历mybatis中mapperLocations属性中的xml文件中每个节点的Builder,比如user.xml,内部会使用XMLStatementBuilder处理xml中的每个节点。

XMLStatementBuilder:解析xml文件中各个节点,比如select,insert,update,delete节点,内部会使用XMLScriptBuilder处理节点的sql部分,遍历产生的数据会丢到Configuration的mappedStatements中。

XMLScriptBuilder:解析xml中各个节点sql部分的Builder。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值