由于本部分内容在SQL映射文件中均按序号注释清楚,故在此仅给出SQL映射文件的具体内容和对应接口类的声明方法。具体请以SQL映射文件为提纲进行查阅。
其中,MyBatis中动态SQL的具体测试代码下载地址:https://download.csdn.net/download/bingbeichen/10530663。
SQL映射文件的具体配置如下:
<mapper namespace="com.qiaobc.mybatis.mapper.EmployeeMapper">
<!-- 1. if判断&OGNL: 实现根据传入参数所携带的字段动态调整查询方式 -->
<!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
<select id="getEmpsByConditionIf" resultType="com.qiaobc.mybatis.bean.Employee">
select id, last_name lastName, gender, email from tbl_employee where 1 = 1
<!-- test:判断表达式(OGNL) OGNL的具体使用参照官方文档 -->
<if test="id!=null">
and id = #{id}
</if>
<!-- 特殊字符应写转义字符,如“”需写为''或"" -->
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
</if>
<!-- OGNL会进行字符串和数字的转换判断 -->
<if test="gender==0 or gender==1">
and gender = #{gender}
</if>
<if test="email!=null and email.trim()!=""">
and email = #{email}
</if>
</select>
<!-- 2. 查询时如果某些条件没带可能导致SQL拼装有问题,比如多出一个and -->
<!-- 上一部分采用where 1=1 and的方式进行解决,在此借用where标签 -->
<!-- public List<Employee> getEmpsByConditionWhere(Employee employee); -->
<select id="getEmpsByConditionWhere" resultType="com.qiaobc.mybatis.bean.Employee">
select id, last_name lastName, gender, email from tbl_employee
<!-- where标签可以去掉第一个多出来的and或or,因此应将and或or放在语句之前 -->
<where>
<if test="id!=null">
id = #{id}
</if>
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
</if>
<if test="gender==0 or gender==1">
and gender = #{gender}
</if>
<if test="email!=null and email.trim()!=""">
and email = #{email}
</if>
</where>
</select>
<!-- 3. Trim标签 -->
<!-- public List<Employee> getEmpsByConditionTrim(Employee employee); -->
<select id="getEmpsByConditionTrim" resultType="com.qiaobc.mybatis.bean.Employee">
select id, last_name lastName, gender, email from tbl_employee
<!-- where标签无法去掉后边多出的and或or -->
<!--
prefix="" : 前缀,即给标签体拼装后的字符串加一个前缀
prefixOverrides="" : 前缀覆盖,即去掉整个字符串前面多余的字符
suffix="" : 后缀,即给标签体拼装后的字符串加一个后缀
suffixOverrides="" : 后缀覆盖,即去掉整个字符串后面多余的字符
-->
<trim prefix="where" suffixOverrides="and">
<if test="id!=null">
id = #{id} and
</if>
<if test="lastName!=null and lastName!=''">
last_name like #{lastName} and
</if>
<if test="gender==0 or gender==1">
gender = #{gender} and
</if>
<if test="email!=null and email.trim()!=""">
email = #{email}
</if>
</trim>
</select>
<!-- 4. choose标签:分支选择,只会进入其中一个,如带有id就按id查询,带有name就按name查询 -->
<!-- 5. set标签:封装修改条件 -->
<!-- public Boolean updateEmp(Employee employee); -->
<update id="updateEmp">
update tbl_employee
<set>
<if test="lastName!=null">
last_name = #{lastName},
</if>
<if test="gender!=null">
gender = #{gender},
</if>
<if test="email!=null">
email = #{email}
</if>
</set>
where id = ${id}
</update>
<!-- 6. foreach标签:遍历集合 -->
<!-- public List<Employee> getEmpsByConditionForeach(List<Integer> ids); -->
<select id="getEmpsByConditionForeach" resultType="com.qiaobc.mybatis.bean.Employee">
select id, last_name lastName, gender, email from tbl_employee where id in
<!--
collection: 指定要遍历的集合;List类型的参数会特殊处理封装在Map中,Map的key就叫List
item: 将当前遍历的集合元素赋值给指定的变量
separator: 标签体中各元素间的分隔符
open: 为标签体遍历完成的字符串拼接一个开始字符
close: 为标签体遍历完成的字符串拼接一个结束字符
index: 索引。遍历List时index为索引,item为值;
遍历Map时,index为Map对象的key, item为Map对象的value
#{变量名}:取出变量值,即获取当前遍历出的元素。
-->
<foreach collection="ids" item="emp_id" separator="," open="(" close=")">
#{emp_id}
</foreach>
</select>
<!-- 7. foreach标签 -->
<!-- public void insertEmps(@Param("emps") List<Employee> emps); -->
<!-- 7.1 批量保存方式一:MySQL支持values(),(),()语法 -->
<insert id="insertEmps">
insert into tbl_employee(last_name, gender, email, dept_id)
values
<foreach collection="emps" item="emp" separator=",">
(#{emp.lastName}, #{emp.gender}, #{emp.email}, #{emp.dept.id})
</foreach>
</insert>
<!-- 7.2 批量保存方式二:需要MySQL数据库连接属性allowMultiQueries=true -->
<!-- 直接设置:jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true -->
<insert id="insertEmps">
<foreach collection="emps" item="emp" separator=";">
insert into tbl_employee(last_name, gender, email, dept_id)
values(#{emp.lastName}, #{emp.gender}, #{emp.email}, #{emp.dept.id})
</foreach>
</insert>
<!-- Oracle数据库批量保存:Oracle不支持values(),(),()方式,只支持如下两种方式:
1).多个insert放在begin - end里面
begin
insert into employees(employee_id,last_name,email)
values(employees_seq.nextval,'test_001','test_001@163.com');
insert into employees(employee_id,last_name,email)
values(employees_seq.nextval,'test_002','test_002@163.com');
end;
2).利用中间表:
insert into employees(employee_id,last_name,email)
select employees_seq.nextval,lastName,email from(
select 'test_a_01' lastName,'test_a_e01' email from dual
union
select 'test_a_02' lastName,'test_a_e02' email from dual
union
select 'test_a_03' lastName,'test_a_e03' email from dual
)
-->
<!-- 8. 内置参数_parameter与_databaseId -->
<!--
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装为一个map;_parameter就是代表这个map
_databaseId:若配置了databaseIdProvider标签,则_databaseId即代表当前数据库的别名
-->
<!--public List<Employee> getEmpsTestInnerParameter(Employee employee); -->
<select id="getEmpsTestInnerParameter" resultType="com.qiaobc.mybatis.bean.Employee">
<!-- 9. bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值 -->
<bind name="_lastName" value="'%'+lastName+'%'"/>
<if test="_databaseId=='mysql'">
select * from tbl_employee
<if test="_parameter!=null">
where last_name like #{_lastName}
</if>
</if>
<if test="_databaseId=='oracle'">
select * from employees
<if test="_parameter!=null">
where last_name like #{_parameter.lastName}
</if>
</if>
</select>
<!-- 10. 抽取可重用的SQL片段,以方便多处引用
1).sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
2).使用include标签来引用已经抽取的SQL片段
3).include标签还可自定义property,sql标签内部即能使用自定义的属性
include-property:取值的正确方式${prop},而不能使用#{}的方式
-->
<sql id="insertColumn">
<if test="_databaseId=='oracle'">
employee_id,last_name,email
</if>
<if test="_databaseId=='mysql'">
last_name,email,gender,d_id
</if>
</sql>
</mapper>
对应接口类的声明方法如下:
public interface EmployeeMapper {
public List<Employee> getEmpsByConditionIf(Employee employee);
public List<Employee> getEmpsByConditionWhere(Employee employee);
public List<Employee> getEmpsByConditionTrim(Employee employee);
public Boolean updateEmp(Employee employee);
public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids);
public void insertEmps(@Param("emps") List<Employee> emps);
}