引入话题:为啥要使用动态sql语句呢?
<select id="findUsersByNameAndAge" parameterType="user" resultType="user">
select * from t_user where name like #{name} and age = #{age};
</select>
在该映射配置文件中,该语句的功能是根据姓名进行模糊查询并且根据年龄多个条件查询。条件是并列存在的。此时若出现一种特殊情况,假如只输入姓名,或者只输入年龄,或者什么都不输入的情况下,该语句就会查不出自己想要的结果。
eg: 若查询条件为name=zh,age为空,数据库表中就算有name=zhao的记录,但是因为它的age字段属性为20,不符合年龄这个条件,就查不到这个结果。
1.<if></if>标签和<where></where>标签
因此要引入动态sql语句来解决这个问题。
<select id="findUsersByNameAndAge" parameterType="user" resultType="user">
<!--select * from t_user where name like #{name} and age = #{age};-->
select * from t_user
<where>
<if test="name != null and name != ''" >
and name like #{name}
</if>
<if test="age != null and age != ''" >
and age = #{age};
</if>
</where>
</select>
注意:首先在编写这段代码,自己犯了一个致命错误,那就是在xml文件的注释使用了#这种注释,是错误的,应使用<!---->
易错的地方:每条语句前面都要加一个and语句,这也许就有一点疑惑了,后面几个条件确实要加and,但为什么第一个也要加呢,其实这与where标签有着很大的关系。当不使用where标签时,代码如下:
<select id="getOrderDetails" parameterType="com.zy.entity.dto.OrderDto" resultType="com.zy.entity.po.OrderPo">
select * from order_table where 1=1
<if test="id != null and id != ''">
And id = #{id}
</if>
<if test="name != null and name != ''">
And name = #{name}
</if>
<if test="type != null and type != ''">
And type = #{type}
</if>
<if test="userId != null and userId != ''">
And userId = #{userId}
</if>
<if test="pageNum != null and pageNum != ''">
limit #{pageSize},#{pageNum}
</if>
</select>
这段代码where后面多了一个条件1=1;这是为了防止当第一个条件不成立时,其where后直接跟着的是第二个条件的and,不符合sql语言的语法规则。1=1恒成立,这样where与and不会直接接触。这也是第一个条件为啥也要加and的原因。
2.sql片段
在xml配置文件中书写sql代码时,会有许多语句是重复的,因此我们把相同的公共sql语句给提取出来,这样直接调用即可。
<select id="findUsersByName" parameterType="string" resultType="User">
<include refid="commendSql">
</include>
where name like #{name};
</select>
<!-- 通用公共sql语句-->
<sql id="commendSql" >
select * from t_user
</sql>
首先使用<sql>语句,将公共片段放入其中,调用<include>通过id引入。这是公共sql片段和调用的语句在同一个配置文件中。
若不在同一个配置文件时,则需要使用refid="全类名"。
<select id="findUsersByName" parameterType="string" resultType="User">
<include refid="com.zy.mapper.OrderMapper.commendSql">
</include>
where name like #{name};
</select>
3.foreach标签
<select id="findUsersByListIds" parameterType="list" resultType="list">
select * from t_user where id in (1,2,3);
</select>
当接受参数为一个集合时,sql语句如上所示,这是已知集合中的数据,当发生改变时,sql语句也需要改变,不灵活,因此引入了<foreach>标签。
<select id="findUsersByListIds" parameterType="list" resultType="user">
<!-- select * from t_user where id in (1,2,3);-->
select * from t_user
<foreach collection="list" open="where id in (" close=")" separator="," item="item" >
#{item}
</foreach>
</select>