cnflat0 2015-01-15
Mybatis动态sql
mybatis可以根据判断一些情况,然后决定是否要生成相应的sql语句,常用的
if:判断,跟java中的if类似
使用方法
<iftest="判断语句">SQL语句</if>:当满足test中的判断语句时,
if里面的sql语句就拼接到前面的sql语句上,如
<selectid="findUsers"resultMap="UserMap">
select*fromuserswhere
<iftest="username!=nullandusername!=''">
username=#{username}
</if>
</select>
mybatis中的模糊查询,在sqlserver中要这样拼接:username='%'+#{username}+'%'(注意是单引号)
当我们使用多个判断时,如果第一个判断不成功,第二个成功的话,可能就会出现where后面直接接and的情况,这样的
sql语句就会出问题,如
<selectid="findUsers"resultMap="UserMap">
select*fromuserswhere
<iftest="username!=nullandusername!=''">
username=#{username}
</if>
<iftest="age!=null">
andage=#{age}
</if>
</select>
如果username为空的话,拼成的sql语句就是select*fromuserswhereandage=#{age},这样是有问题的
我们可以使用trim去处理这种情况
trim类似于replace:
trim属性有:
prefixOverrides:前缀判断的条件,当前缀是该值时,则用prefix中的值替换掉prefixOverrides中的值
prefix:用来替换prefixOverrides的值
suffixOverrides:后缀判断的条件,当后缀是该值时,则用suffix中的值替换掉suffixOverrides中的值
suffix:用来替换suffixOverrides的值
如我们要做一个查找用户的sql
<selectid="findUser"resultMap="userMap">
select*fromusers
<trimprefix="where"prefixOverrides="AND|OR">
<iftest="username!=nullandusername!=''">
ANDusernamelike'%'+#{username}+'%'
</if>
<iftest="age!=null">
ORage=#{age}
</if>
</trim>
</select>
当username不为空时,则trim中的语句是ANDusernamelike'%'#{username}'%',以AND打头,满足prefixOverrides中的判断,
所以用prefix中的值WHERE去替换AND,替换后是WHEREusernamelike'%'#{username}'%'
当username为空时,且age不为空时,则trim中语句是ORage=#{age},以OR打头,同样用WHERE去替换,替换后就是WHEREage=#{age}
suffix同样,如我们要生成一个可重用的sql片段
<sqlid="column_list">
<trimsuffix=""suffixOverrides=",">
<iftest="username!=nullandusername!=''">
username,
</if>
<iftest="password!=null>
password,
</if>
<iftest="age!=null">
age,
</if>
</trim>
</sql>
当trim中的语句是以逗号结尾,则用就''去替换,也就是去掉逗号
当我们只要用一个条件去查的话,我们可以使用choose,choose类似于java中的switch,如下面
<selectid="findUser">
select*fromuserwhere
<choose>
<whentest="username!=null">
usernamelike'%'+#{username}+'%'
</when>
<whentest="password!=null">
password=#{password}
</when>
<otherwise>
age=#{age}
</otherwise>
</choose>
</select>
当username不为空时,生成的Sql语句是select*fromuserwhereusernamelike'%'+#{username}+'%',不管后面password和age是否为空,username满足了就不会后面的了,跟switch一样,只会对应一个case