简介:动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
动态sql主要有:
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
接下来我们会详细介绍
环境搭建
1.sql数据库搭建
CREATE TABLE `employee` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `sn` varchar(20) DEFAULT NULL, `salary` decimal(8,2) DEFAULT NULL, `deptId` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; INSERT INTO `employee` VALUES ('1', '赵一', '001', '800.00', '10'); INSERT INTO `employee` VALUES ('2', '倩儿', '002', '900.00', '10'); INSERT INTO `employee` VALUES ('3', '孙三', '003', '800.00', '20'); INSERT INTO `employee` VALUES ('4', '李四', '004', '1000.00', '30'); INSERT INTO `employee` VALUES ('5', '周五', '005', '900.00', '30'); INSERT INTO `employee` VALUES ('6', '吴六', '006', '1200.00', '40'); INSERT INTO `employee` VALUES ('7', '郑七', '007', '1400.00', '10');
我们这里已经搭建好了
2.编写对应的实体类、Mapper 接口及 Mapper XML
实体类
package com.kuang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class employee {
private int id;
private String name;
private String sn;
private double salary;
private int deptId;
}
1.IF语句
使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:
<select id="queryByMinSalary" resultType="employee">
SELECT id, name, sn, salary, deptId
FROM employee
<if test="minSalary != null">
WHERE salary >= #{minSalary}
</if>
</select>
大概意思就是如果minSalary为null 则if后面的自动去掉
若不为null 则会拼接上后面的sql
测试代码
public class test {
@Test
public void queryall()
{
SqlSession session = MybatisUtils.sqlSession();
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
List<employee> employee = mapper.queryByMinSalary(1000);
for (int i = 0; i < employee.size(); i++) {
System.out.println(employee.get(i));
}
}
}
2.where 语句
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
1.编写代码
< 在sql配置文件中打不出来只能转义 下面就是转义了的
<select id="queryByMinSalaryAndMaxSalary" resultType="Employee">
SELECT id, name, sn, salary, deptId
FROM employee
<where>
<if test="minSalary != null">
AND salary >= #{minSalary}
</if>
<if test="maxSalary != null">
AND salary <= #{maxSalary}
</if>
</where>
</select>
2.测试结果
代码
public class test {
@Test
public void queryall()
{
SqlSession session = MybatisUtils.sqlSession();
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
List<employee> employee = mapper.queryByMinSalaryAndMaxSalary(500,1000);
for (int i = 0; i < employee.size(); i++) {
System.out.println(employee.get(i));
}
}
}
3.Set语句
set 元素会动态地在行首插入 SET 关键字,并会 删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
1.sql代码
<update id="update" parameterType="employee">
UPDATE employee
<set>
<if test="name != null">
name = #{name},
</if>
<if test="sn != null">
sn = #{sn},
</if>
<if test="salary != null">
salary = #{salary},
</if>
<if test="deptId != null">
deptId = #{deptId},
</if>
</set>
WHERE id = #{id}
</update>
当if里面为空时 会自动去掉逗号和set。
2.测试代码及结果
@Test
public void update()
{
SqlSession session = MybatisUtils.sqlSession();
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
mapper.update(new employee(1,"李洋静",null,900,10));
}
4. foreach语句
动态 SQL 的另外一个常用的操作需求是对一个集合进行遍历,通常是在构建 IN 条件语句的时候,这里就会使用到 foreach 元素
1.代码
<delete id="batchDelete">
DELETE FROM employee WHERE id IN
<!--
collection 遍历数组或集合的 key 或者属性名
open 遍历开始拼接的字符串
index 遍历索引
item 遍历元素
separator 每遍历元素拼接字符串
close 遍历结束拼接字符串
-->
<foreach collection="ids" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</delete>
一定要在mapper接口用注解里指明集合的名字
int batchDelete(@Param("ids") int[] ids);
2.结果