什么是动态SQL?
就是相对与固定SQL。就是通过传入的参数不一样,可以组成不同结构的SQL语句. 这种根据参数的条件修改SQL结构的SQL语句,我们称为动态SQL语句.
If 使用
<select id="selectByCondition" resultType="com.mybatis.pojo.User">
<!-- 错误写法 select * from user where name like '%#{name}%' or age = #{age} -->
<!--
正确写法:
select * from user where name like concat('%',#{name},'%') or age = #{age}
或者传值加上%
上述SQL语句的语义来说,是一个静态SQL语句,一开始已经确定SQL的语义的
不管有没有数据,都会对全部数据进行修改,如果某一个数据没有,name会自动设置为null
不符合实际场景
解决方案: 使用MyBatis的动态SQL语句
-->
select * from user where
<if test="name!=null and name!=''">
name like concat('%',#{name},'%')
</if>
<if test="age!=null and age!=''">
or age = #{age}
</if>
</select>
我们会发现当都不传时,sql语句为:select * from user where。会报错。
当我门只传age值时,sql语句为:select * from user where or age=1。会报错。
因此需要另一个标签解决,这个标签就是where
where标签
1.当编写 where 标签时,如果内容中第一个是 and/or 去掉第一个 and/or
2. 如果中有内容会生成 where 关键字,如果没有内容不 生成 where 关键
<select id="selectByCondition" resultType="com.mybatis.pojo.User">
<!-- 错误写法 select * from user where name like '%#{name}%' or age = #{age} -->
<!--
正确写法1:
select * from user where name like concat('%',#{name},'%') or age = #{age}
或者传值加上%
上述SQL语句的语义来说,是一个静态SQL语句,一开始已经确定SQL的语义的
不管有没有数据,都会对全部数据进行修改,如果某一个数据没有,name会自动设置为null
不符合实际场景
解决方案: 使用MyBatis的动态SQL语句
-->
select * from user
<where>
<if test="name!=null and name!=''">
name like concat('%',#{name},'%')
</if>
<if test="age!=null and age!=''">
or age = #{age}
</if>
</where>
</select>
sql与include标签
1.某些 SQL 片段如果希望复用,可以使用定义这个片段
2.sql片段用include标签引入
<select id="selectByCondition" resultType="com.mybatis.pojo.User">
<!-- 错误写法 select * from user where name like '%#{name}%' or age = #{age} -->
<!--
正确写法1:
select * from user where name like concat('%',#{name},'%') or age = #{age}
或者传值加上%
上述SQL语句的语义来说,是一个静态SQL语句,一开始已经确定SQL的语义的
不管有没有数据,都会对全部数据进行修改,如果某一个数据没有,name会自动设置为null
不符合实际场景
解决方案: 使用MyBatis的动态SQL语句
-->
select * from user
<!-- include:引入sql片段 -->
<include refid="selectSql"/>
</select>
<!-- sql片段:
id:唯一标识
-->
<sql id="selectSql">
<where>
<if test="name!=null and name!=''">
name like concat('%',#{name},'%')
</if>
<if test="age!=null and age!=''">
or age = #{age}
</if>
</where>
</sql>
<select id="selectTotalByCondition" resultType="long">
select count(*) from user
<include refid="selectSql"/>
</select>
set标签的使用
1.作用:去掉最后一个逗号
2.作用:如果里面有内容生成 set 关键字,没有就不生成
3.id=#{id} 目的防止中没有内容,mybatis 不生成 set 关键字,如果修改中没有 set 从句 SQL 语法错误.
<update id="updateUserByNotNull">
update user
<set>
id=#{id}
<if test="username!=null and username!=''">
username=#{username},
</if>
<if test="password!=null and password!=''">
password=#{password},
</if>
<if test="age!=null and age!=''">
age=#{age},
</if>
</set>
where id=#{id}
</update>
trim标签
1.prefix:在trim标签里的成立sql语句前面添加prefix值,一般prefix值为where/set
2.prefixOverrides:去掉在trim标签里的成立sql语句前面第一个关键字,一般是and /or
3.suffix:在trim标签里的成立sql语句后面添加suffix值
4.suffixOverrieds:去掉在trim标签里的成立sql语句最后面一个字符,一般是,逗号
–prefix
<select id="selectByCondition" resultType="com.mybatis.pojo.User">
select * from user
<include refid="selectSql"/>
</select>
<sql id="selectSql">
<trim prefix="where">
<if test="username!=null and username!=''">
username like concat('%',#{username},'%')
</if>
</trim>
</sql>
当username有值时,sql语句为:select * from user where username like concat(’%哥%’)
–prefixOverrides
<select id="selectByCondition" resultType="com.mybatis.pojo.User">
select * from user
<!-- include:引入sql片段 -->
<include refid="selectSql"/>
</select>
<!-- sql片段: id:唯一标识 -->
<sql id="selectSql">
<!-- 注意:and|or不能写成and | or,不能有空格 -->
<trim prefix="where" prefixOverrides="and|or">
<if test="username!=null and username!=''">
and username like concat('%',#{username},'%')
</if>
<if test="age!=null and age!=''">
or age = #{age}
</if>
</trim>
</sql>
当只有username有值时,sql语句为:select * from user where username like concat(’%’,#{username},’%’)
当只有age有值时,sql语句为:select * from user where age = #{age}
当两个都有值时,sql语句为:select * from user where username like concat(’%’,?,’%’) or age = ?
–suffixOverrieds
<update id="updateUserByNotNull">
update user
<trim prefix="set" suffixOverrides=",">
id=#{id},
<if test="username!=null and username!=''">
username=#{username},
</if>
<if test="password!=null and password!=''">
password=#{password},
</if>
<if test="age!=null and age!=''">
age=#{age},
</if>
</trim>
where id=#{id}
</update>
–suffix
<update id="updateUserByNotNull">
update user
<trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
id=#{id},
<if test="username!=null and username!=''">
username=#{username},
</if>
<if test="password!=null and password!=''">
password=#{password},
</if>
<if test="age!=null and age!=''">
age=#{age},
</if>
</trim>
</update>
foreach标签
1.collectino=”” 要遍历的集合
2.item 迭代变量, #{迭代变量名}获取内容
3. open 循环后左侧添加的内容
4. close 循环后右侧添加的内容
5. separator 每次循环时,元素之间的分隔符
实例1:
<delete id="deleteByIds">
delete from user where id in
<foreach collection="ids" item="id" close=")" open="(" separator=",">
#{id}
</foreach>
</delete>
实例2:
<insert id="insertByBatch">
insert into user(username,password,age) values
<foreach collection="users" item="user" separator=",">
(#{user.username},#{user.password},#{user.age})
</foreach>
</insert>