10、动态SQL
什么是动态sql:动态sql指的是根据不同的查询条件,生成不同的sql语句
是mybaits的强大特性之一
10.1、常用的标签
if
choose(when,oitherwise)
trim(where set)
foreach
10.2、if标签
可以根据需求来进行不同的查询条件,如果有值就拼上条件,没有的话就不拼
判断字符类型
<select id="queryAll" resultMap="BaseResultMap">
select
*
from
`user`
where
<if test="username!=null and username!=''">
username = #{username,jdbcType=VARCHAR}
</if>
</select>
判断集合类型
<if test="username!=null and username.size!=0">
username = #{username,jdbcType=VARCHAR}
</if>
10.3 Where 标签
当我们有多个查询条件并且使用if时,假设第一个条件拼接,where后边便会多出来一个and就会使sql报错,使用where标签就可以帮我们解决这个问题,消除第一个and或者or(最常用),当查询条件都为空时,where关键字也就不会在sql内拼接
<select id="queryAll" resultMap="BaseResultMap">
select
*
from
`user`
<where>
<if test="username!=null and username.size!=0">
username = #{username,jdbcType=VARCHAR}
</if>
</where>
</select>
10.4 set标签
当插入或者修改数据时,也是选择性插入或修改时也会有同样的问题(逗号问题),set标签就可以帮我们去掉第一个或者最后一个逗号
<update id="update">
update `user`
<set>
<if test="username!=null and username!=''">
username = #{username,jdbcType=VARCHAR},
</if>
<if test="password!=null and password!=''">
username = #{password,jdbcType=VARCHAR}
</if>
</set>
where id=#{id}
</update>
10.5 choose标签
choose标签是搭配when和otherwise标签一起使用的
可以想象为if-else 如果满足第一个条件就走第一个不在往后执行,第一个没有就执行下一个,一直到最后都没有就执行otherwise标签内的数据
<select id="queryAll" resultMap="BaseResultMap">
select * from `user`
<where>
<choose>
<when test="username!=null and username!=''">
username = #{username,jdbcType=VARCHAR}
</when>
<when test="password!=null and password!=''">
and password = #{password,jdbcType=VARCHAR}
</when>
<otherwise>
and id = #{id}
</otherwise>
</choose>
</where>
</select>
10.6 SQL片段
将多个sql使用的共同语句通过sql标签提取成公共的
使用include标签来引用
<!--定义公共内容-->
<sql id="col">
id,username,password
</sql>
<!--使用include标签来引用-->
<select id="queryAll" resultMap="BaseResultMap">
select
<include refid="col"></include>
from `user`
<where>
<choose>
<when test="username!=null and username!=''">
username = #{username,jdbcType=VARCHAR}
</when>
<when test="password!=null and password!=''">
and password = #{password,jdbcType=VARCHAR}
</when>
<otherwise>
and id = #{id}
</otherwise>
</choose>
</where>
</select>
使用include来引用sql标签内容,也可以引用别的文件中的sql片段,需要在前边加上namespace标签
注意:
1、最好基于单标来定义sql片段,提高片段的可重用性
2、在sql片段中不要包括where
10.7 foreach
相当于java中的for循环
<select id="queryList" resultMap="BaseResultMap">
select <include refid="col"/>
from `user`
where
id in
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
collection:传进来的集合
item:遍历集合取出每一项数据定义别名
open:最左边的符号
close:最右边的符号
separator:每一项数据之间的分隔符
定义mapper接口
List<User> queryList(@Param("ids") List<String> ids);
测试类
@org.junit.Test
public void test02(){
SqlSession sqlSession = getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<String> ids = new ArrayList<>();
ids.add("1");
ids.add("2");
ids.add("3");
List<User> users = mapper.queryList(ids);
users.forEach(action->{
System.out.println(action);
});
sqlSession.close();
}
输出
10.8 trim标签
<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>
- prefix:
- 表示在trim包裹的SQL语句前面添加的指定内容。
- suffix:
- 表示在trim包裹的SQL末尾添加指定内容
- prefixOverrides:
- 表示去掉(覆盖)trim包裹的SQL的指定首部内容
- suffixOverrides:
- 表示去掉(覆盖)trim包裹的SQL的指定尾部内容
小结
动态sql语句就是一个拼接的问题,为了保证准确性,我们最好首先把原生的sql语句写出来,然后再通过mybatis的动态标签来改,防止出错。如果这些标签可以熟练使用了,便可以直接只用标签