Mybatis学习(7)单表的CURD操作-动态SQL

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SDDDLLL/article/details/84843620

        在前面已经介绍了两种情况,属性名与查询字段名不一致的情况,还有Mapper动态代理的情况,本篇博客将考虑第三种情况,使用动态SQL。动态SQL,主要是解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的条件不同,执行的SQL语句也不同。若将每种可能的情况均逐一列出,对所有的查询条件进行排列组合,那么将会出现大量的SQL语句。此时,可以使用动态SQL来解决这样的问题。

举个例子:下面也将根据这个例子进行讨论,假设管理员要从学生管理系统中自定义选出一些学生的信息。

        用户自定义的查询条件,此时年龄成绩每一次查询范围可能都不一样,此时就是查询条件不确定的情况,动态SQL指的是,通过Mybatis提供的各种标签做出判断以实现动态拼接的SQL语句,比如常用的SQL标签<if>、<where>、<choose/>、<foreach/>等

接下来开始测试,看看如何实现动态SQL

一、测试环境的搭建

1、定义数据库表

2、定义实体

package com.test.beans;
public class Student {
	private Integer id;
	private String name;
	private int age;
	private double score;
	//带参构造器和无参构造器

	//每个属性的getter和setter方法

    //toString方法

}

3、定义测试类

package com.test.mytest;

public class MyTest {
	//由于增删改查都需要StudentDaoImpl,所以将其设置2全局变量。	
	private IStudentDao dao ;
	private SqlSession sqlSession;
	
	@Before
	public void testBefore(){
		sqlSession = MybatisUtil.getSqlSession();
		dao = sqlSession.getMapper(IStudentDao.class);
	}
	
	@After
	public void after(){
		if(sqlSession!=null){
			sqlSession.close();
		}
	}
	
}

4、注意事项

在mapper的动态SQL中若出现>、<、>=、<=,最好将其转换为实体符号,否则XML解析出现问题

二、<if/>标签

1、定义Dao接口

package com.test.dao
public interface IStudentDao{
    List<Student> selectStudentsIf(Student student);
}

2、定义映射文件

现在假设管理员要根据姓名和年龄选出学生。

       首先管理员可以输入姓名和年龄来查询学生情况,但是当管理员什么也没有输入的时候就点击了查询按钮,为了不出现问题。我们在where后添加了一个“1=1”的条件。这样就避免了当两个条件都没有设定时候只剩下一个where,而出现的不完整的SQL。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

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

3、修改测试类

4、查看结果

当有两个查询条件时候:

当有一个查询条件时候:

无条件查询时候:

 

三、<where/>标签

          <if>标签中存在一个比较麻烦的地方:需要在where后手工添加一个“1=1”的字句。因为若where后的所有<if/>条件均为false,而where后有没有“1-1”,那么就会出现只剩下where的情况,此时sql不完整,就会出错。但是当数据量很大时候,会严重的影响查询效率。因此我们使用where标签

1、修改Dao接口

2、修改映射文件

此时,有查询条件时候,可以自动的添加where子句。没有查询条件的时候,不会添加where语句。

          注意:第一个<if>标签中的SQL片段,可以不包含and。不过,写上and也不会错,系统会自动的将多余的and去掉。但是其他<if>标签的and必须写上,否则SQL语句会报错

3、修改测试类

4、查看结果

当有两个查询条件时候:

当有一个查询条件时候:

无查询条件:

四、<choose>标签

        该标签只可以包含<when/>和<otherwise/>,可以包含多个,他们可以联合使用,类似于java中的switch与case功能

这个例子的要求是:若姓名不空,则按照姓名查询。若姓名为空,则按照年龄查询。若没有查询条件,则没有查询结果。

1、修改Dao接口

2、修改映射文件

3、修改测试类

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

<foreach/>标签用于实现对数组和集合的遍历,使用时需要注意:

  • collection表示要遍历的集合类型,这里是数组也就是array。
  • open、close、separator为对遍历内容的SQL拼接。

本案例要实现的功能是:查询出id为1和3的学生信息

1、修改Dao接口

2、修改映射文件

动态SQL的判断中使用的都是OGNL表达式。OGNL表达式中的数组使用array表示。数组长度使用array.length表示。

3、修改测试类

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

1、修改Dao接口

2、修改映射文件

3、修改测试类

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

1、修改Dao接口

2、修改映射文件

3、修改测试类

八、<sql/>标签

        sql标签用于自定义sql片段,以便其他SQL标签复用。其他标签使用该SQL片段时候,需要使用<include>字标签。该<sql/>标签可以定义SQL语句中的任何部分,所以<include/>字标签可以放在动态SQL的任何位置。

1、修改Dao接口

2、修改映射文件

3、修改测试类

猜你喜欢

转载自blog.csdn.net/SDDDLLL/article/details/84843620
今日推荐