一、动态SQL

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

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

二、使用动态SQL原因

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

三、<if/>标签

注意事项:

(1)

 @Test
public void test08() {
Student stu = new Student("明", 20, 0);
List<Student> students = dao.selectStudentsByCondition(stu);
for (Student student : students) {
System.out.println(student);
} }

com.jmu.test.MyTest

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

com.jmu.dao.IStudentDao

 <mapper namespace="com.jmu.dao.IStudentDao">
<select id="selectStudentsByCondition" resultType="Student">
select id,name,age,score
from student
where
<if test="name !=null and name !=''">
name like '%' #{name} '%'
</if>
<if test="age>0">
and age >#{age}
</if>
</select>
</mapper>

mapper.xml

输出:

0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition  - ==>  Preparing: select id,name,age,score from student where name like '%' ? '%' and age >?
48 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - ==> Parameters: 明(String), 20(Integer)
96 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - <== Total: 15
Student [id=159, name=明明, score=87.9, age=23]
Student [id=173, name=小明明, score=99.5, age=23]
Student [id=175, name=明明, score=99.5, age=23]
Student [id=177, name=明明, score=99.5, age=23]
Student [id=179, name=明明, score=99.5, age=23]
Student [id=181, name=明明, score=99.5, age=23]
Student [id=183, name=明明, score=99.5, age=23]
Student [id=185, name=明明, score=99.5, age=23]
Student [id=187, name=明明, score=99.5, age=23]
Student [id=189, name=明明, score=99.5, age=23]
Student [id=191, name=明明, score=99.5, age=23]
Student [id=193, name=明明, score=99.5, age=23]
Student [id=195, name=明明, score=99.5, age=23]
Student [id=198, name=明明, score=99.5, age=23]
Student [id=200, name=明明, score=99.5, age=23]

output

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

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

  

解决:

四、<where/>标签

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

 @Test
public void test02() {
// Student stu = new Student("明", 20, 0);
Student stu = new Student("", 20, 0);
List<Student> students = dao.selectStudentsByWhere(stu);
for (Student student : students) {
System.out.println(student);
} }

com.jmu.test.MyTest

import java.util.List;
import java.util.Map; import com.jmu.bean.Student; public interface IStudentDao {
// 根据条件查询问题
List<Student> selectStudentsByIf(Student student);
List<Student> selectStudentsByWhere(Student student);
}

com.jmu.dao.IStudentDao

 <select id="selectStudentsByWhere" resultType="Student">
select id,name,age,score
from student
<where>
<if test="name !=null and name !=''">
and name like '%' #{name} '%'
</if>
<if test="age>0">
and age >#{age}
</if>
</where>
</select>

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

输出:

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

output

五、<choose/>标签

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

 <select id="selectStudentsByChoose" resultType="Student">
select id,name,age,score
from student
<where>
<choose>
<when test="name !=null and name !=''">
and name like '%' #{name} '%'
</when>
<when test="age>0">
and age>#{age}
</when>
<otherwise>
1=2 <!-- false,使得查询不到结果 -->
</otherwise>
</choose>
</where>
</select>

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

 import java.util.List;
import java.util.Map; import com.jmu.bean.Student; public interface IStudentDao {
// 根据条件查询问题
List<Student> selectStudentsByIf(Student student);
List<Student> selectStudentsByWhere(Student student);
List<Student> selectStudentsByChoose(Student student); }

com.jmu.dao.IStudentDao

 }
@Test
public void test03() {
// Student stu = new Student("明", 20, 0);
Student stu = new Student("", 20, 0);
// Student stu = new Student("", 0, 0);
List<Student> students = dao.selectStudentsByChoose(stu);
for (Student student : students) {
System.out.println(student);
} }

MyTest

输出:

0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf  - ==>  Preparing: select id,name,age,score from student where 1=1 and age >?
50 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Parameters: 20(Integer)
86 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - <== Total: 2
Student [id=198, name=明明, score=99.5, age=23]
Student [id=200, name=明明, score=99.5, age=23]
104 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >?
104 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >?
105 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer)
105 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer)
109 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2
109 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2
Student [id=198, name=明明, score=99.5, age=23]
Student [id=200, name=明明, score=99.5, age=23]
121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>?
121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>?
121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>?
122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer)
122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer)
122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer)
124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2
124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2
124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2
Student [id=198, name=明明, score=99.5, age=23]
Student [id=200, name=明明, score=99.5, age=23]

output

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

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

输出:

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

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

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

com.jmu.dao.IStudentDao

 @Test
public void test04() {
int[] ids={197,198,199};
List<Student> students = dao.selectStudentsByForeach(ids);
for (Student student : students) {
System.out.println(student);
} }

MyTest

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

mapper.xml

输出:

176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach  - ==>  Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? )
177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer)
179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3
Student [id=197, name=明明, score=87.9, age=19]
Student [id=198, name=明明, score=99.5, age=23]
Student [id=199, name=明明, score=87.9, age=19]

output

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

 @Test
public void test05() {
List<Integer> ids =new ArrayList<>();
ids.add(198);
ids.add(199);
List<Student> students = dao.selectStudentsByForeach2(ids);
for (Student student : students) {
System.out.println(student);
} }

MyTest

 import java.util.List;
import com.jmu.bean.Student; public interface IStudentDao {
// 根据条件查询问题
List<Student> selectStudentsByIf(Student student);
List<Student> selectStudentsByWhere(Student student);
List<Student> selectStudentsByChoose(Student student);
List<Student> selectStudentsByForeach(int[] ids);
List<Student> selectStudentsByForeach2(List<Integer> ids);
}

com.jmu.dao.IStudentDao

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

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

输出:

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

output

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

 import java.util.List;
import com.jmu.bean.Student; public interface IStudentDao {
// 根据条件查询问题
List<Student> selectStudentsByIf(Student student);
List<Student> selectStudentsByWhere(Student student);
List<Student> selectStudentsByChoose(Student student);
List<Student> selectStudentsByForeach(int[] ids);
List<Student> selectStudentsByForeach2(List<Integer> ids);
List<Student> selectStudentsByForeach3(List<Student> ids);
}

com.jmu.dao.IStudentDao

 @Test
public void test06() {
Student stu1 = new Student();
stu1.setId(198);
Student stu2 = new Student();
stu2.setId(199);
List<Student> stus =new ArrayList<>();
stus.add(stu1);
stus.add(stu2);
List<Student> students = dao.selectStudentsByForeach3(stus);
for (Student student : students) {
System.out.println(student);
} }

MyTest

 <select id="selectStudentsByForeach3" resultType="Student">
select id,name,age,score
from student
<if test="list.size>0">
where id in
<foreach collection="list" item="stu" open="(" close=")"
separator=",">
#{stu.id}
</foreach>
</if>
</select>

mapper.xml

输出:

 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3  - ==>  Preparing: select id,name,age,score from student where id in ( ? , ? )
49 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - ==> Parameters: 198(Integer), 199(Integer)
90 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - <== Total: 2
Student [id=198, name=明明, score=99.5, age=23]
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. Java微信公众平台开发_06_素材管理

    一.本节要点 1.官方文档的media 这个media可以理解为文件,即我们需要以POST方式提交一个文件 2.媒体文件有效期 媒体文件在微信后台保存时间为3天,即3天后media_id失效. 二.代 ...

  2. 项目实战2—LVS负载均衡

    负载均衡集群企业级应用实战-LVS 实现基于LVS负载均衡集群的电商网站架构 随着业务的发展,网站的访问量越来越大,网站访问量已经从原来的1000QPS,变为3000QPS,网站已经不堪重负,响应缓慢 ...

  3. RunLoop想入门,看这篇就够了

    前言 刚刚听到RunLoop的时候我也是一脸懵逼,这是什么,有什么用呢,逼格貌似还挺高.然后就开始尝试去搞懂它,去找博客,但是几乎所有的博客都是枯燥乏味的,都是讲概念,然后给个实例,对于我这个小白来说 ...

  4. linux基础命令整理(一)

    ls 显示当前目录内容 1)ls / (显示根目录下所有的目录和文件) 2)ls -l / (以列表的形式显示根目录下所有的目录和文件) 绝对路径和相对路径 1)绝对路径,以/开头的都是绝对路径,比如 ...

  5. 分布式缓存之Ehcache与terracotta - Terracotta服务器概念篇

    1.介绍 Terracotta服务器为Terracotta产品提供分布式数据平台.Terracotta服务器集群被称为Terracotta服务器阵列(TSA).Terracotta服务器阵列可以从单个 ...

  6. 基于MVC设计模式的Web应用框架:struts2的简单搭建(一)

    Struts2的初步介绍 Struts2是apache项目下的一个web 框架,普遍应用于阿里巴巴.京东等互联网.政府.企业门户网站.虽然之前存在了很大的安全漏洞,在2013年让苹果.中国移动.中国联 ...

  7. 一个简单的迷你jQuery实现

    //仅提供与学习使用(function () { var _$ = window.$; var _jQuery = window.jQuery; //暴露外部使用的一个接口 var jQuery = ...

  8. JS构造函数模式

    构造函数是可以创建特定类型对象的函数,可以接受参数定义函数成员.如果之前做过java比较好理解,举个例子: function exampleFunction(arg1, arg2, arg3){ th ...

  9. 解决WebSocket兼容ie浏览器版本问题

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7942323.html 在使用Netty进行WebSocket开发时,测试发现:ie 11系列个别低版本连接W ...

  10. Android 软键盘的显示和隐藏,这样操作就对了

    一.前言 如果有需要用到输入的地方,通常会有需要自动弹出或者收起软键盘的需求.开篇明义,本文会讲讲弹出和收起软键盘的一些细节,最终还会从源码进行分析. 想要操作软键盘,需要使用到 InputMetho ...