前言
在实际项目开发中,经常需要根据不同的条件去做不同的CRUD。总不能根据有一个条件就创建一个查询方法吧,再或者,要删除多条数据的时候,也总不能循环去调用删除方法,比如像这样
for(Integer id : ids) {
userDao.deleteUserById(id);
}
这样会不停的获取数据库连接,资源消耗是很大的(第六篇深入对比了这种方式的问题,总之比较严重)。
在Mybatis中就针对这个问题有一个特性,就是动态SQL,可以很简单的解决这个问题。
动态SQL元素和使用JSTL或其他类似基于XML的文本处理器相似,Mybatis采用功能强大的基于OGNL的表达式来完成动态SQL。OGNL的表达式可以被用在任意的SQL映射语句中。
在Mybatis中,常用的动态SQL元素包括:
>if
>choose(when、otherwise)
>where
>set
>foreach
>bind
下面就根据每个标签依依做一个示例。
首先搭建Mybatis环境和日志环境搭建mybatis环境和日志环境(参考第一篇和第二篇),并创建如下一张表tb_emp(id、姓名、地址和状态)和相应的持久层对象,插入几条数据:
if标签
if的逻辑就和java语言的条件分支语句if的逻辑是一样的,代表判断,同样也只能接受true或false作为运算结果。
现在就根据地址和状态去做一个员工查询,但是状态是一个可变条件。
mapper文件、dao层接口
<mapper namespace="com.zepal.mybatis.dao.EmpDao">
<resultMap type="com.zepal.mybatis.domain.Emp" id="empMap">
<id column="emp_id" property="empId"/>
<result column="emp_name" property="empName"/>
<result column="emp_addr" property="empAddr"/>
<result column="emp_status" property="empStatus"/>
</resultMap>
<select id="getEmpByAddrAndStatus" parameterType="map" resultMap="empMap">
SELECT * FROM tb_emp
WHERE emp_addr = #{empAddr}
<!-- 注意这里 -->
<if test="empStatus != null">
AND emp_status = #{empStatus}
</if>
;
</select>
</mapper>
public interface EmpDao {
List<Emp> getEmpByAddrAndStatus(Map<String, Object> paramMap);
}
因为typeAliases(参照第二篇配置)的关系,Mybatis可以接收任何java对象和数据类型作为参数,这里以Map作为参数传递,typeAliases已经为常用的java对象作了处理,所以这里parameterType不用全路径。
上面的<if>标签,作为可选条件,如果传进mapper中的empStatus不为null则带上emp_status条件查询。
测试代码及结果
public class Test {
public static void main(String[] args) {
InputStream is = Test.class.getResourceAsStream("/mybatis/mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("empAddr", "上海");
paramMap.put("empStatus", "ACTIVE");
List<Emp> emps = empDao.getEmpByAddrAndStatus(paramMap);
System.out.println(emps.toString());
sqlSession.close();
}
}
DEBUG [main] - ==> Preparing: SELECT * FROM tb_emp WHERE emp_addr = ? AND emp_status = ? ;
DEBUG [main] - ==> Parameters: 上海(String), ACTIVE(String)
DEBUG [main] - <== Total: 1
[Emp [empId=2, empName=李四, empAddr=上海, empStatus=ACTIVE]]
<