动态SQL语句:定义(一)
文章系列
静态SQL与动态SQL
- 静态SQL:程序运行前,具有固定的形式和结构的SQL。
- 动态SQL:程序运行时,能够动态改变形式或结构的SQL。
一些思考和想法
在实际的项目中,很多时候无法简单地用一条静态的SQL语句实现复杂的业务逻辑,往往需要通过程序语言动态地生成SQL语句。然而,在代码中通过条件判断语句拼接产生SQL语句,存在诸多缺点,简单列举如下:
代码杂乱和重复,编码的工作量大,而且容易产生错误。
拼接SQL语句的过程中,容易引起SQL注入。
代码与SQL语句混合在一起,代码结构不清晰,SQL语句的可读性不高。
针对以上存在的问题,希望实现以下几个目标:
提供一套统一的标记语言,编写动态SQL语句。
提供一个代码解析器解析动态SQL语句,生成真实的SQL。
避免拼接SQL过程中存在的问题,如:SQL注入,多余的【and】或【or】或【,】等。
这篇文章先定义好要实现的动态SQL语法以及必要的条件判断函数,在后续的文章中,会逐步给出具体的实现方案,最终的代码也将会发布到Github:https://github.com/Lotusun/Robin.git。希望通过这个实践,提高自己对:编译原理、词法分析器、语法分析器、有限状态机以及ScriptEngine的理解。
动态SQL语法
条件语句(if)
用法:if( condition ){ body },或if( condition ){ body } else { body }
说明:condition支持JavaScript语法。
选择语句(choose)
用法:choose{ when(condition){ body } else { body } }
说明:condition支持JavaScript语法;when子句可以存在多个;
结构语句(where)
用法:where{ body }
说明:用于where语句,能够去除body前后多余的【and】或【or】。
结构语句(set)
用法:set{ body }
说明:用于update语句,能够去除body前后多余的【,】。
结构语句(value)
用法:value{ body }
说明:用于insert语句,能够生成insert语句。
参数语句(#)
用法:#{name}
说明:能够将参数替换为【?】,避免SQL注入。
参数语句($)
用法:${name}
说明:能够将参数替换成字符串,存在SQL注入。
参数语句(@)
用法:@{name}
说明:标记存储过程的返回值。
参数语句(in)
用法:in{name}
说明:用于in语句,能够将List参数替换成多个【?】。
分页语句(page)
用法:page(a, b){ body } order { column }
说明:能够动态生成分页语句;其中,a为每页行数,b为当前页数;
条件判断函数
isNull()
说明:测试对象的值,若为null则为true,否则为false。
isNotNull()
说明:测试对象的值,功能与isNull()相反。
isAllNull()
说明:测试多个对象的值,若存在对象使isNotNull()为true则为false,否则为true。
isAnyNull()
说明:测试多个对象的值,若存在对象使isNull()为true则为true,否则为false。
isEmpty()
说明:测试对象的值,若为:null或空字符串或数组长度为0,则为true,否则为false。
isNotEmpty()
说明:测试对象的值,功能与isEmpty()相反。
isAllEmpty()
说明:测试多个对象的值,若存在对象使isNotEmpty()为true则为false,否则为true。
isAnyEmpty()
说明:测试多个对象的值,若存在对象使isEmpty()为true则为true,否则为false.
isBlank()
说明:测试对象的值,若为:null或空字符串或空白字符(\t, \n, \r等)则为true,否则为false。
isNotBlank()
说明:测试对象的值,功能与isBlanl()相反。
isAllBlank()
说明:测试多个对象的值,若存在对象使isNotBlank()为true则为false,否则为true。
isAnyBlank()
说明:测试多个对象的值,若存在对象使isBlank()为true则为true,否则为false。
示例
select语句
select id, account, name, sex from user where{ if(isNotEmpty(name)){ name = #{name} } }update语句
update user set{ if(isNotEmpty(name)){ name = #{name}, } if(isNotEmpty(sex)){ sex = #{sex}, } }insert语句
insert user values{ id = #{id}, account = #{account}, name = #{name} if(isNotEmpty(sex)){ sex = #{sex} } }delete语句
delete from user where{ if(isNotEmpty(id)){ id = #{id} }else{ } }
动态SQL语句:定义(一)的更多相关文章
- 动态sql语句基本语法--Exec与Exec sp_executesql 的区别
http://www.cnblogs.com/goody9807/archive/2010/10/19/1855697.html 动态sql语句基本语法 1 :普通SQL语句可以用Exec执行 ...
- IBatis.net动态SQL语句
在学习动态SQL语句之前,首先必须对条件查询有一定了解,先来学习如何向IBatis.Net的映射文件里传入参数. 一.条件查询 1.传递单个参数 如根据Id查询: <select id=&quo ...
- 存储过程中执行动态Sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- IBatis.net动态SQL语句(六)
在学习动态SQL语句之前,首先必须对条件查询有一定了解,先来学习如何向IBatis.Net的映射文件里传入参数. 一.条件查询 1.传递单个参数 如根据Id查询: <select id=&quo ...
- Oracle基础 动态SQL语句
一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...
- oracle 存储过程 动态sql语句
一.在oracle项目开发中越到问题: 在利用ODP向oracle中插入数据时,如果这样写: insert into clobTable (id, story) values(1,'....'); ...
- 处理动态SQL语句的参数
原文:处理动态SQL语句的参数 经常对SQL进行开发,写动态的SQL语句,是少之不了的,但是在使用动态语句中,常是因为有动态的参数的出现.参考下面代码示例: 正因为有了标记1的动态条件代码,而让SQL ...
- MyBatis 源码分析——动态SQL语句
有几年开发经验的程序员应该都有暗骂过原生的SQL语句吧.因为他们不能一句就搞定一个业务,往往还要通过代码来拼接相关的SQL语句.相信大家会理解SQL里面的永真(1=1),永假(1=2)的意义吧.所以m ...
- 怎样SQL存储过程中执行动态SQL语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
随机推荐
- SQL点滴23—T-SQL中的除法
原文:SQL点滴23-T-SQL中的除法 在T-SQL中没有除法运算,但是在T-SQL中可以实现类似除法的操作Divide.一般除法操作的结果一个列来自于被除关系表,剩下的来自除关系表.这里举一个例子 ...
- 全新通用编程语言 Def 招募核心贡献者、文档作者、布道师 deflang.org
先给出官网地址:deflang.org 一句话简介:可扩展编程语言 Def 的目标是将 C++ 的高效抽象和 Lisp 的强大表现力融为一体. 你可以通过阅读 入门教程 .源码 或 测试用例 来简要或 ...
- Spring Resource之ResourceLoader
ResourceLoader接口意味着任何实现的对象都能够返回Resource实例. public interface ResourceLoader { Resource getResource(St ...
- Linux下防火墙设置
Linux下开启/关闭防火墙命令 1) 永久性生效,重启后不会复原 开启:chkconfigiptables on 关闭:chkconfigiptables off 2) 即时生效,重启后复原 开启 ...
- Android正在使用Handler实现消息分发机制(两)
在开始这篇文章之前,.首先,我们在总结前两篇文章Handler, Looper和MessageQueue像一些关键点: 0)在创建线程Handler之前,你必须调用Looper.prepare(), ...
- JMM介绍
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVvemhhbmZlbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- 数据结构二叉树的java实现,包括二叉树的创建、搜索、删除和遍历
根据自己的学习体会并参考了一些网上的资料,以java写出了二叉树的创建.搜索.删除和遍历等操作,尚未实现的功能有:根据先序和中序遍历,得到后序遍历以及根据后序和中序遍历,得到先序遍历,以及获取栈的深度 ...
- JavaScript闭包小窥
众所周知,JavaScript没有块级作用域,只有函数作用域.那就意味着定义在函数中的参数和变量在函数外部是不可见的,而在一个函数内部任何位置定义的变量,在该函数内部任何地方都可见.这带来的好处是内部 ...
- Android调用本机应用市场,实现应用评分功能
原本以为应用评分是个很小的功能,但是一实现才发现真不是个小事.网上搜索资料没有找到答案,在很多开发群里面询问了很多人也没有解决问题,最后分析log,反编译看源码才终于有了些眉目,好吧,上代码: try ...
- 线程池python
原创博文,转载请注明出处 今天在学习python进程与线程时,无意间发现了线程池threadpool模块,见官方文档. 模块使用非常简单,前提是得需要熟悉线程池的工作原理. 我们知道系统处理任务时,需 ...