3,动态SQL
动态 SQL 是 MyBatis 的强大特性之一。借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了易用性。
3.1,if
使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。
例如:给员工增加一个按姓名查询的方法:
List<Employee> getEmployeeLikeName(String name);
实现:
<select id="getEmployeeLikeName" resultType="Employee">
select id,name,age from tb_employee
<if test="name != null and name != ''">
where name like #{name}
</if>
</select>
3.2,SQL片段
为了重用一些语句,我们可以使用 sql 标签来定义一些共用的代码形成 SQL 片段。定义方式为:
<sql id="columns">id,name,age</sql>
它有一个必须属性是id,用于给这个sql片段一个引用名称,共用代码写在这个标签中间。
定义好后,在使用的地方通过 <include refid="id属性名"/>
进行使用
例:
<select id="getEmployeeLikeName" resultType="Employee">
select <include refid="columns" /> from tb_employee
<if test="name != null and name != ''">
where name like #{name}
</if>
</select>
3.3,choose,when,otherwise
MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
添加方法:
按照name和age查询们都满足的话返回数据。
List<Employee> getEmployeesByCondition(@Param("name") String name, @Param("age") int age);
实现:
<sql id="mysql">select id,name,age from tb_employee</sql>
<select id="getEmployeesByCondition" resultType="Employee">
<include refid="mysql"/> where id=5
<choose>
<when test="name != null">
and name=#{name}
</when>
<when test="age > 0">
and age=#{age}
</when>
<otherwise>
and 1=1
</otherwise>
</choose>
</select>
3.4,trim,where,set
3.4.1,where
不使用where:
<select id="getEmployeesByCondition" resultType="Employee">
<include refid="mysql"/> where 1=1
<if test="name != null and name != ''">
and name=#{name}
</if>
<if test="age > 0">
and age=#{age}
</if>
</select>
使用where
<select id="getEmployeesByCondition" resultType="Employee">
<include refid="mysql"/>
<where>
<if test="name != null and name != ''">
and name=#{name}
</if>
<if test="age > 0">
and age=#{age}
</if>
</where>
</select>
3.4.2,trim
如果 where 元素没有按正常套路使用,我们还可以通过自定义 trim 元素来定制我们想要的功能。
例如:和where等价的自定义trim为:
<trim prefix="where" prefixOverrides="AND |OR">
...
</trim>
3.4.3,set
set 标签用于修改数据时使用。
定义方法:
void update(Employee employee);
实现:
<update id="update">
update tb_employee
<trim prefix="set" suffixOverrides="," prefixOverrides=",">
<if test="name != null and name != ''">
name=#{name},
</if>
<if test="age > 0">
age=#{age},
</if>
</trim>
where id=#{id}
</update>
3.5,foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历。
3.5.1,批量查询
动态 SQL 的另外一个常用的必要操作是对一个集合进行遍历,通常使用 in 来操作。例如,我们查询 id 在 1,2,3,4 的员工信息。
定义方法:
List<Employee> getEmployeesByIn(List<Integer> ids);
实现:
<select id="getEmployeesByIn" resultType="Employee">
select id,name,age from tb_employee where id in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreach 标签属性说明:
- collection:用于指定参数的类型,可以是 list,也可以是 set,还可以是 map,还可以是 array。
- item:用于遍历时的临时变量
- open:开始符号
- close:关闭符号
- separator:分割符
3.5.2,批量插入
定义方法:
void batchInsert(List<Employee> emps);
实现:
<insert id="batchInsert">
insert into tb_employee(name,age) values
<foreach collection="list" item="emp" separator=",">
(#{emp.name}, #{emp.age})
</foreach>
</insert>