Mybatis动态SQL——if,where,trim,choose,set.foreach的用法
知识点:主要介绍mybatis中,动态sql中的if,where,trim,set,foreach的用法
自学谷粒学院mybatis学习视频,参考mybatis官方文档
java包:log4j.jar
mybatis-3.4.1jar
mysql-connector-java-5.1.37-bin.jar
实体类:
Employee.java类
package com.hand.mybatis.bean;
public class Employee {
private Integer eId;
private String eName;
private Integer gender;
private String email;
private Department dept;
public Employee() {
super();
}
public Employee(Integer eId,String eName, Integer gender, String email) {
super();
this.eId=eId;
this.eName = eName;
this.gender = gender;
this.email = email;
}
public Employee(Integer eId, String eName, Integer gender, String email, Department dept) {
super();
this.eId = eId;
this.eName = eName;
this.gender = gender;
this.email = email;
this.dept = dept;
}
public Integer geteId() {
return eId;
}
public void seteId(Integer eId) {
this.eId = eId;
}
public String getEName() {
return eName;
}
public void setEname(String ename) {
this.eName = ename;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Employee [eId=" + eId + ", ename=" + eName + ", gender=" + gender + ", email=" + email + "]";
}
}
Department.java实体类
package com.hand.mybatis.bean;
import java.util.List;
public class Department {
private Integer id;
private String departName;
private List<Employee> empList;
public Department() {
super();
}
public Department(Integer id) {
super();
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDepartName() {
return departName;
}
public void setDepartName(String departName) {
this.departName = departName;
}
public List<Employee> getEmpList() {
return empList;
}
public void setEmpList(List<Employee> empList) {
this.empList = empList;
}
@Override
public String toString() {
return "Department [id=" + id + ", departName=" + departName + "]";
}
}
EmployeeMapperDynamicSQL.java mapper接口
package com.hand.mybatis.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.hand.mybatis.bean.Employee;
public interface EmployeeMapperDynamicSQL {
//使用if
List<Employee> getEmpsByconditionIf(Employee employee);
//使用trim()
List<Employee> getEmpsByconditionTrim(Employee employee);
//使用choose
List<Employee> getEmpsByconditionChoose(Employee employee);
//跟新字段(set)
int updateEmp(Employee employee);
//根据list集合条件,查询集合(foreach遍历list集合条件)
List<Employee> getEmpsByConditionForeach(@Param("idlist") List<Integer> idlist);
//批量保存(foreach插入多条数据)
int addEmpsBatch(@Param("emps") List<Employee> emps);
}
EmployeeMapperDynamicSQL.xml sql映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hand.mybatis.dao.EmployeeMapperDynamicSQL">
<!-- • if
• choose (when, otherwise):分支选择,swtich-case
如果带了eid就用eid查询,如果带了eName就用eName查询,只会进入其中一个
• trim 字符串截取(where(封装查询条件), set(封装修改条件))
• foreach -->
<!-- //使用if -->//一般if用在sql条件的多字段拼接,if判断字段不为null,"",等情况下
<!-- public List<Employee> getEmpsByconditionIf(Employee employee); -->
<!-- 查询员工,要求,携带了那个字段查询条件就带上那个字段的值 -->
<select id="getEmpsByconditionIf" resultType="com.hand.mybatis.bean.Employee">
select * from emp
<where>
<!-- where 1=1 --><!-- test,判断表达式(OGNL)
从参数中取值判断,遇见特殊符号去写转义字符
w3c: ISO 8859-1
&&,&&
"" ""-->
<if test="eId!=null">
eid=#{eId}
</if>
<if test="eName!=null && eName!= """>
and ename like #{eName} //and一般放在字段前面,《where》标签不会报错
</if>
<if test="email!=null and email.trim()!="""> //一些字符如果出错,可以ws3=>HTML ISO-8859-1参考手册里查找对应的字符,如mybatis里写
and email=#{email} 大小与号(><)出错,改成<(<)>(>)则不会报错
</if>
<!-- ognl会进行字符串与数字的转换判断“0”==0 -->
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</where>
</select>
<!-- 使用trim -->
<!-- List<Employee> getEmpsByconditionTrim(Employee employee); -->
<select id="getEmpsByconditionTrim" resultType="com.hand.mybatis.bean.Employee">
select * from emp
<!--后面多出来的and或者or where 标签不能解决
trim标签中是整个字符串拼接后的结果
prefix="":给拼接后的整个字符串加一个前缀
prefixOverrides="":前缀覆盖,去掉整个字符串前面多余的字符
suffix="":后缀 suffix给拼接后的整个字符串加一个后缀
suffixOverrides="" 后缀覆盖,去掉整个字符串后面多余的字符-->
<!-- 自定义字符串的截取规则 -->
<trim prefix="where" suffixOverrides="and">//这里意思是在条件最前加where,去掉每个if条件里的字段后面多余的and,就不会报错
<if test="eId!=null">
eid=#{eId} and
</if>
<if test="eName!=null && eName!= """>
ename like #{eName} and
</if>
<if test="email!=null and email.trim()!=""">
email=#{email} and
</if>
<!-- ognl会进行字符串与数字的转换判断“0”==0 -->
<if test="gender==0 or gender==1">
gender=#{gender}
</if>
</trim>
</select>
<!-- //使用choose
List<Employee> getEmpsByconditionChoose(Employee employee); -->
<select id="getEmpsByconditionChoose" resultType="com.hand.mybatis.bean.Employee">
select * from emp
<where>
<!-- 如果带了eid就用eid查询,如果带了eName就用eName查询,只会进入其中一个 -->
<choose>
<when test="eId!=null">//只会选择一条路径,若同时有两个字段传入,则优先选择前面的字段
eid=#{eId}
</when>
<when test="eName!=null">
ename=#{eName}
</when>
<when test="gender!=null">
gender=#{gender}
</when>
<when test="email!=null">
email=#{email}
</when>
<otherwise>
1=1 //当所有字段都为空时,查询原表中所有记录
</otherwise>
</choose>
</where>
</select>
<!-- //跟新字段 传那个字段跟新那个字段(使用set)
void updateEmp(Employee employee); -->
<update id="updateEmp">
UPDATE emp
<set> <!-- //方法一:使用set标签去掉多余的,号 -->
<if test="eName!=null">
ename=#{eName},
</if>
<if test="gender!=null">
gender=#{gender},
</if>
<if test="email">
email=#{email}
</if>
</set>
<!-- 方法二:使用trim标签去掉多余的,号
<trim prefix="set" suffixOverrides=",">
<if test="eName!=null">
ename=#{eName},
</if>
<if test="gender!=null">
gender=#{gender},
</if>
<if test="email">
email=#{email}
</if>
</trim> -->
WHERE eid=#{eId}
</update>
<!-- //根据list集合条件,查询集合(foreach遍历list集合条件)
List<Employee> getEmpsByConditionForeach(List<Integer> idlist); -->
<select id="getEmpsByConditionForeach" resultType="com.hand.mybatis.bean.Employee">
<!-- select * from emp where eid in(101,102,103) 方法一:in(1,2,3)--> //原始传入多个id的情况,用in(1,2,3)
select * from emp where eid in
<!--
collection:指定要遍历的集合
list类型的参数会特殊处理封装在map中,map的key就是list
item:将当前遍历的元素赋值给指定的变量
separator:每个元素之间的分隔符
open:遍历出所有结果拼接一个开始的字符
close:遍历出所有结果拼接一个结束的字符
index:索引,遍历list的时候,index就是索引,item就是当前值
遍历map的时候index表示就是map的key,item就是map的值
#{变量名}:每个元素之间的分隔符
-->
<foreach collection="idlist" item="itemid" separator=","
open="(" close=")">
#{itemid}
</foreach>
</select>
<!-- 批量保存(foreach插入多条数据两种方法)
int addEmpsBatch(@Param("emps") List<Employee> emps); -->
<!-- MySQL下批量保存,可以foreach遍历 mysql支持values(),(),()语法 --> //推荐使用
<insert id="addEmpsBatch">
INSERT INTO emp(ename,gender,email,did)
VALUES
<foreach collection="emps" item="emp" separator=",">
(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
</foreach>
</insert>
<!-- 这种方式需要数据库连接属性allowMutiQueries=true的支持 --> //在jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true
<!-- <insert id="addEmpsBatch"> 后加上allowMultiQueries=true
<foreach collection="emps" item="emp" separator=";"> 表示可以多次执行insert into语句,中间;不会错
INSERT INTO emp(ename,gender,email,did)
VALUES(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
</foreach>
</insert> -->
</mapper>
代码:https://github.com/shuaishuaihand/mybatis.git