XxxMapper.xml中一些标签的使用可以帮助我们完成动态SQL的需求,这些标签有(部分):
<where/> <if/> <choose/> <set/> <foreach/> 等等
如下代码:
<select id="queryBlogIF" parameterType="map" resultType="blog"> select * from blog <where> <if test="id != null"> id=#{id} </if> <if test="title != null"> and title=#{title} </if> <if test="author != null"> and author=#{author}; </if> </where> </select>
作用是,使用一个map来传入属性对应的值,查询相应的结果。
<where/>标签代替了原sql中的手写where关键字的功能,能够动态的识别and、or关键字并进行对应的删除或者保留。什么意思呢?
这里搭配了<if/>标签使用。if标签就如Java中的if功能一样,后面test中填入相对应的表达式。上面<if test="id != null">,判断传入的id是否为空。
如果3个if条件都满足,那么这个sql语句就会变成select * from blog where id=#{id} and title=#{title} and author=#{author};若只有第一个满足,SQL为select * from blog where id=#{id} ;...若一个都不满足,SQL为select * from blog.
看到这里应该明白了where标签的作用了吧:如果where下的if标签,返回了空的结果集,则自动忽略该标签下的sql语句;如果结果集为非空,则会拼接该语句,并且根据语法,智能的删去或保留and或or关键字。非常智能。
再看看如下代码:
<select id="queryBlogChoose" parameterType="map" resultType="blog"> select * from blog <where> <choose> <when test="title != null"> title=#{title} </when> <when test="author != null"> and author=#{author} </when> <otherwise> and views=#{views} </otherwise> </choose> </where> </select>
<choose/>标签,搭配<when/> <otherwise/>标签出现。类似于Java中的switch 语句。此代码的功能是:如果传入了title,那么只保留title=#{title}语句;传入的是author,保留author语句;如果都不穿入,保留views语句。那如果传入了title和author怎么办?类似于switch-case,会保留最先出现的代码title=#{title}。
如下代码:
<update id="UpdateBlog" parameterType="map"> update blog <set> <if test="title != null"> title=#{title}, </if> <if test="author != null"> author=#{author} </if> </set> where id=#{id}; </update>
<set/>标签与<where/>标签作用一致。不同点是set标签用于增删改操作中,并且智能保留,(逗号),where标签则是用于查询操作,智能保留的是and或者or。以上代码不难读懂。
最后:如果我们想完成如下sql操作该怎么做?
select * from blog WHERE ( id=? or id=? or id=? )
<foreach/>标签则可以做到拼接的功能。代码如下:
<select id="getBlogs" resultType="blog" parameterType="map"> select * from blog <where> <foreach collection="ids" item="id" open="and (" close=")" separator="or"> id=#{id} </foreach> </where> </select>
其中
<foreach collection="ids" item="" open="" separator="" close=""/>
collection种传入一个集合ids,item为传入的元素id,open拼接sql的开头。这里要拼的sql是( id=? or id=? or id=? ),明显开头为( ,所以填(;中间的元素分隔符用or隔开,separator中填入or,最后用)结尾,填入close内。
个人认为foreach较难理解,要到实际场景,根据最终的sql来设计拼接。