MyBatis_动态SQL

一、动态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

输出:

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”的判断,就降低了整个系统的执行效率

 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

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

 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

输出:

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功能。

 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

输出:

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拼接。

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

输出:

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

 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

输出:

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

 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

时间: 2024-10-12 02:30:04

MyBatis_动态SQL的相关文章

mybatis_动态sql 查询、更新

1)sql where 条件 select id="find" parameterType="User" resultType="User"> select id,name, age,address from user_c where 1=1 <if test="id!=null"> and id=#{id} </if> <if test="name!=null">

MyBatis4:动态SQL

什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的省略逗号,动态SQL可以彻底处理这种痛苦. 通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种情形,这种语言可以被用在任意映射的SQL语句中. 动态SQL元素和使用JSTL或其它相似的基于XML的文本处理器相似,在MyBatis之前的版本中,有很多元素需

MyBatis动态SQL小结

p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; font-size: 10.5pt; font-family: 等线 } .MsoChpDefault { font-family: 等线 } div.WordSection1 { } ol { margin-bottom: 0cm } ul { margin-bottom: 0cm } Mybati

笔记:MyBatis 动态SQL

有时候,静态的SQL语句并不能满足应用程序的需求.我们可以根据一些条件,来动态地构建SQL语句.例如,在Web应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执行检索操作.在实现这种类型的搜索功能,我们可能需要根据这些条件来构建动态的SQL语句.如果用户提供了任何输入条件,我们需要将那个条件 添加到SQL语句的WHERE子句中. MyBatis通过使用<if>,<choose>,<where>,<foreach>,<

MyBatis 动态sql详解

MyBatis的动态sql语句 1.if 条件 2.choose , when 和 otherwise条件 3.where 条件 where条件:1.自动加上where.2.如果where子句以and或者or开头,则自动删除第一个and或者or..所以我们不需要自己加where 4.trim 条件 trim条件和where条件类似但是功能更强大:不仅可以替换掉子句开头的and或者or,还提供了加前缀和后缀的功能. 5.forEach循环 6.set 条件 set条件:自动加上set,自动去除最后

db2存储过程动态sql被截断

编写存储过程,使用动态sql时,调试时发现变量赋值后被截断. 关键代码如下: 实现的效果是先把上下游做对比的sql语句和相关参数存入RKDM_DATA_VOID_RULE, 执行存储过程后把两个sql语句得出的结果插入另一张结果表RKDM_DATA_VOID_CHK_REST. 建表语句: CREATE TABLE RKDM_DATA_VOID_CHK_REST ( DATA_DT DATE, ORDR_NUM INTEGER, CHK_BIG_CLS VARCHAR(256), DATA_PR

mybatis入门-动态sql

什么是动态sql 判断的动态sql mybatis核心就是对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 现有需求如下:需要查询用户,输入的是用户类,如果用户的性别类不为空,则将性别作为查询条件之一,如果用户的姓名不为空,则将用户姓名作为查询条件之一.如果用户两个属性都为空,则查询所有用户. 我们知道,在mapper中,我们的传入参数只有一个,多个参数只能通过包转类来实现,现在这种问题怎么解决呢?答案就是在xml文件中加入判断,使sql语句动态生成.刚才的需求所对应的

MyBatis的动态SQL详解

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力.如果你有使用 JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空 格或在列表的最后省略逗号.动态 SQL 可以彻底处理这种痛苦. 通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种

动态SQL

一 动态SQL /* 1.动态SQL概念的内涵 2.实现动态SQL的元素 3.if语句节点 4.choose(when,otherwise)语句节点 5.where节点 6.trim节点 7.set节点(update的set子句) 8.foreach节点 */ 1.动态SQL概念的内涵 MyBatis 最强大的特性之一就是它的动态语句功能,使用动态SQL完成多条件查 询.MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL 语中实现某些逻辑. 2.实现动态SQL的元素