MyBatis动态sql
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis动态sql相关的知识,希望对你有一定的参考价值。
什么是动态sql
MyBatis的强大特性之一便是动态sql,之前我们在用JDBC的时候,根据不同条件拼接SQL语句是很痛苦的事情,利用MyBatis的动态sql特性便可以解决这个问题。
动态sql的组成元素
在学习动态sql之前,先来了解下ONGL,什么是ONGL呢?它和EL表达式差不多,是一种功能强大的表达式语言,用来获取和设置Java对象的属性。动态sql的实际使用元素并不多,无非就那几种,但是它们带来了灵活性的同时,很大程度上提高了程序的可读性和可维护性。下面看下组成元素:
1)if元素:简单的条件判断
2)choose(when、otherwise)元素:相当于java中的switch
3)trim、where、set元素:重点,见代码详解
1. sql映射文件
<!--
查询时如果某些条件没有加上可能会出现sql拼装错误的问题
解决方法:
1. 给where后面加上1=1,以后的条件都and xxx.
2. mybatis使用where标签来将所有的查询条件包括在内,mybatis就会将where标签中多余的and或or去除掉
ps:where只会去除掉第一个多出来的or或and
3. 后面多出的and或者or,where标签不能解决,用trim标签解决(自定义字符串截取的规则)
<trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and"></trim>
prefix="": 前缀,
prefixOverrides="":去掉前面的某些字符串,
suffix="":后缀,
suffixOverrides="":去掉后面的某些字符串
-->
<select id="getEmpsByConditionIf" resultType="com.zgz.MyBatis.bean.Employee">
select id, last_name lastName, email, gender from tbl_employee
<where>
<!--
OGNL表达式:
1. test里面写判断的条件
2. 特殊符号要转义
3. ognl表达式会进行字符串和数字的转换判断,如:"1"==1
-->
<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>
<!--
where标签用在查询的时候,写在sql语句外面
set标签用在更新的时候,写在sql语句外面
-->
<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>
<if test="id!=null">
id=#{id}
</if>
</where>
</update>
2.测试的接口方法
//携带了那个字段查询条件就带上这个字段的值
public List<Employee> getEmpsByConditionIf(Employee employee);
//更新操作
public void updateEmp(Employee employee);
3. 测试类
@Test
public void testDynamicSQL() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapperDynamicSQL = openSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(3, "xiaoli", null, null);
//测试where标签
// List<Employee> emps = mapperDynamicSQL.getEmpsByConditionIf(employee);
// for(Employee emp: emps) {
// System.out.println(emp);
// }
//测试set标签
// mapperDynamicSQL.updateEmp(employee);
// openSession.commit(); //手动提交数据
} finally {
openSession.close();
}
}
4)foreach元素:重点,见代码详解
1. sql映射文件
<select id="getEmpsByConditionForeach" resultType="com.zgz.MyBatis.bean.Employee">
select * from tbl_employee where id in
<!--
foreach标签:
collection:指定要遍历的集合,可以是List,数组,Set等集合
item:示集合中每一个元素进行迭代时的别名
separator:各个元素的分隔符
open和close:配置以什么符号将这些集合中的元素包装起来
index:当前元素在集合中的位置下标
-->
<foreach collection="ids" item="item" separator=","
open="(" close=")">
#{item}
</foreach>
</select>
2.测试的接口方法
//测试foreach
public List<Employee> getEmpsByConditionForeach(@Param("ids")List<Integer> ids);
3. 测试类
@Test
public void testDynamicSQL() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapperDynamicSQL = openSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(3, "xiaoli", null, null);
//测试foreach标签
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
ids.add(4);
List<Employee> emps = mapperDynamicSQL.getEmpsByConditionForeach(ids);
for(Employee emp : emps) {
System.out.println(emp);
}
} finally {
openSession.close();
}
}
以上代码均未给出mybatis的主配置文件,自行添加
5)test元素:判断真假
总结
要抓住重点:常用的无非就是if,where,set,foreach一定要掌握。
以上是关于MyBatis动态sql的主要内容,如果未能解决你的问题,请参考以下文章
Mybatis -- 动态Sql概述动态Sql之<if>(包含<where>)动态Sql之<foreach>sql片段抽取
mybatis动态sql之利用sql标签抽取可重用的sql片段
MYBATIS05_ifwherechoosewhentrimsetforEach标签sql片段