做者 : Stanley 罗昊sql
【转载请注明出处和署名,谢谢!】数据库
写在前面:mybatis
*本章节适合有Mybatis基础者观看*spa
我如今写一个查询所有的sql语句,这个对各位来讲,想必应该是很是简单,我举个例子:code
select * from studnet //查询所有
我如今需求又变了。我如今要根据年龄进行查询了,那是否是也依然很简单:xml
select * from student where age = #{age} //根据年龄查询学生
那么,我如今再来一个需求,根据年龄跟姓名来查:对象
select * from student where age = #{age} and name=#{name};
可是,咱们仔细发现,我刚才在写sql语句,就须要复制粘贴,那也就意味着,在这以上的sql语句是重复的,也就是说三个语句里,查询的都是同一张表,只不过加了一些条件;blog
所以,我没有必要写三次,其实咱们写一次就够了;开发
若是使用动态sql来实现的话,就很是方便,好比:class
我第一次使用的时候,仅使用select * from student 仅仅的查询所有,用于初始化
我第二次再去使用的时候 仅使用 where = age
我第三次再去使用的时候 就成了 where = age and name =name
能够灵活的控制sql语句,这就是动态sql;
能够设想一下,若是没有动态sql,咱们是否是一个功能模块,就要写三段sql语句,很显然让代码变的很是臃肿不整洁,效率还低,因此,在正常的企业开发当中,动态sql用点居多!
那么,到底怎么实现呢?这个,就用到了mybatis xml文件中的动态标签了;
首先,咱们须要看一下查询条件:本次业务涉及到查询全部、根据学生年龄查询、根据学生年龄而且根据学生姓名进行查询;
查询全部,由于要在页面初始化中使用,因此页面加载以后须要展现出来,另外那些条件,就是几个筛选条件,能够利用他们知足本身的查询须要;
如今,咱们就根据以上业务来完成一个动态sql;
在要进行查询的xml文件中编写:
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student where <if test = " name!= null and name!= ' ' ">//若是传过来的student对象有name属性,而且该属性不为空,便执行次条件 student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </select>
讲解:
1.if:什么叫if,就是若是有这么怎办,若是没怎么怎么办,在这里的意思就是,你如今查的时候,要是传入了一个名字,那么,我就根据你传过来的name进行查询。
换句话说,若是你没传这个字段,那么是否是就不进入这个判断了,也就表明你没写这个where同样;
用意:我如今传过来一个学生对象,若是这个学生对象包含了一个name属性,且name属性不为空,那么我就要把这个student = #{name}给加上
if后面的test里面就写执行条件
2.咱们如今除了name以外,是否是还有可能有age;
根据以上的业务,咱们发现,也是有根据age进行查询的,那么,咱们仅需在下面跟上一个if里面来写关于age的判决便可;
可是值得注意的是,本次编写前面须要加上and;
and:为何在加and呢?
咱们能够设想一下,目前的sql语句是这样的:
select * from student where name = #{name}
若是不加and的话,是否是就变成了:
select * from student where name = #{name}age = #{age}
这样显然是不对的,sql语法都出错两,因此须要在前面加上and,加上and以后就是合法的sql语句了:
select * from student where name = #{name}And age = #{age}
那么,问题来了,以上写的那种方案是,name 跟 age 必须所有存在,才能够生效,一旦不存在,那么就会报错,我如今认定这个name时在时不在的状况;
我举个例子,本次查询,仅仅按照age查询,这个时候,age传过来了,可是name没有传过来,由于我只查询age,确定只用把age传过来,这个时候,name拿不到值,就致使了这样的sql语句:
select * from student where And age = #{age}
这就很明显,sql语句怎么可能写成这样,这个and就很是使人厌烦,为何会致使成这样呢?
还记得咱们写的一个if标签吗?若是name = null and name = ‘ ’,我这条标签就不去执行,一旦不去执行就变成以上那样了,本来有name是这样的:
select * from student where name = #{name}And age = #{age}
你如今name为空了,那就代表name = #{name}就消失了
这个and你也去不掉它,你一旦去掉了,又会形成另一种sql语法非法,如何解决这个不协调的字段呢?
有两种解决方案;
第一种:
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student where 1 = 1 <if test = " name!= null and name!= ' ' ">//若是传过来的student对象有name属性,而且该属性不为空,便执行次条件 And student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </select>
我把studnt = name前面也加了一个and,可是这样作会致使本次sql语句不成立,不要紧,我在where后面加了一个 1 = 1,就表明永远成立,也就是强制让数据库认下这个and;
第二种【最佳/推荐】:
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student <where> <if test = " name!= null and name!= ' ' ">//若是传过来的student对象有name属性,而且该属性不为空,便执行次条件 And student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </where> </select>
如今呢,咱们直接用where标签把sql包裹,把主查询后面的where就删掉,由于已经不须要了,那么加上这个where标签后,sql变成什么样子了呢?
select * from student <where> and name = #{name}and age = #{age}
这样的sql语句看似是否是像是那种有问题的sql语句,由于在where后面就有and,可是没关心,不用管,这个<where>标签是智能的,它会自动处理第一个and,不会处理第二个;
什么意思呢?就是本次查询,若是你须要这个and,那么我就给你加上,若是你不须要这个and,我就不给你加,很显然,本次查询不须要这个and,因此就没给你加;
这个时候,你把第一个and给删了,再去执行,你会发现跟没删同样,若是你加上这个and,你就会发现,跟没加同样,就是这么智能,很是便捷;
可是,若是你把第二个或日后的and删了,就会出问题了,由于它只会帮你处理第第一个and;
因此,原理是这样的:
刚才我说了,若是没有name,那么第一个if就会消失,紧接着,age是否是就顶替name了,那么age就是第一个了
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student <where> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </where> </select>
那么这个智能where标签恰到好处的把第一个and给消掉了,从而完成了根据age查询;
了解以上概念后,咱们就把上面的业务给所有写完吧,若是age跟name均不为空,那么我就根据这两个进行查询;
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student <where> <if test = " name!= null and name!= ' ' ">//若是传过来的student对象有name属性,而且该属性不为空,便执行次条件 And student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> <if test = "age ! = null and age !=' ' And name !=null and name ! = ' ' "> And student = #{name} And student = #{age} </if> </where> </select>