1.动态sql
1.1if语句
接口映射文件中,多条件查询时,有可能因为传递的参数不对,导致异常
比如:如果你传递的username为null怎么办?为" "怎么办?
<!--
多条件查询
如果传递参数个数不对,会出现异常,动态sql可以解决
-->
<select id="findByCondition" resultMap="users" parameterType="user">
select * from user where uname like "%"#{username}"%" and sex = #{sex}
</select>
使用动态sql解决,动态sql可以加一些判断。
<!--
多条件查询
-->
<select id="findByCondition" resultMap="users" parameterType="user">-->
select * from user where 1=1
<if test="username != null">
and uname like "%"#{username}"%"
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</select>
1.2where语句
<!--
where : 可以自动去掉条件中的第一个and
多条件 都写上 and关键字
-->
<select id="findByCondition" resultMap="users" parameterType="user">
select * from user
<where>
<if test="username != null">
and uname like "%"#{username}"%"
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</where>
</select>
1.3sql片段
如果很多statement动态sql部分都一样,可以抽取为sql片段,然后在statement中引用即可。
<!--SQL片段
把重复的sql语句提取出来,需要使用时引用即可
id="": 唯一标志
文本:sql语句
-->
<sql id="select_user">select * from user</sql>
<!--
where : 帮助程序员处理第一个and
多条件 都写上 and关键字
-->
<select id="findByCondition" resultMap="users" parameterType="user">
-- 关联使用sql片段
-- include :包含
-- refid: 关联的sql片段的id。如果指定的id不在本映射文件中,需要在前面加namespace
-- ref :references
<include refid="select_user"></include>
<where>
<if test="username != null">
and uname like "%"#{username}"%"
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</where>
</select>
1.4foreach语句
如果要向sql传递数组或list,则使用foreach语句
可以将查询改为多个id查询,比如:
select*from user where id=1 or id=12 or id=17或
select*from user where id in(1,12,17)
多个id要作为参数传进来,所以可以在自定义一个pojo中增加一个属性:private List ids;
然后修改sql片段:
<if test="ids!=null and ids!=' ' ">
<foreach collection="ids" item=user_id open="AND(" close=")" separator=" OR ">
id=#{user_id}
</foreach>
<if>
所以这一部分拼接出来就是AND(id=1 OR id=12 OR id=17)
上面的属性:
- collection: 参数的类型:如果是集合:list,如果是数组: array
- open :前缀
- close:后缀
- separator: 分隔符
- item: 循环中的每一个对象
- index:循环中的索引( 一般不用)
补充:
在mybatis中,如果输入的是Integer或int类型的0,上面<if>标签返回的是false,也就是说即使非null非" ",也不会拼接sql