MyBatis——动态SQL的四个常⽤标签(<if>、<where>、
<foreach>、。。。
⽂章⽬录:
1.什么是动态SQL?
动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接SQL 语句。这⾥的条件判断使⽤的表达式为 OGNL 表达式。常⽤的动态 SQL标签有<if>、<where>、<foreach>、<sql>等。
MyBatis 的动态 SQL 语句,与 JSTL 中的语句⾮常相似。
动态 SQL,主要⽤于解决查询条件不确定的情况:在程序运⾏期间,根据⽤户提交的查询条件进⾏查询。提交的查询条件不同,执⾏的 SQL 语句不同。若将每种可能的情况均逐⼀列出,对所有条件进⾏排列组合,将会出现⼤量的SQL 语句。此时,可使⽤动态 SQL 来解决这样的问题。
使⽤动态SQL时,dao接⼝中⽅法的形参要使⽤Java对象。
2.MyBatis中的动态SQL
2.1 动态SQL——if标签
2.1.1 语法格式
<if test="boolean判断结果"> <!--要么为true、要么为false-->
sql语句的部分
</if>
<!-- 对于该标签的执⾏,当 test 的值为 true 时,会将其包含的 SQL ⽚段断拼接到其所在的 SQL 语句中。 -->
2.1.2 应⽤举例
package com.bjpowernode.dao;
import ity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//if
List<Student> selectIf(Student student);
}
<!-- if
test: 使⽤对象的属性值作为条件
-->
<select id="selectIf" resultType="ity.Student">
select *
from student
where id=-1
<if test="name!=null and name!=''">
or name=#{name}
</if>
<if test="age>0">
or age=#{age}
</if>
</select>
<!--
<if/>标签的中存在⼀个⽐较⿇烦的地⽅:需要在 where 后⼿⼯添加 id=-1的⼦句。
因为,若 where 后的所有<if/>条件均为 false,⽽ where 后若⼜没有 id=-1 ⼦句,则 SQL 中就会只剩下⼀个空的 where,SQL 出错。所以,在where 后,需要添加⼦句 id=-1,以防⽌这种情况的发⽣。但当数据量很⼤时,会严重影响查询效率。
-->
@Test
public void testSelectIf() {
SqlSession session = SqlSession();
StudentDao Mapper(StudentDao.class);
Student student=new Student();
student.setName("张起灵");
student.setAge(20);
List<Student> students=studentDao.selectIf(student);
students.forEach( stu -> System.out.println("stu === " + stu) );
session.close();
}
根据上⾯三个代码块,将其中的内容转为等价的 sql 语句如下:
select *
from student
where id=-1 or name="张起灵" or age=20
2.2 动态SQL——where标签
2.2.1 语法格式
<where>
其他动态sql
</where>
2.2.2 应⽤举例
package com.bjpowernode.dao;
import ity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//where
List<Student> selectWhere(Student student);
}
<!-- where -->
<select id="selectWhere" resultType="ity.Student">
select *
from student
<where>
<if test="name!=null and name!=''">
or name=#{name}
</if>
<if test="age>0">
or age=#{age}
</if>
</where>
</select>
<!--
使⽤<where/>标签,在有查询条件时,可以⾃动添加上 where ⼦句;没有查询条件时,不会添加 where ⼦句。
需要注意的是,第⼀个<if/>标签中的SQL ⽚断,可以不包含 and。不过,写上 and 也不错,where标签会将离它最近的 and 或者 or 删掉。
但其它<if/>中 SQL ⽚断的 and,必须要求写上。否则 SQL 语句将拼接出错
-->
@Test
public void testSelectWhere() {
SqlSession session = SqlSession();
StudentDao Mapper(StudentDao.class);
Student student=new Student();
student.setName("张起灵");
student.setAge(20);
List<Student> students=studentDao.selectWhere(student);
students.forEach( stu -> System.out.println("stu === " + stu) );
session.close();
}
根据上⾯三个代码块,将其中的内容转为等价的 sql 语句如下:
select *
from student
where id=-1 or name="张起灵" or age=20
2.3 动态SQL——foreach标签
2.3.1 语法格式
<foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separator="集合成员之间的分隔符">    #{item的值}
</foreach>
<!--
如果dao接⼝中⽅法的形参是数组,则collection="array"
如果dao接⼝中⽅法的形参是List,则collection="list"
#item的值}:获取集合成员的值
-->
2.3.2 应⽤举例1(简单类型)
package com.bjpowernode.dao;
import ity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//for-each 1
List<Student> selectForeachOne(List<Integer> idlist);
}
<!-- foreach第⼀种⽅式,循环简单类型的List: List<Integer> -->
<select id="selectForeachOne" resultType="ity.Student">        select *
from student
<if test="list!=null and list.size>0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="stuid">
#{stuid}
</foreach>
</if>
</select>
@Test
public void testSelectForeachOne() {
SqlSession session = SqlSession();
StudentDao Mapper(StudentDao.class);
List<Integer> idlist=new ArrayList<>();
idlist.add(1001);
idlist.add(1002);
jstl条件标签
idlist.add(1003);
List<Student> students=studentDao.selectForeachOne(idlist);
students.forEach( stu -> System.out.println("stu === " + stu));
session.close();
}
根据上⾯三个代码块,将其中的内容转为等价的 sql 语句如下:
select *
from student
where id in (1001,1002,1003)
2.3.2 应⽤举例2(对象类型)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。