MyBatis的动态SQL

MyBatis的动态SQL主要包括if,choose(when,otherwise),where,set,foreach,先来看看if:

<select id="queryTeacherByStudentNameAddSex" parameterType="com.zengyg.myibatis.dto.StudentInfo"
    resultMap="teacherResultUseJoin">
    select t.teacher_id ,t.name ,t.sex,student_id,s.name as name_s,s.sex as sex_s
    from teacher t left join student s on t.teacher_id =s.teacher_id
    where t.teacher_id = #{teacherId}
    <if test="sex != null and name != null">
        and s.name = #{name}
        and s.sex = #{sex}
    </if>
</select>

if的test中可以是一个或者多个条件,可以是and也可以是or
choose(when,otherwise)的写法:

<select id="queryTeacherByStudentNameOrSex" parameterType="com.zengyg.myibatis.dto.StudentInfo"
    resultMap="teacherResultUseJoin">
    select t.teacher_id ,t.name ,t.sex,student_id,s.name as name_s,s.sex as sex_s
    from teacher t left join student s on t.teacher_id =s.teacher_id
    where t.teacher_id = #{teacherId}
    <choose>
        <when test="sex != null ">
            and s.sex = #{sex}
        </when>
        <when test="name != null ">
            and s.name = #{name}
        </when>     
        <otherwise>
            and s.student_id =3
        </otherwise>
    </choose> 
</select>

和java 的switch case语句类似的写法,只要有一个条件满足则不在继续 执行下面的我when,如果所有条件都不满足,执行otherwise块,最后来看看foreach语句:

<select id="queryTeacherByStudentName" parameterType="com.zengyg.myibatis.dto.TeacherInfo"
    resultMap="teacherResultUseJoin">
    select t.teacher_id ,t.name ,t.sex,student_id,s.name as name_s,s.sex as sex_s
    from teacher t left join student s on t.teacher_id =s.teacher_id
    where s.name in
    <foreach item="student" index="index" collection="list"
        open="(" separator="," close=")">
        #{student.name}
    </foreach>
</select>

在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有以下3种情况:

  • 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  • 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  • 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可,此时collection属性值为map的key

list和array很好理解,对Map做一个说明,简单的示例代码,其中Java代码片段:

ArrayList<String> studentNames= new ArrayList<String>();
HashMap<String,Object> params = new HashMap<String,Object>();
params.put("nameList", studentNames);
params.put("sex", "F");

SqlMap代码片段:

<foreach item="name" index="index" collection="nameList"
    open="(" separator="," close=")">
    #{name}
</foreach>

Mybatis的动态SQL还有 where, set,用来处理查询时where后面紧跟动态SQL和update后紧跟动态SQL的问题,如下的select语句,当name为空sex不为空时,MyBatis会自动把sex前面的and 去掉,最后的查询语句类似: SELECT * FROM student where sex = ‘F’

<select id="*****" parameterType="Blog" resultType="***">
    SELECT * FROM student
    <where>
        <if test="name != null">
            name= #{nane}
        </if>
        <if test="sex != null">
            and sex = #{sex}
        </if>
    </where>
</select>

同样set的场景用于update语句,set元素会动态前置SET关键字,而且也会消除任意无关的逗

<update id="*****" parameterType="****" resultType="***">
    update student
    <set>
        <if test="name != null">
            name= #{nane},
        </if>
        <if test="teacherId!= null">
            teacher_id= #{teacherId},
        </if>
        <if test="sex != null">
            sex = #{sex}
        </if>
    </set>
    where student_id= #{studentId}
</update>

虽然Mybaties提供了where和set的解决方案,使sql可以正确执行,但为了程序的性能和稳健,业务层还是应该做必要的非空校验,不应该不带任何条件进行查询和更新

以上完整代码地址:https://git.oschina.net/zengyg/J2EEAPIStudy.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值