MyBatis——动态SQL的四个常用标签(<if>、<where>、<foreach>、<sql>)

文章目录:

1.什么是动态SQL? 

2.MyBatis中的动态SQL 

2.1 动态SQL——if标签

2.1.1 语法格式 

2.1.2 应用举例

2.2 动态SQL——where标签

2.2.1 语法格式 

2.2.2 应用举例

2.3 动态SQL——foreach标签

2.3.1 语法格式

2.3.2 应用举例1(简单类型)

2.3.2 应用举例2(对象类型)

2.4 动态SQL——sql标签

2.4.1 语法格式 

2.4.2 应用举例


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 语法格式 


   
   
  1. <if test="boolean判断结果"> <!--要么为true、要么为false-->
  2. sql语句的部分
  3. </if>
  4. <!-- 对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片段断拼接到其所在的 SQL 语句中。 -->

2.1.2 应用举例


   
   
  1. package com.bjpowernode.dao;
  2. import com.bjpowernode.entity.Student;
  3. import java.util.List;
  4. /**
  5. *
  6. */
  7. public interface StudentDao {
  8. //if
  9. List<Student> selectIf (Student student);
  10. }

   
   
  1. <!-- if
  2. test: 使用对象的属性值作为条件
  3. -->
  4. <select id="selectIf" resultType="com.bjpowernode.entity.Student">
  5. select *
  6. from student
  7. where id=-1
  8. <if test="name!=null and name!=''">
  9. or name=#{name}
  10. </if>
  11. <if test="age>0">
  12. or age=#{age}
  13. </if>
  14. </select>
  15. <!--
  16. <if/>标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 id=-1的子句。
  17. 因为,若 where 后的所有<if/>条件均为 false,而 where 后若又没有 id=-1 子句,则 SQL 中就会只剩下一个空的 where,SQL 出错。
  18. 所以,在where 后,需要添加子句 id=-1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。
  19. -->

   
   
  1. @Test
  2. public void testSelectIf () {
  3. SqlSession session = MyBatisUtil.getSqlSession();
  4. StudentDao studentDao=session.getMapper(StudentDao.class);
  5. Student student= new Student();
  6. student.setName( "张起灵");
  7. student.setAge( 20);
  8. List<Student> students=studentDao.selectIf(student);
  9. students.forEach( stu -> System.out.println( "stu === " + stu) );
  10. session.close();
  11. }

根据上面三个代码块,将其中的内容转为等价的 sql 语句如下:👇👇👇 


   
   
  1. select *
  2. from student
  3. where id = -1 or name ="张起灵" or age = 20

2.2 动态SQL——where标签

2.2.1 语法格式 


   
   
  1. <where>
  2. 其他动态sql
  3. </where>

2.2.2 应用举例


   
   
  1. package com.bjpowernode.dao;
  2. import com.bjpowernode.entity.Student;
  3. import java.util.List;
  4. /**
  5. *
  6. */
  7. public interface StudentDao {
  8. //where
  9. List<Student> selectWhere (Student student);
  10. }

   
   
  1. <!-- where -->
  2. <select id="selectWhere" resultType="com.bjpowernode.entity.Student">
  3. select *
  4. from student
  5. <where>
  6. <if test="name!=null and name!=''">
  7. or name=#{name}
  8. </if>
  9. <if test="age>0">
  10. or age=#{age}
  11. </if>
  12. </where>
  13. </select>
  14. <!--
  15. 使用<where/>标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加 where 子句。
  16. 需要注意的是,第一个<if/>标签中的SQL 片断,可以不包含 and。不过,写上 and 也不错,where标签会将离它最近的 and 或者 or 删掉。
  17. 但其它<if/>中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错
  18. -->

   
   
  1. @Test
  2. public void testSelectWhere () {
  3. SqlSession session = MyBatisUtil.getSqlSession();
  4. StudentDao studentDao=session.getMapper(StudentDao.class);
  5. Student student= new Student();
  6. student.setName( "张起灵");
  7. student.setAge( 20);
  8. List<Student> students=studentDao.selectWhere(student);
  9. students.forEach( stu -> System.out.println( "stu === " + stu) );
  10. session.close();
  11. }

根据上面三个代码块,将其中的内容转为等价的 sql 语句如下:👇👇👇  


   
   
  1. select *
  2. from student
  3. where id = -1 or name ="张起灵" or age = 20

2.3 动态SQL——foreach标签

2.3.1 语法格式


   
   
  1. <foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separator="集合成员之间的分隔符">
  2. #{item的值}
  3. </foreach>
  4. <!--
  5. 如果dao接口中方法的形参是数组,则collection="array"
  6. 如果dao接口中方法的形参是List,则collection="list"
  7. #item的值}:获取集合成员的值
  8. -->

2.3.2 应用举例1(简单类型)


   
   
  1. package com.bjpowernode.dao;
  2. import com.bjpowernode.entity.Student;
  3. import java.util.List;
  4. /**
  5. *
  6. */
  7. public interface StudentDao {
  8. //for-each 1
  9. List<Student> selectForeachOne (List<Integer> idlist);
  10. }

   
   
  1. <!-- foreach第一种方式,循环简单类型的List: List<Integer> -->
  2. <select id="selectForeachOne" resultType="com.bjpowernode.entity.Student">
  3. select *
  4. from student
  5. <if test="list!=null and list.size>0">
  6. where id in
  7. <foreach collection="list" open="(" close=")" separator="," item="stuid">
  8. #{stuid}
  9. </foreach>
  10. </if>
  11. </select>

   
   
  1. @Test
  2. public void testSelectForeachOne () {
  3. SqlSession session = MyBatisUtil.getSqlSession();
  4. StudentDao studentDao=session.getMapper(StudentDao.class);
  5. List<Integer> idlist= new ArrayList<>();
  6. idlist.add( 1001);
  7. idlist.add( 1002);
  8. idlist.add( 1003);
  9. List<Student> students=studentDao.selectForeachOne(idlist);
  10. students.forEach( stu -> System.out.println( "stu === " + stu));
  11. session.close();
  12. }

根据上面三个代码块,将其中的内容转为等价的 sql 语句如下:👇👇👇   


   
   
  1. select *
  2. from student
  3. where id in ( 1001, 1002, 1003)

2.3.2 应用举例2(对象类型)


   
   
  1. package com.bjpowernode.dao;
  2. import com.bjpowernode.entity.Student;
  3. import java.util.List;
  4. /**
  5. *
  6. */
  7. public interface StudentDao {
  8. //for-each 2
  9. List<Student> selectForeachTwo (List<Student> studentList);
  10. }

   
   
  1. <!-- foreach第二种方式,循环对象类型的List: List<Student> -->
  2. <select id="selectForeachTwo" resultType="com.bjpowernode.entity.Student">
  3. select *
  4. from student
  5. <if test="list!=null and list.size>0">
  6. where id in
  7. <foreach collection="list" open="(" close=")" separator="," item="stu">
  8. #{stu.id}
  9. </foreach>
  10. </if>
  11. </select>

   
   
  1. @Test
  2. public void testSelectForeachTwo () {
  3. SqlSession session = MyBatisUtil.getSqlSession();
  4. StudentDao studentDao=session.getMapper(StudentDao.class);
  5. List<Student> list= new ArrayList<>();
  6. Student s1= new Student();
  7. s1.setId( 1001);
  8. Student s2= new Student();
  9. s2.setId( 1002);
  10. Student s3= new Student();
  11. s3.setId( 1003);
  12. list.add(s1);
  13. list.add(s2);
  14. list.add(s3);
  15. List<Student> students=studentDao.selectForeachTwo(list);
  16. students.forEach( stu-> System.out.println( "stu === " + stu));
  17. session.close();
  18. }

根据上面三个代码块,将其中的内容转为等价的 sql 语句如下:👇👇👇    


   
   
  1. select *
  2. from student
  3. where id in ( 1001, 1002, 1003)

2.4 动态SQL——sql标签

2.4.1 语法格式 


   
   
  1. <sql id="...">
  2. sql语句
  3. </sql>
  4. <include refid="sql标签的id属性值"> </include>
  5. <!--
  6. <sql/>标签用于定义 SQL 片断,以便其它 SQL 标签复用。
  7. 而其它标签使用该 SQL 片断,需要使用<include/>子标签。
  8. 该<sql/>标签可以定义 SQL 语句中的任何部分,所以<include/>子标签可以放在动态 SQL 的任何位置。
  9. -->

2.4.2 应用举例


   
   
  1. package com.bjpowernode.dao;
  2. import com.bjpowernode.entity.Student;
  3. import java.util.List;
  4. /**
  5. *
  6. */
  7. public interface StudentDao {
  8. //代码片段
  9. List<Student> selectSql (List<Student> studentList);
  10. }

   
   
  1. <!-- 定义代码片段 -->
  2. <sql id="selectStudent">
  3. select id,name,age from student
  4. </sql>
  5. <sql id="studentFieldList">
  6. where id in
  7. </sql>
  8. <select id="selectSql" resultType="com.bjpowernode.entity.Student">
  9. <include refid="selectStudent"> </include>
  10. <if test="list!=null and list.size>0">
  11. <include refid="studentFieldList"> </include>
  12. <foreach collection="list" open="(" close=")" separator="," item="student">
  13. #{student.id}
  14. </foreach>
  15. </if>
  16. </select>

   
   
  1. @Test
  2. public void testSelectSql () {
  3. SqlSession session = MyBatisUtil.getSqlSession();
  4. StudentDao studentDao=session.getMapper(StudentDao.class);
  5. List<Student> list= new ArrayList<>();
  6. Student s1= new Student();
  7. s1.setId( 1001);
  8. Student s2= new Student();
  9. s2.setId( 1002);
  10. Student s3= new Student();
  11. s3.setId( 1003);
  12. list.add(s1);
  13. list.add(s2);
  14. list.add(s3);
  15. List<Student> students=studentDao.selectSql(list);
  16. students.forEach( stu-> System.out.println( "stu === " + stu));
  17. session.close();
  18. }

根据上面三个代码块,将其中的内容转为等价的 sql 语句如下:👇👇👇     


   
   
  1. select id,name,age
  2. from student
  3. where id in ( 1001, 1002, 1003)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
当使用MyBatis进行动态SQL的编写时,通常会使用以下标签: 1. <if>标签:用于判断条件是否成立,如果成立则执行内部的SQL语句,否则忽略。 ``` <select id="getUserList" resultType="User"> SELECT * FROM user WHERE 1=1 <if test="username != null"> AND username = #{username} </if> <if test="age != null"> AND age = #{age} </if> </select> ``` 2. <where>标签:用于拼接WHERE子句,如果内部有任何一个条件成立,则WHERE子句会自动添加到SQL语句中。 ``` <select id="getUserList" resultType="User"> SELECT * FROM user <where> <if test="username != null"> AND username = #{username} </if> <if test="age != null"> AND age = #{age} </if> </where> </select> ``` 3. <set>标签:用于拼接SET子句,用于更新表中的数据。 ``` <update id="updateUser" parameterType="User"> UPDATE user <set> <if test="username != null"> username = #{username}, </if> <if test="age != null"> age = #{age}, </if> </set> WHERE id = #{id} </update> ``` 4. <trim>标签:用于去除SQL语句中的逗号或AND/OR等无用的字符。 ``` <select id="getUserList" resultType="User"> SELECT * FROM user <trim prefix="WHERE" prefixOverrides="AND |OR "> <if test="username != null"> AND username = #{username} </if> <if test="age != null"> AND age = #{age} </if> </trim> </select> ``` 5. <foreach>标签:用于循环遍历集合或数组,并将其作为参数传递给SQL语句中。 ``` <select id="getUserListByIdList" resultType="User"> SELECT * FROM user WHERE id IN <foreach collection="idList" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值