1.Mybatis框架动态SQL的常用标签
- <if>标签:用于判断条件是否成立,如果条件成立则执行相应的SQL语句块。可以嵌套使用多个<if>标签来实现复杂的条件判断。test:判断字段名不能为空
<select id="getUserList" parameterType="User" resultType="User"> SELECT * FROM user WHERE 1=1 <if test="username != null and username != ''"> AND username = #{username} </if> <if test="email != null and email != ''"> AND email = #{email} </if> </select>
- <choose>、<when>、<otherwise>标签:用于实现类似于switch-case的逻辑判断。<choose>标签下可以有多个<when>标签和一个<otherwise>标签,当某个<when>条件满足时,执行对应的SQL语句块;当所有<when>条件都不满足时,执行<otherwise>标签下的SQL语句块。
<select id="getUserList" parameterType="User" resultType="User"> SELECT * FROM user WHERE 1=1 <choose> <when test="username != null and username != ''"> AND username = #{username} </when> <when test="email != null and email != ''"> AND email = #{email} </when> <otherwise> AND status = 'active' </otherwise> </choose> </select>
- <trim>标签:用于处理SQL语句块中的前缀、后缀以及中间部分的空格或逗号。通过指定prefix:加上前缀 ,suffix:加上后缀,prefixOverrides:省略前缀,suffixOverrides:省略后缀,可以灵活地控制SQL语句块的生成。
<update id="updateUser" parameterType="User"> UPDATE user <trim prefix="SET" suffixOverrides=","> <if test="username != null and username != ''"> username = #{username}, </if> <if test="email != null and email != ''"> email = #{email}, </if> </trim> WHERE id = #{id} </update>
4.<foreach>标签:用于循环遍历集合或数组,并将集合中的元素依次插入到SQL语句中。通过item:别名,index:表示在迭代过程中,当前迭代到的位置(下标),collection:参数名称, open:开始, separator:分隔符 ,close:结束。等属性,可以指定遍历时的变量名、索引名以及要遍历的集合。
<select id="getUserListByIds" parameterType="java.util.List" resultType="User">
SELECT * FROM user
WHERE id IN
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</select>
5.<where>
标签 :可以将包含条件的 SQL 片段包裹起来,并根据这些条件动态生成 WHERE 子句。它会自动处理 WHERE 关键字和条件之间的逻辑关系,使 SQL 语句更加简洁和易读。一般与if一起用于查询语句,下面我们就来写一个if+where的查询
<select id="getUserList" parameterType="User" resultType="User">
SELECT * FROM user
<where>
<if test="username != null and username != ''">
AND username = #{username}
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
</where>
</select>
在上述示例中,<where>
标签包裹了包含 username 和 email 条件的 SQL 片段。如果 username
不为空,则会生成 AND username = #{username}
;如果 email
不为空,则会生成 AND email = #{email}
。如果两个条件都为空,则 <where>
标签会自动忽略其中的内容,不生成 WHERE 关键字,从而避免生成无效的 SQL。
6.<set>
标签:可以将包含需要更新的字段和值的 SQL 片段包裹起来,并根据这些条件动态生成 SET 子句。它会自动处理 SET 关键字、字段和值之间的逗号和空格,使 SQL 语句更加简洁和易读。用于修改语句
<update id="updateUser" parameterType="User">
UPDATE user
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="email != null and email != ''">
email = #{email},
</if>
</set>
WHERE id = #{id}
</update>
在上述示例中,<set>
标签包裹了包含需要更新的字段和值的 SQL 片段。如果 username
不为空,则会生成 username = #{username},
;如果 email
不为空,则会生成 email = #{email},
。如果两个字段都为空,则 <set>
标签会自动忽略其中的内容,不生成 SET 关键字,从而避免生成无效的 SQL。
2.Mybatis 动态 sql 是做什么的?
Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。
3.动态 sql 的执行原理?
原理为:使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。
4.使用foreach写一个批量新增
(1)写接口
//批量新增
public int insertUser(@Param("sysUsers") List<SysUser> sysUsers);
(2)写xml文件
<insert id="insertManySupplierNotID" parameterType="java.util.List">
insert into t_supplier( supCode, supName, supContact, supPhone, supFax, createdTime) values
<foreach collection="supplierMany" item="supplier" separator=",">
(#{supplier.supCode}, #{supplier.supName}, #{supplier.supContact}, #{supplier.supPhone}, #{supplier.supFax},#{supplier.createdTime})
</foreach>
</insert>
(3)写测试方法
@Test
public void insertManySupplierNotID() throws Exception{
List<Supplier> list=new ArrayList<>();
SimpleDateFormat ft=new SimpleDateFormat("yyyy-MM-dd");
Supplier supplier=new Supplier();
supplier.setSupCode("1111");
supplier.setSupName("郑慧婷");
supplier.setSupContact("3333");
supplier.setSupPhone("18593413645");
supplier.setSupFax("020-12345");
supplier.setCreatedTime(ft.parse("2023-09-12"));
Supplier supplier1=new Supplier();
supplier1.setSupCode("2222");
supplier1.setSupName("孙淇");
supplier1.setSupContact("4444");
supplier1.setSupPhone("18593013645");
supplier1.setSupFax("020-123456");
supplier1.setCreatedTime(ft.parse("2023-09-22"));
list.add(supplier);
list.add(supplier1);
SqlSession sqlSession=MyBatisUtil.createSqlSession();
val i = sqlSession.getMapper(SysUserMapper3.class).insertManySupplierNotID(list);
sqlSession.commit();
System.out.println(i);
}
5.使用foreach写一个批量删除
(1)写接口
//批量删除
public int deleteManySupplierNotID(@Param("ids") List<Integer> ids);
(2)写xml文件
<delete id="deleteManySupplierNotID" parameterType="java.util.Iterator">
delete from t_supplier where id in
<foreach collection="ids" open="(" separator="," close=")" item="id">
#{id}
</foreach>
</delete>
(3)写测试方法
@Test
public void deleteManySupplierNotID() throws Exception{
List<Integer> list=new ArrayList<>();
list.add(18);
list.add(19);
SqlSession sqlSession=MyBatisUtil.createSqlSession();
val i = sqlSession.getMapper(SysUserMapper3.class).deleteManySupplierNotID(list);
sqlSession.commit();
System.out.println(i);
}
总结动态 SQL
动态 SQL 就和它的名字一样,赋予了 SQL 一个动态的语法,我们可以根据前端需要的参数,来控制一整条 SQL 语句。本质上,关于动态 SQL 的标签,就是用来拼接或删除 SQL 的,没有其他的作用。
在使用动态 SQL 之前,我们应该先把心中设想好的完完整整的 SQL 写出来,之后再对此 SQL 进行变换,这样一来,便不会出错。