一、动态Sql
通过MyBatis提供的各种标签方法实现动态拼接Sql。
这些标签类似于JSTL标签,可以写控制语句动态的拼接Sql
二、if标签、where标签
使用了 <where>标签自动处理 AND 前缀,<where>只处理第一个 AND(如果存在),后续的 AND不会受影响。
如:WHERE name LIKE '%zz%' AND age = 23 AND gender = '女'
<where>会去掉第一个 AND(AND name LIKE...→ name LIKE...),后续的 AND保留。
通过 <if>标签实现条件判断:
当 name不为空时,添加模糊查询条件
当 age不为空时,添加精确匹配条件
当 gender不为空时,添加精确匹配条件
例:
java
<select id="selectByCondition" parameterType="Student" resultMap="studentMap">
SELECT <include refid="studentColumns"/>
FROM student
<where>
<if test="name!=null and name!=''">
AND name LIKE concat('%',#{name},'%')
</if>
<if test="age!=null">
AND age=#{age}
</if>
<if test="gender!=null and name!=''">
AND gender=#{gender}
</if>
</where>
</select>
测试类
@Test
public void testselectByCondition() throws IOException {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
Student stu = new Student();
stu.setName("王");
stu.setGender("女");
List<Student> list = sqlSession.selectList("student.selectByCondition", stu);
for (Student student : list) {
System.out.println(student);
}
}
三、set标签
在更新数据有些时候希望User里面只有属性值有数据的才去做更新操作,属性没有数据的时候不做任何操作还是原来的值。
update user set name=?,age=?,gender=? where id=?;
在根据条件拼接sql时候有一个问题,如果想统一处理,最后一个","处理起来麻烦。
<set>标签用于动态生成 SET子句,并自动去除末尾多余的逗号(,)
java
<update id="updateCondition" parameterType="Student">
UPDATE student
<set>
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="age!=null">
age=#{age},
</if>
<if test="gender!=null and gender!=''">
gender=#{gender},
</if>
</set>
WHERE id=#{id}
</update>
测试类
@Test
public void testUpdateCondition() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
Student student = new Student();
student.setId(1);
student.setName("小李1");
student.setAge(25);
//student.setGender("女");
int count = sqlSession.update("student.updateCondition", student);
System.out.println(count);
sqlSession.commit();
}
四、foreach标签
处理数组或者集合,MyBatis使用foreach标签解析。
做一个批量删除的操作,参数可以是集合或是数组的形式传递过来:int[] idArray = {1,2,3,4};、List idList;
java
<delete id="deleteAllByArray">
DELETE FROM student
WHERE id IN
<foreach collection="array" open="(" item="id" close=")" separator=",">
#{id}
</foreach>
</delete>
测试类
@Test
public void testDeleteAllByArray() {
int[] array = {8,9,11};
SqlSession sqlSession = MyBatisUtil.getSqlSession();;
int count = sqlSession.delete("student.deleteAllByArray", array);
System.out.println("count: " + count);
sqlSession.commit();
sqlSession.close();
}
collection="array":表示参数是一个数组(如 int[]或 String[])。
open="("和 close=")":生成 IN语句的括号 ( )。
separator=",":用逗号分隔多个 ID。
item="id":遍历时的临时变量名,在 #{id}中使用。
collection="list":表示参数是一个 List(如 List<Integer>或 List<String>)。
open="("和 close=")":生成 IN语句的括号 ( )。
separator=",":用逗号分隔多个 ID。
item="id":遍历时的临时变量名,在 #{id}中使用。
java
<delete id="deleteAllByList">
DELETE FROM student
WHERE id IN
<foreach collection="list" open="(" item="id" close=")" separator=",">
#{id}
</foreach>
</delete>
测试类
@Test
public void testDeleteAllByList() {
List<Integer> list = new ArrayList<>();
list.add(4);
list.add(6);
SqlSession sqlSession = MyBatisUtil.getSqlSession();;
int count = sqlSession.delete("student.deleteAllByList", list);
System.out.println("count: " + count);
sqlSession.commit();
sqlSession.close();
}
五、choose、when、otherwise
if----else if----else if ----else
<choose>、<when>、<otherwise> 标签实现多条件分支选择,只会执行第一个满足条件的 <when>分支,后续条件即使成立也会被忽略。
例如:
如果用户填写了名字,这个搜索就按照名字来搜索,你即使填写了别的条件也不去拼接,
如果没有填写名字,填写了年龄,就按照年龄来搜索,
如果名字和年龄都没有填写,但是填写了性别就按照性别来查找
name、age、gender搜索时候只能按照其中一个来搜索,但是优先级name>age>gender
执行逻辑
1.按顺序检查 <when>条件:
如果 name非空,生成 name LIKE '%值%',忽略后续条件。
如果 name为空但 age非空,生成 age=值,忽略后续条件。
如果 name和 age都为空但 gender非空,生成 gender=值。
2.所有条件都不满足:<otherwise>为空,最终 SQL 可能变成 WHERE后无内容(需注意语法错误)。
java
<select id="selectByCondition2" parameterType="Student" resultMap="studentMap">
SELECT <include refid="studentColumns"/>
FROM student
WHERE
<choose>
<when test="name!=null and name!='' ">
name LIKE concat('%',#{name},'%')
</when>
<when test="age!=null">
age=#{age}
</when>
<when test="gender!=null and gender!=''">
gender=#{gender}
</when>
<otherwise></otherwise>
</choose>
</select>
@Test
public void testSelectByCondition1() {
Student student = new Student();
//student.setName("王");
student.setAge(23);
student.setGender("女");
SqlSession sqlSession = MyBatisUtil.getSqlSession();
List<Student> list = sqlSession.selectList("student.selectByCondition2", student);
for (Student s : list) {
System.out.println(s);
}
}
六、trim
MyBatis 中的<trim>标签是一个特殊的动态 SQL 元素,它用于在动态生成 SQL 语句时自动添加或删除前后缀,以及在多个元素之间添加分隔符。这在构建包含多个可选部分的 SQL 语句时非常有用,例如在 INSERT、UPDATE 或 WHERE 子句中。
<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="" ></trim>
<trim>标签提供了以下几个属性:
- prefix:在生成的 SQL 中添加的前缀。
- prefixOverrides:用于删除前缀中的特定字符。
- suffix:在生成的 SQL 中添加的后缀。
- suffixOverrides:用于删除后缀中的特定字符。与 prefixOverrides 类似,但用于删除尾随的字符。