一、动态SQL

动态SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据提交的查询条件进行查询。

动态SQL,即通过MyBatis提供的各种标签对条件作出判断以实现动态拼接SQL语句。

二、使用动态SQL原因

提供的查询条件不同,执行的SQL语句不同。若将每种可能的情况均逐一列出,就将出现大量的SQL语句。

三、<if/>标签

注意事项:

(1)

  1. @Test
  2. public void test08() {
  3. Student stu = new Student("明", 20, 0);
  4. List<Student> students = dao.selectStudentsByCondition(stu);
  5. for (Student student : students) {
  6. System.out.println(student);
  7. }
  8.  
  9. }

com.jmu.test.MyTest

  1. public interface IStudentDao {
  2. // 根据条件查询问题
  3. List<Student> selectStudentsByCondition(Student student);
  4. }

com.jmu.dao.IStudentDao

  1. <mapper namespace="com.jmu.dao.IStudentDao">
  2. <select id="selectStudentsByCondition" resultType="Student">
  3. select id,name,age,score
  4. from student
  5. where
  6. <if test="name !=null and name !=''">
  7. name like '%' #{name} '%'
  8. </if>
  9. <if test="age>0">
  10. and age >#{age}
  11. </if>
  12. </select>
  13. </mapper>

mapper.xml

输出:

  1. 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - ==> Preparing: select id,name,age,score from student where name like '%' ? '%' and age >?
  2. 48 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - ==> Parameters: 明(String), 20(Integer)
  3. 96 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - <== Total: 15
  4. Student [id=159, name=明明, score=87.9, age=23]
  5. Student [id=173, name=小明明, score=99.5, age=23]
  6. Student [id=175, name=明明, score=99.5, age=23]
  7. Student [id=177, name=明明, score=99.5, age=23]
  8. Student [id=179, name=明明, score=99.5, age=23]
  9. Student [id=181, name=明明, score=99.5, age=23]
  10. Student [id=183, name=明明, score=99.5, age=23]
  11. Student [id=185, name=明明, score=99.5, age=23]
  12. Student [id=187, name=明明, score=99.5, age=23]
  13. Student [id=189, name=明明, score=99.5, age=23]
  14. Student [id=191, name=明明, score=99.5, age=23]
  15. Student [id=193, name=明明, score=99.5, age=23]
  16. Student [id=195, name=明明, score=99.5, age=23]
  17. Student [id=198, name=明明, score=99.5, age=23]
  18. Student [id=200, name=明明, score=99.5, age=23]

output

(2) 针对第一个值为空,sql语句“where and”出错的情况

  1. // Student stu = new Student("明", 20, 0);
  2. Student stu = new Student("", 20, 0);

  

解决:

四、<where/>标签

当数据量特别大,做“where 1= 1”的判断,就降低了整个系统的执行效率

  1. @Test
  2. public void test02() {
  3. // Student stu = new Student("明", 20, 0);
  4. Student stu = new Student("", 20, 0);
  5. List<Student> students = dao.selectStudentsByWhere(stu);
  6. for (Student student : students) {
  7. System.out.println(student);
  8. }
  9.  
  10. }

com.jmu.test.MyTest

  1. import java.util.List;
  2. import java.util.Map;
  3.  
  4. import com.jmu.bean.Student;
  5.  
  6. public interface IStudentDao {
  7. // 根据条件查询问题
  8. List<Student> selectStudentsByIf(Student student);
  9. List<Student> selectStudentsByWhere(Student student);
  10. }

com.jmu.dao.IStudentDao

  1. <select id="selectStudentsByWhere" resultType="Student">
  2. select id,name,age,score
  3. from student
  4. <where>
  5. <if test="name !=null and name !=''">
  6. and name like '%' #{name} '%'
  7. </if>
  8. <if test="age>0">
  9. and age >#{age}
  10. </if>
  11. </where>
  12. </select>

/mybatis7-dynamicSql/src/com/jmu/dao/mapper.xml

输出:

  1. 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Preparing: select id,name,age,score from student where 1=1 and age >?
  2. 48 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Parameters: 20(Integer)
  3. 86 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - <== Total: 2
  4. Student [id=198, name=明明, score=99.5, age=23]
  5. Student [id=200, name=明明, score=99.5, age=23]
  6. 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >?
  7. 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >?
  8. 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer)
  9. 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer)
  10. 115 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2
  11. 115 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2
  12. Student [id=198, name=明明, score=99.5, age=23]
  13. Student [id=200, name=明明, score=99.5, age=23]

output

五、<choose/>标签

该标签可以包含多个<when/>和一个<otherwise/>,它们联合使用来完成JAVA的开关语句switch...case功能。

  1. <select id="selectStudentsByChoose" resultType="Student">
  2. select id,name,age,score
  3. from student
  4. <where>
  5. <choose>
  6. <when test="name !=null and name !=''">
  7. and name like '%' #{name} '%'
  8. </when>
  9. <when test="age>0">
  10. and age>#{age}
  11. </when>
  12. <otherwise>
  13. 1=2 <!-- false,使得查询不到结果 -->
  14. </otherwise>
  15. </choose>
  16. </where>
  17. </select>

/mybatis7-dynamicSql/src/com/jmu/dao/mapper.xml

  1. import java.util.List;
  2. import java.util.Map;
  3.  
  4. import com.jmu.bean.Student;
  5.  
  6. public interface IStudentDao {
  7. // 根据条件查询问题
  8. List<Student> selectStudentsByIf(Student student);
  9. List<Student> selectStudentsByWhere(Student student);
  10. List<Student> selectStudentsByChoose(Student student);
  11.  
  12. }

com.jmu.dao.IStudentDao

  1. }
  2. @Test
  3. public void test03() {
  4. // Student stu = new Student("明", 20, 0);
  5. Student stu = new Student("", 20, 0);
  6. // Student stu = new Student("", 0, 0);
  7. List<Student> students = dao.selectStudentsByChoose(stu);
  8. for (Student student : students) {
  9. System.out.println(student);
  10. }
  11.  
  12. }

MyTest

输出:

  1. 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Preparing: select id,name,age,score from student where 1=1 and age >?
  2. 50 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Parameters: 20(Integer)
  3. 86 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - <== Total: 2
  4. Student [id=198, name=明明, score=99.5, age=23]
  5. Student [id=200, name=明明, score=99.5, age=23]
  6. 104 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >?
  7. 104 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >?
  8. 105 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer)
  9. 105 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer)
  10. 109 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2
  11. 109 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2
  12. Student [id=198, name=明明, score=99.5, age=23]
  13. Student [id=200, name=明明, score=99.5, age=23]
  14. 121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>?
  15. 121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>?
  16. 121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>?
  17. 122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer)
  18. 122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer)
  19. 122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer)
  20. 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2
  21. 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2
  22. 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2
  23. Student [id=198, name=明明, score=99.5, age=23]
  24. Student [id=200, name=明明, score=99.5, age=23]

output

当查询的条件均不满足时:

  1. Student stu = new Student("", 0, 0);

输出:

六、<foreach/>标签--遍历数组

该标签用于实现对数组与集合的遍历,对其使用需要注意:

  • collection表示要遍历的集合类型,这里是数组,即array。
  • open、close、separate为遍历内容的SQL拼接。
  1. List<Student> selectStudentsByForeach(int[] ids);

com.jmu.dao.IStudentDao

  1. @Test
  2. public void test04() {
  3. int[] ids={197,198,199};
  4. List<Student> students = dao.selectStudentsByForeach(ids);
  5. for (Student student : students) {
  6. System.out.println(student);
  7. }
  8.  
  9. }

MyTest

  1. <select id="selectStudentsByForeach" resultType="Student">
  2. <!-- select id,name,age,score from student where id in (1,3,5) -->
  3. select id,name,age,score
  4. from student
  5. <if test="array.length>0">
  6. where id in
  7. <foreach collection="array" item="myid" open="(" close=")"
  8. separator=",">
  9. #{myid}
  10. </foreach>
  11. </if>
  12. </select>

mapper.xml

输出:

  1. 176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
  2. 176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
  3. 176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
  4. 176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
  5. 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
  6. 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
  7. 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
  8. 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
  9. 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
  10. 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
  11. 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
  12. 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
  13. Student [id=197, name=明明, score=87.9, age=19]
  14. Student [id=198, name=明明, score=99.5, age=23]
  15. Student [id=199, name=明明, score=87.9, age=19]

output

七、<foreach/>标签--遍历泛型为基本类型的List

  1. @Test
  2. public void test05() {
  3. List<Integer> ids =new ArrayList<>();
  4. ids.add(198);
  5. ids.add(199);
  6. List<Student> students = dao.selectStudentsByForeach2(ids);
  7. for (Student student : students) {
  8. System.out.println(student);
  9. }
  10.  
  11. }

MyTest

  1. import java.util.List;
  2. import com.jmu.bean.Student;
  3.  
  4. public interface IStudentDao {
  5. // 根据条件查询问题
  6. List<Student> selectStudentsByIf(Student student);
  7. List<Student> selectStudentsByWhere(Student student);
  8. List<Student> selectStudentsByChoose(Student student);
  9. List<Student> selectStudentsByForeach(int[] ids);
  10. List<Student> selectStudentsByForeach2(List<Integer> ids);
  11. }

com.jmu.dao.IStudentDao

  1. <select id="selectStudentsByForeach2" resultType="Student">
  2. <!-- select id,name,age,score from student where id in (1,3,5) -->
  3. select id,name,age,score
  4. from student
  5. <if test="list.size>0">
  6. where id in
  7. <foreach collection="list" item="myid" open="(" close=")"
  8. separator=",">
  9. #{myid}
  10. </foreach>
  11. </if>
  12. </select>

/mybatis7-dynamicSql/src/com/jmu/dao/mapper.xml

输出:

  1. 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach2 - ==> Preparing: select id,name,age,score from student where id in ( ? , ? )
  2. 48 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach2 - ==> Parameters: 198(Integer), 199(Integer)
  3. 78 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach2 - <== Total: 2
  4. Student [id=198, name=明明, score=99.5, age=23]
  5. Student [id=199, name=明明, score=87.9, age=19]

output

八、<foreach/>标签--遍历泛型为自定义类型的List

  1. import java.util.List;
  2. import com.jmu.bean.Student;
  3.  
  4. public interface IStudentDao {
  5. // 根据条件查询问题
  6. List<Student> selectStudentsByIf(Student student);
  7. List<Student> selectStudentsByWhere(Student student);
  8. List<Student> selectStudentsByChoose(Student student);
  9. List<Student> selectStudentsByForeach(int[] ids);
  10. List<Student> selectStudentsByForeach2(List<Integer> ids);
  11. List<Student> selectStudentsByForeach3(List<Student> ids);
  12. }

com.jmu.dao.IStudentDao

  1. @Test
  2. public void test06() {
  3. Student stu1 = new Student();
  4. stu1.setId(198);
  5. Student stu2 = new Student();
  6. stu2.setId(199);
  7. List<Student> stus =new ArrayList<>();
  8. stus.add(stu1);
  9. stus.add(stu2);
  10. List<Student> students = dao.selectStudentsByForeach3(stus);
  11. for (Student student : students) {
  12. System.out.println(student);
  13. }
  14.  
  15. }

MyTest

  1. <select id="selectStudentsByForeach3" resultType="Student">
  2. select id,name,age,score
  3. from student
  4. <if test="list.size>0">
  5. where id in
  6. <foreach collection="list" item="stu" open="(" close=")"
  7. separator=",">
  8. #{stu.id}
  9. </foreach>
  10. </if>
  11. </select>

mapper.xml

输出:

  1. 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - ==> Preparing: select id,name,age,score from student where id in ( ? , ? )
  2. 49 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - ==> Parameters: 198(Integer), 199(Integer)
  3. 90 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - <== Total: 2
  4. Student [id=198, name=明明, score=99.5, age=23]
  5. Student [id=199, name=明明, score=87.9, age=19]

output

九、SQL片段

MyBatis_动态SQL的更多相关文章

  1. mybatis_动态sql 查询、更新

    1)sql where 条件 select id="find" parameterType="User" resultType="User" ...

  2. Mybatis_总结_03_用_动态SQL

    一.前言 MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还 ...

  3. 值得注意的ibatis动态sql语法格式

    一.Ibatis常用动态sql语法,简单粗暴用一例子 <select id="iBatisSelectList" parameterClass="java.util ...

  4. Mysql - 游标/动态sql/事务

    游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的. 动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此 ...

  5. MyBatis4:动态SQL

    什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的 ...

  6. 分享公司DAO层动态SQL的一些封装

    主题 公司在DAO层使用的框架是Spring Data JPA,这个框架很好用,基本不需要自己写SQL或者HQL就能完成大部分事情,但是偶尔有一些复杂的查询还是需要自己手写原生的Native SQL或 ...

  7. MySQL存储过程动态SQL语句的生成

    用Mysql存储过程来完成动态SQL语句,使用存储过程有很好的执行效率: 现在有要求如下:根据输入的年份.国家.节假日类型查询一个节假日,我们可以使用一般的SQL语句嵌入到Java代码中,但是执行效率 ...

  8. 【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】

    一.动态SQL 什么是动态SQL,就是在不同的条件下,sql语句不相同的意思,曾经在“酒店会员管理系统”中写过大量的多条件查询,那是在SSH的环境中,所以只能在代码中进行判断,以下是其中一个多条件查询 ...

  9. 自定义函数执行动态sql语句

    --函数中不能调用动态SQL,使用用存储过程吧.如果还要对函数做其他操作,换成存储过程不方便,可以考虑把其他操作一起封装在存储过程里面.如:   create proc [dbo].[FUN_YSCL ...

随机推荐

  1. 由浅入深学习springboot中使用redis

    很多时候,我们会在springboot中配置redis,但是就那么几个配置就配好了,没办法知道为什么,这里就详细的讲解一下 这里假设已经成功创建了一个springboot项目. redis连接工厂类 ...

  2. DateTime格式

    SELECT * FROM TABLE (TO_DATE('2007/9/1','yyyy/mm/dd') BETWEEN CGGC_STRATDATE AND CGGC_ENDDATE OR CGG ...

  3. c#中的Out, params,ref 细说并沉淀

    1. Out,params,ref之前先记录平时用的最多的按值传递参数的情况,当然默认情况下参数传入函数的默认行为也是按值传递的. 1: //默认情况下参数会按照值传递 2: static int a ...

  4. iOS打包静态库(完整篇)

    1. 什么是库? 所谓库就是程序代码的集合,是共享程序代码的一种方式. 2. 库的分类 根据程序代码的开源情况,库可以分为两类 开源库源代码是公开的,你可以看到具体实现.比如GitHub上比较出名的第 ...

  5. java.lang.Collections

    java.lang.Collections 此类完全由在collection上进行操作或返回 collection 的静态方法组成.也就是说Collections提供了对Collection集合操作的 ...

  6. jvm内存区域与内存溢出

    java内存 java动态运行时区域包括:方法区.虚拟机栈.本地方法栈.堆.程序计数器,如右图所示:   程序计数器 程序计数器用来标识要执行的代码的行号,为线程私有   虚拟机栈 为线程所私有 虚拟 ...

  7. alex python of day2

      模块 sys模块:sys模块是用c语言写的,所以在lib下是不会有sys.py这个文件存在 1 import sys 2 print(sys.path) #打印环境变量 3 print(sys.a ...

  8. axios跨域

    参考:http://www.ruanyifeng.com/blog/2016/04/cors.html 遇到前后分离情况 前端 a.com 后端 server.a.com 环境 vue全家桶前端 ph ...

  9. win10环境下tensorflow-gpu安装

    踩了很多坑,浪费了一下午时间,在此记录一下. pip install tensorflow-gpu 然后下载安装cuda8.0 https://developer.nvidia.com/cuda-do ...

  10. 使用numpy实现批量梯度下降的感知机模型

    生成多维高斯分布随机样本 生成多维高斯分布所需要的均值向量和方差矩阵 这里使用numpy中的多变量正太分布随机样本生成函数,按照要求设置均值向量和协方差矩阵.以下设置两个辅助函数,用于指定随机变量维度 ...