if判断
查询时携带了哪个字段where条件就按照什么来查询
mapper 接口
代码语言:javascript复制public interface EmployMapperDynamicSQL {
// 携带了哪个字段查询条件就带上这个字段的值
public List<Employee> getEmpsByConditionIf(Employee employee);
}
mapper.xml
代码语言:javascript复制<?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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
<!--查询员工,要求,携带了哪个字段查询条件在查询的时候就带上这个字段的值-->
<select id="getEmpsByConditionIf" resultType="com.sangyu.bean.Employee">
select * from tbl_employee
where
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null && lastName!= """>
and last_name like #{lastName}
</if>
<if test="email != null and email.trim() != """>
and email = #{email}
</if>
<if test="gender==0 or gender == 1">
and gender = #{gender}
</if>
</select>
</mapper>
where查询条件
前面的例子中通过if 条件增加判断where按照什么条件去查询,但是会有一个问题,当传递的参数中前面的没有值where条件 也会在前面加上and
针对上面的问题,可以查询条件中增加 where 1= 1,剩余的if判断语句中都用and
还有一种方式就是使用where标签,mybatis将所有的查询条件拼装sql,多出来的and或者or去掉(只会去掉第一个多出来的and或者or)
Trim标签
使用where条件只会去掉第一个多出来的and或者or,如果后面多出的and或者or,使用where并不能解决。mybatis提供了Trim标签,
代码语言:javascript复制<?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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
<!--查询员工,要求,携带了哪个字段查询条件在查询的时候就带上这个字段的值-->
<select id="getEmpsByConditionIf" resultType="com.sangyu.bean.Employee">
select * from tbl_employee
-- where 1 = 1
<!-- <where>-->
-- prefix = "" 前缀,trim标签体中是整个字符串拼串后的结果,prefix给拼串后的整个字符串加上一个前缀
-- prefixOverrides = "" 前缀覆盖,去掉整个字符串前面多余的字符
-- suffix = "" 后缀 给拼串后的整个字符串加一个后缀
-- suffixOverrides = "" 后缀覆盖 ,去掉整个字符串后多余的字符
<trim prefix="where" suffixOverrides="and">
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null && lastName!= """>
last_name like #{lastName} and
</if>
<if test="email != null and email.trim() != """>
email = #{email} and
</if>
<if test="gender==0 or gender == 1">
gender = #{gender} and
</if>
</trim>
<!-- </where>-->
</select>
</mapper>
choose分支选择(when ,otherwise)
mybaits中的分支选择相当于java中的switch-case
代码语言:javascript复制<?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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
<select id="getEmpsByConditionChoose" resultType="com.sangyu.bean.Employee">
select * from tbl_employee
-- 如果带了id就用id查,如果带了lastName就用lastName查,只会进入其中一个
-- 当所有条件都不满足的时候就输出 otherwise 中的内容
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="lastName!=null">
last_name like #{lastName}
</when>
<when test="email!=null">
email = #{email}
</when>
<otherwise>
gender = 0
</otherwise>
</choose>
</where>
</select>
</mapper>
set和if结合的动态更新
代码语言:javascript复制<?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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
<select id="updateEmp">
update tbl_employee
<set>
<if test="lastName!=null">
last_name=#{lastName},
</if>
<if test="email != null">
email = #{email},
</if>
<if test="gender!= null">
gender = #{gender}
</if>
where id = #{id}
</set>
</select>
</mapper>
foreach 遍历集合
在foreach遍历集合时,如果集合传递的是List(就是在mapper中接口方法定义的参数类型)那么,mybatis会将List封装到map中,map的key默认是list,如果在定义方法的时候定义了@param那么key就是定义的参数名称。foreach标签中的collectin属性值根据是否定义@param决定属性值的内容
代码语言:javascript复制<!-- collection : 执行要遍历的集合-->
<!-- list类型的参数会特殊处理封装在map中,map的key就叫list-->
<!-- item : 将当前遍历出的元素赋值给指定的变量-->
<!-- separator : 每个元素之间的分隔符-->
<!-- open : 遍历出所有结果拼接一个开始的字符-->
<!-- 遍历出所有结果拼接一个结束的字符-->
<!-- 索引,遍历list的时候index就是索引,item 就是当前值-->
<!-- 遍历map的时候index表示的就是map的key,item就是map的值-->
<!-- #{变量名}就能取出变量的值也就是当前遍历出的元素-->
<select id="getEmpsByConditionForeach" resultType="com.sangyu.bean.Employee">
select * from tbl_employee
<foreach collection="ids" item="item_id" separator=","
open="where id in(" close=")">
#{item_id}
</foreach>
</select>
foreach 批量保存
代码语言:javascript复制// mapper接口定义
public interface EmployMapperDynamicSQL {
public void addEmps(@Param("emps") List<Employee> emps);
}
代码语言:javascript复制<!--批量保存 -->
<select id="addEmps">
insert into tbl_employee(last_name,email,gender,d_id)
values
<foreach collection="emps" item = "emp" separator=",">
(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
</foreach>
</select>
image.png
另一种批量保存的方式
dbconfig.properties 修改数据库连接属性allowMultiQueries=true,使用Mysql的批量保存
代码语言:javascript复制jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=false&allowMultiQueries=true
jdbc.username = root
jdbc.password = abcd123456
代码语言:javascript复制<!-- 使用Mysql的批量保存,可以foreach遍历,mysql支持value(),(),()语法-->
<select id="addEmps">
<foreach collection="emps" item="emp" separator=";">
insert into tbl_employee(last_name,email,gender,d_id) values
(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
</foreach>
</select>
bind 绑定
代码语言:javascript复制<!-- bind,可以将OGNL表达式的值绑定到一个变量中,方便后面引用这个变量的值,_parameter参数保存了com.sangyu.bean.Employee这个对象。
所以可以通过OGNL表达式从_parameter参数中获取到Employee的对应属性值
(也就是把_parameter看作了users的别名)。-->
<select id="getEmpsTestInnerParameter" resultType="com.sangyu.bean.Employee">
<bind name="_lastName" value="'%' lastName '%'"/>
select * from tbl_employee
<if test="_parameter != null">
where last_name like #{_lastName}
</if>
</select>
执行测试代码
代码语言:javascript复制@Test
public void Test21() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
EmployMapperDynamicSQL mapper = session.getMapper(EmployMapperDynamicSQL.class);
Employee employee = new Employee();
employee.setLastName("e");
List<Employee> list = mapper.getEmpsTestInnerParameter(employee);
for(Employee employee1 : list){
System.out.println(employee1);
}
} finally {
session.close();
}
}