MyBatis学习-4
- if
- choose(when,otherwise)
- trim(where,set)
- foreach
- sql
上面这些就是我们的动态SQL语句了,他们能够非常方便的组合SQL语句,提高开发人员的效率。
1.if
我们可以再MyBatis的Mapper当中写SQL的时候通过if标签来判断是否在SQL语句中添加某个条件比如我们先写一个通过ID和LastName的模糊搜索:
select * from tbl_employee
<if test="id!=null">
id = #{id}
</if>
and and last_name like #{Lastname}
如果我们的id传入为null,那么我们就只剩下模糊查询了,那怎么办呢,这时候就该我们的where标签了。
2.where
先来段代码解决一下上面的问题
select * from tbl_employee
<where>
<if test="id!=null">
id = #{id}
</if>
<if test="Lastname!=null and Lastname!=""">
and last_name like #{Lastname}
</if>
</where>
的确,从表面上来看,就是多了个where标签而已, 不过实质上, mybatis是对它做了处理,如果标签返回的内容是以AND 或OR 开头的,它会剔除掉第一个多出来的and或者是or。
3.trim
使用tirm你可以自己定义sql语句我先说几个他的属性:
- prefix=“”在语句添加前缀
- prefixOverrides=“”前缀覆盖,去掉整个字符串前面多余的字符
- suffix=“”在语句中添加后缀
- suffixOverrides=“”后缀覆盖,去掉整个字符串后面多余的字符串
下面写一个小小的测试:
先新建一个EmployeeMapperDyamicSQL接口吧
package com.snake_lvyonghao.MyBatis.Dao;
import com.snake_lvyonghao.MyBatis.bean.Employee;
import java.util.List;
public interface EmployeeMapperDyamicSQL {
List<Employee> getEmpsByConditionIF(Employee employee);
List<Employee> getEmpsByConditionTrim(Employee employee);
}
再来一个EmployeeMapperDyamicSQL.xml
<?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.snake_lvyonghao.MyBatis.Dao.EmployeeMapperDyamicSQL">
<!--查询员工,要求携带了哪个字段就带上这个字段的值-->
<select id="getEmpsByConditionIF" resultType="com.snake_lvyonghao.MyBatis.bean.Employee">
select * from tbl_employee
<where>
<if test="id!=null">
id = #{id}
</if>
<if test="Lastname!=null and 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>
</where>
</select>
<!--Tirm-->
<select id="getEmpsByConditionTrim" resultType="com.snake_lvyonghao.MyBatis.bean.Employee">
select * from tbl_employee
<trim prefix="where" suffixOverrides="and" prefixOverrides="and">
<if test="id!=null">
id = #{id}
</if>
<if test="Lastname!=null and 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>
</trim>
</select>
</mapper>
最后放上我们的测试内容:
@Test
public void test07() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDyamicSQL mapper = openSession.getMapper(EmployeeMapperDyamicSQL.class);
Employee employee = new Employee(3,"%h%","huwenhao@lookout.com",null);
// List<Employee> emps = mapper.getEmpsByConditionIF(employee);
// for(Employee emp : emps){
// System.out.println(emp);
// }
List<Employee> emps2 = mapper.getEmpsByConditionTrim(employee);
for(Employee emp : emps2){
System.out.println(emp);
}
}finally {
openSession.close();
}
}
3.choose
它类似我们的带了break的switch-caes,同样我们先学习两个在choose标签中的的标签
- when标签:就是咱的switch的意思,标签当中的内容自然是咱要执行的内容。
- otherwhen标签:就是当咱所有的when都失败了则之行otherwhen标签中的内容
好的我就先做一个简单的测试,我们按照ID,LastName,email,gender的顺序查找:
首先在接口种生命一个新的方法List<Employee> getEmpsByConditionChoose(Employee employee);
。
然后写上我们的Mapper的配置
<select id="getEmpsByConditionChoose" resultType="com.snake_lvyonghao.MyBatis.bean.Employee">
select * from tbl_employee
<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>
最后当然是我们的测试喽:
@Test
public void test07() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDyamicSQL mapper = openSession.getMapper(EmployeeMapperDyamicSQL.class);
Employee employee = new Employee(null,null,null,null); System.out.println(emp);
List<Employee> emps3 = mapper.getEmpsByConditionChoose(employee);
for(Employee emp : emps3){
System.out.println(emp);
}
}finally {
openSession.close();
}
}
当然为了测试我们选择在最初的时候把employee初始化参数都为null,怎么测试就看你了。
4.set
set这个在sql中我们通常用来做update操作,但是如果我们想想要在set中添加if语句我们该怎么做,这时候我们就要用到我们的set标签了
同样我们先在接口中声明一个方法List<Employee> getEmpsByConditionForeach(Integer id);
接下来去我们的Mapper中配置一番,我们根据给定的参数,并配合ID,修改传入不为null参数值的列。
<update 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>
</set>
<where>
id = #{id}
</where>
</update>
在写一个测试run一下看看:
try {
EmployeeMapperDyamicSQL mapper = openSession.getMapper(EmployeeMapperDyamicSQL.class);
Employee employee = new Employee(5,"lvyong","snake_lvyonghao@163.com","1");
mapper.updateEmp(employee);
openSession.commit();
5.foreach
foreach类似我们程序设计语言当中的for:each,在学习之前我们先来看看他的两个属性有什么作用:
- collection:指定要遍历的集合(List类型的参数会被封装在Map当中,Map的key就叫list)
- item:将当前遍历出的元素赋值给指定的元素
- #{变量名}:就是取出item里变量的值,也就是当前遍历出的元素
- separator:元素和元素之间的分隔符
- open:以什么开始,�遍历所有的结果拼接一个开始的字符
- close:以什么结束,遍历所有的结果拼接一个结束的字符
- index:遍历list是index就是索引,item就是当前的值,遍历Map的时候index表示的就是map的key,item就是map的值
好我们先来在接口中写一个方法List<Employee> getEmpsByConditionForeach(List<Integer> list);
。
然后在Mapper中来学习一下如何使用上面的属性吧,我希望能够根据Id去查询,并把结果封装到一个List当中去:
<select id="getEmpsByConditionForeach" resultType="com.snake_lvyonghao.MyBatis.bean.Employee">
SELECT * from tbl_employee
<foreach collection="list" item="item_id" separator="," open="where id in(" close=")">
#{item_id}
</foreach>
</select>
最后我们在测试类中它他进行测试:
@Test
public void test07() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDyamicSQL mapper = openSession.getMapper(EmployeeMapperDyamicSQL.class);
Employee employee = new Employee(5,"lvyong","snake_lvyonghao@163.com","1");
List<Employee> emps4 = mapper.getEmpsByConditionForeach(Arrays.asList(1,2,3,4));
for (Employee emp : emps4){
System.out.println(emp);
}
openSession.commit();
}finally {
openSession.close();
}
}
批量操作用foreach真是太方便了,我还写了一个批量增加的,这里我就只放上一个Mapper的代码,具体的代码通过Github上的项目来看吧:
<insert id="addEmps">
insert into tbl_employee(last_name,email,gender,d_id)
<foreach collection="emps" item="emp" separator="," open="VALUES">
(#{emp.Lastname},#{emp.email},#{emp.gender},#{emp.department.id})
</foreach>
</insert>
6.sql && include
类似程序设计语言中的宏定义,sql抽取可重用的sql片段动态SQL语句也是可以的,include引用sql片段,还可以自定义一些property,sql标签内部就能使用自定义的属性${},我来简单的举个例子:
<sql id="insertColumn">
id,last_name,email,${test}
</sql>
<!--引用的时候-->
<inlucde refid="insertColumn">
<property name="test" value="abc"/>
</include>
7.其他参数
这里我们再介绍两个额外的参数:
- _parameter:代表整个参数,如果是单个参数就代表这个参数,如果是多个参数就会封装成一个Map,代表这个Map
- _databaseId:如果在数据库的配置文件中配置了detabaseIdProvider标签,就代表当前数据库的别名,通常用动态的SQL中的if语句判断当前数据库类型,然后执行不同的SQL语句