mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
MyBatis中用于实现动态SQL的元素主要有:if,choose(when,otherwise),trim,where,set,foreach
下面看几个我用到的几个元素:
(1)if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。
<if test="userCustom.sex != null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username != null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
when元素表示当when中的条件满足的时候就输出其中的内容,跟JAVA中的switch效果差不多的是按照条件的顺序,当when中有条件满足的时候,就会跳出choose,即所有的when和otherwise条件中,只有一个会输出,当所有的我很条件都不满足的时候就输出otherwise中的内容。所以上述语句的意思非常简单, 当sex!=null的时候就输出and userCustom.sex= #{userCustom.sex},不再往下判断条件,当sex为空且username!=null的时候就输出and userCustom.username= #{userCustom.username},当所有条件都不满足的时候就输出otherwise中的内容。
<select id="findUserList" parameterType="cn.itcast.mybatis.po.UserQueryVo" resultType="cn.itcast.mybatis.po.UserCustom">
select * from USER where 11 = 1
<choose>
<when test="userCustom.sex != null"> </span>
and userCustom.sex= #{userCustom.sex}
</when>
<when test="userCustom.username != null"> </span>
and userCustom.username= #{userCustom.username}
</when>
<otherwise>
and name= "www"
</otherwise>
</choose>
</select>
<!-- 用户信息综合查询
#{userCustom.sex}:取出pojo包装对象中性别值
${userCustom.username}:取出pojo包装对象中用户名称
-->
<select id="findUserList" parameterType="cn.itcast.mybatis.po.UserQueryVo"
resultType="cn.itcast.mybatis.po.UserCustom">
SELECT * FROM USER
<!--
where可以自动去掉条件中的第一个and
-->
<where>
<if test="userCustom !=null">
<if test ="userCustom.sex!=null and userCustom.sex!='' ">
</if>
<if test ="userCustom.username!=null and userCustom.username!='' ">
</if>
</if>
</where>
</select>
(4)foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。 向sql传递数组或List,mybatis使用foreach解析,foreach元素的属性主要有item,index,collection,open,separator,close。
index:指定一个名字,用于表示在迭代过程中,每次迭代到的位置
collection:指定输入 对象中集合属性
item:每个遍历生成对象中
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
<if test="ids!=null">
<!-- 使用foreache遍历id
collection:指定输入对象中集合属性
item:每个遍历生成对象中
open:开始遍历时候要拼接的串
close:结束遍历需要拼接的串
separator:遍历的两个对象中间需要拼接的串
-->
<!-- 使用下面的sql拼接:
and (id=1 or id=10 or id=16)
-->
<!-- <foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
每次遍历需要拼接的串
id=#{item_id}
</foreach> -->
<!-- 实现and id in(1,10,22) -->
<foreach collection="ids" item="item_id" open="and id in(" close=")" separator=",">
<!-- 每次遍历需要拼接的串 -->
#{item_id}
</foreach>
</if>
(5)此外mybatis可以定义sql片段,引用sql片段,提高代码的重用性
定义sql判断:
<!-- 定义sql片段 id:sql片段的唯一标识
经验:定义sql片段是基于单表定义,这样重用性比较高
sql片段中尽量不包含where
-->
<sql id="query_user_where">
<if test="userCustom != null">
<if test="userCustom.sex != null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username != null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
<if test="ids!=null">
<!-- 使用foreache遍历id
collection:指定输入对象中集合属性
item:每个遍历生成对象中
open:开始遍历时候要拼接的串
close:结束遍历需要拼接的串
separator:遍历的两个对象中间需要拼接的串
-->
<!-- 使用下面的sql拼接:
and (id=1 or id=10 or id=16)
-->
<!-- <foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
每次遍历需要拼接的串
id=#{item_id}
</foreach> -->
<!-- 实现and id in(1,10,22) -->
<foreach collection="ids" item="item_id" open="and id in(" close=")" separator=",">
<!-- 每次遍历需要拼接的串 -->
#{item_id}
</foreach>
</if>
</if>
</sql>
<!-- 用户信息综合查询 #{userCustom.sex}:取出包装对象中性别的值 -->
<select id="findUserList" parameterType="UserQueryVo"
resultType="UserCustom">
select id,username,birthday,sex,address from user
<!-- where可以自动去掉条件中的第一个and -->
<where>
<!-- 引用sql片段的id,如果refid指定的id不在本mapper文件中,需要加上namespace -->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其他sql片段 -->
</where>
</select>
动态sql这一块具体实践中还有很多需要注意的,以后有时间继续分享。