使用Mybatis实现动态SQL(一)
使用Mybatis实现动态SQL
作者 : Stanley 罗昊
【转载请注明出处和署名,谢谢!】
写在前面:
*本章节适合有Mybatis基础者观看*
前置说明
我现在写一个查询全部的sql语句,这个对各位来说,想必应该是非常简单,我举个例子:
select * from studnet //查询全部
我现在需求又变了。我现在要根据年龄进行查询了,那是不是也依然很简单:
select * from student where age = #{age} //根据年龄查询学生
那么,我现在再来一个需求,根据年龄跟姓名来查:
select * from student where age = #{age} and name=#{name};
但是,我们仔细发现,我刚才在写sql语句,就需要复制粘贴,那也就意味着,在这以上的sql语句是重复的,也就是说三个语句里,查询的都是同一张表,只不过加了一些条件;
因此,我没有必要写三次,其实我们写一次就够了;
如果使用动态sql来实现的话,就非常方便,比如:
我第一次使用的时候,仅使用select * from student 仅仅的查询全部,用于初始化
我第二次再去使用的时候 仅使用 where = age
我第三次再去使用的时候 就成了 where = age and name =name
可以灵活的控制sql语句,这就是动态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}
解决sql语句解释失败
那么,问题来了,以上写的那种方案是,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>
使用Mybatis实现动态SQL(一)的更多相关文章
- MyBatis的动态SQL详解
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...
- Mybatis解析动态sql原理分析
前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...
- mybatis 使用动态SQL
RoleMapper.java public interface RoleMapper { public void add(Role role); public void update(Role ro ...
- MyBatis框架——动态SQL、缓存机制、逆向工程
MyBatis框架--动态SQL.缓存机制.逆向工程 一.Dynamic SQL 为什么需要动态SQL?有时候需要根据实际传入的参数来动态的拼接SQL语句.最常用的就是:where和if标签 1.参考 ...
- MyBatis探究-----动态SQL详解
1.if标签 接口中方法:public List<Employee> getEmpsByEmpProperties(Employee employee); XML中:where 1=1必不 ...
- mybatis中的.xml文件总结——mybatis的动态sql
resultMap resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功. 如果sql查询字段名和pojo的属性名不一致,可以通过re ...
- mybatis.5.动态SQL
1.动态SQL,解决关联sql字符串的问题,mybatis的动态sql基于OGNL表达式 if语句,在DeptMapper.xml增加如下语句; <select id="selectB ...
- MyBatis的动态SQL详解-各种标签使用
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) ...
- 利用MyBatis的动态SQL特性抽象统一SQL查询接口
1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...
随机推荐
- 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用FairyGUI (一)
我们的热更新脚本在实际使用中,当然也要支持常用的第三方组件,例如这里介绍一个非常实用的第三方UI库:FairyGUI. 什么是FairyGUI 这里照搬FaiyGUI官网的介绍: 重新定义 UI 制作 ...
- Java (六、String类和StringBuffer)
Java String 类 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 创建字符串 // ==比较的是字符串在栈中存放的 ...
- ARCGIS 数据格式
1. 开篇 刚开始接触 GIS 时,老师说过这样一句话"做我们这一行的,数据就是命,没有数据,什么都干不了".现在我们需要做一个 webgis 的小项目,体会到了这句阐述的精髓.数 ...
- 使用VirtualBox调试项目踩过的坑
当我们完成项目后 通常需要做其他系统的测试 例如win10下测试完成后要在win7中测试 这时,安装一个虚拟机是较为明智的选择 本文将讲述在使用虚拟机测试Unity发布的exe(所有的3D文件都适用) ...
- C Primer Plus 第9章 函数 编程练习
复习题: 8. int choice(int a,int b,int c){ int max; max = a; if (b > max) max = b; if (c > max) ma ...
- EOS技术研究:合约与数据库交互
智能合约操作链数据库是很常见的应用场景.EOS提供了专门的工具来做这件事(相当于Ethereum的leveldb),专业术语叫做持久化API,本文将完整严密地介绍这个工具以及对它的使用测试. 关键字: ...
- 树莓派+花生棒+leanote搭建自己的笔记服务器
背景 对于一个程序猿来说.女朋友可以(暂时)没有,但是不能没有一个很好的记笔记的应用.因为记笔记可以帮助自己积累学习提升自己.每一次回头看自己记得笔记,你都会有新的理解. 也许有人会说,用有道云啊,有 ...
- File文件的读写操作RandomAccessFile类
1.Java提供了一个对文件随机访问的操作,访问包括读和写操作,该类名是RandomAccessFile,该类的读写是基于指针的操作. 2.RandomAccessFile在堆文件进行随机访问操作时有 ...
- java集合HashMap、HashTable、HashSet详解
一.Set和Map关系 Set代表集合元素无序,集合元素不可重复的集合,Map代表一种由多个key-value组成的集合,map集合是set集合的扩展只是名称不同,对应如下 二.HashMap的工作原 ...
- Hibernate入门----配置文件
一.Hibernate简介 hibernate是一个开源的,轻量级的,持久成ORM框架. Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数 ...