接着上篇MyBatis--代理模式实现数据库增删改查,对于某些需要拼接的复杂SQL语句,MyBatis在映射文件中预定义了一些标签,可以利用这些标签来方便拼接自己的逻辑
一、if标签
顾名思义,if标签就是用来实现if判断的
实现根据员工对象获取员工信息,员工对象中的单个属性为空,则不参与查询条件
定义接口方法:
/**
* 根据员工对象获取员工信息
* @param emp
* @return
*/
List<Emp> findByEmp(Emp emp);
映射文件新增查询:
<!--List<Emp> findByEmp(Emp emp);-->
<select id="findByEmp" resultType="emp">
select * from emp where 1 = 1
<if test="empno != null ">
and empno = #{empno}
</if>
<if test="ename != null ">
and ename = #{ename}
</if>
<if test="job != null ">
and job = #{job}
</if>
<if test="mgr != null ">
and mgr = #{mgr}
</if>
<if test="hiredate != null ">
and hiredate = #{hiredate}
</if>
<if test="sal != null ">
and sal = #{sal}
</if>
<if test="comm != null ">
and comm = #{comm}
</if>
<if test="deptno != null ">
and deptno = #{deptno}
</if>
</select>
测试方法:
// 根据员工信息动态sql查询员工 -- if
@Test
public void test1() {
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = new Emp();
emp.setDeptno(20);
List<Emp> result = mapper.findByEmp(emp);
result.forEach(System.out::println);
}
二、where标签
上面我们在where后面跟了个 1 = 1,原因是不加会形成where and ename = ...这种情况,那么sql语句就出错了,也可以直接使用where标签替代
通过where标签查询员工信息
映射文件使用where标签:
<!--List<Emp> findByEmp(Emp emp);-->
<select id="findByEmp" resultType="emp">
select * from emp
<where>
<if test="empno != null ">
and empno = #{empno}
</if>
<if test="ename != null ">
and ename = #{ename}
</if>
<if test="job != null ">
and job = #{job}
</if>
<if test="mgr != null ">
and mgr = #{mgr}
</if>
<if test="hiredate != null ">
and hiredate = #{hiredate}
</if>
<if test="sal != null ">
and sal = #{sal}
</if>
<if test="comm != null ">
and comm = #{comm}
</if>
<if test="deptno != null ">
and deptno = #{deptno}
</if>
</where>
</select>
三、choose标签
choose标签相当于switch语句,并且只要有一个匹配了,就break不往下执行了
choose标签和when标签配合使用
通过choose标签查询员工信息
映射文件:
<select id="findByEmp2" resultType="emp">
select * from emp
<where>
<choose>
<when test="empno != null ">
and empno = #{empno}
</when>
<when test="ename != null ">
and ename = #{ename}
</when>
<when test="job != null ">
and job = #{job}
</when>
<when test="mgr != null ">
and mgr = #{mgr}
</when>
<when test="hiredate != null ">
and hiredate = #{hiredate}
</when>
<when test="sal != null ">
and sal = #{sal}
</when>
<when test="comm != null ">
and comm = #{comm}
</when>
<when test="deptno != null ">
and deptno = #{deptno}
</when>
</choose>
</where>
</select>
测试方法:
// 根据员工信息动态sql查询员工 -- choose
@Test
public void test2() {
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = new Emp();
emp.setJob("SALESMAN");
emp.setDeptno(20);
List<Emp> result = mapper.findByEmp2(emp);
result.forEach(System.out::println);
}
结果打印为职位为SALESMAN条件的员工,部门并不生效
四、set标签
set标签用于数据库更新操作
实现更新员工信息
定义接口方法:
/**
* 更新员工信息
* @param emp
* @return
*/
int updateEmp(Emp emp);
映射文件中新增更新:
<!--int updateEmp(Emp emp);-->
<update id="updateEmp">
update emp
<set>
<if test="ename != null and ename != '' ">
,ename = #{ename}
</if>
<if test="job != null and job != '' ">
,job = #{job}
</if>
<if test="mgr != null ">
,mgr = #{mgr}
</if>
<if test="hiredate != null ">
,hiredate = #{hiredate}
</if>
<if test="sal != null ">
,sal = #{sal}
</if>
<if test="comm != null ">
,comm = #{comm}
</if>
<if test="deptno != null ">
,deptno = #{deptno}
</if>
</set>
where empno = #{empno}
</update>
其中要注意的是:if标签中要加上","
测试方法:
// 更新员工信息 -- set
@Test
public void test3() {
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = new Emp();
emp.setEmpno(7499);
emp.setJob("SALESMAN");
emp.setDeptno(20);
int result = mapper.updateEmp(emp);
System.out.println(result);
sqlSession.commit();
}
五、trim标签
set标签相当于在每个if标签中加上"set"前缀,trim标签支持自定义前缀和后缀
set标签实现更新员工信息
映射文件使用trim:
<update id="updateEmp2">
update emp
<trim prefix="set" prefixOverrides=",">
<if test="ename != null and ename != '' ">
,ename = #{ename}
</if>
<if test="job != null and job != '' ">
,job = #{job}
</if>
<if test="mgr != null ">
,mgr = #{mgr}
</if>
<if test="hiredate != null ">
,hiredate = #{hiredate}
</if>
<if test="sal != null ">
,sal = #{sal}
</if>
<if test="comm != null ">
,comm = #{comm}
</if>
<if test="deptno != null ">
,deptno = #{deptno}
</if>
</trim>
where empno = #{empno}
</update>
prefixOverrides表示除去第一个匹配的前缀,相应的还有suffixOverrides,用于去除第一个匹配的后缀
六、bind标签
bind标签一般用于模糊查询的模板
实现根据姓名模糊查询员工信息
定义接口方法:
/**
* 根据姓名模糊查询员工信息
* @param ename
* @return
*/
List<Emp> findByEname(String ename);
映射文件新增查询:
<!--List<Emp> findByEname(String ename);-->
<select id="findByEname" resultType="emp">
<bind name="likeEname" value="'%'+ename+'%'"/>
select * from emp where ename like #{likeEname}
</select>
测试方法:
// 根据姓名模糊查询员工信息 -- bind
@Test
public void test5() {
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> result = mapper.findByEname("a");
result.forEach(System.out::println);
}
七、sql标签
sql标签就是预定义一些常用的字符串当作变量
sql标签与include标签配合使用
在映射文件中定义包含所有表字段的变量,争对上面的模糊查询进行修改
原:
<!--List<Emp> findByEname(String ename);-->
<select id="findByEname" resultType="emp">
<bind name="likeEname" value="'%'+ename+'%'"/>
select * from emp where ename like #{likeEname}
</select>
修改后:
<sql id="empColumn">empno,ename,job,mgr,hiredate,sal,comm,deptno</sql>
<sql id="baseSelect">select <include refid="empColumn"/> from emp</sql>
<!--List<Emp> findByEname(String ename);-->
<select id="findByEname" resultType="emp">
<bind name="likeEname" value="'%'+ename+'%'"/>
<include refid="baseSelect" /> where ename like #{likeEname}
</select>
八、foreach标签
foreach标签用于将数组或List集合拼接
实现根据部门编号数组查询员工信息
定义接口方法:
/**
* 根据部门编号数组查询员工信息
* @param deptnos
* @return
*/
List<Emp> findByDeptnoArray(int[] deptnos);
映射文件中使用foreach:
<!--
collection: array表示数组 list表示集合
open: 闭合的前缀
close: 闭合的后缀
separator: 中间元素的分割符
item: 临时元素的变量名
-->
<select id="findByDeptnoArray" resultType="emp">
select * from emp where deptno in
<foreach collection="array" open="(" close=")" separator="," item="deptno">
#{deptno}
</foreach>
</select>
测试方法:
// 根据部门编号数组查询员工信息 -- foreach
@Test
public void test6() {
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> result = mapper.findByDeptnoArray(new int[]{10, 20});
result.forEach(System.out::println);
}