文章系列


  1. 动态SQL语句:定义(一)

静态SQL与动态SQL


  • 静态SQL:程序运行前,具有固定的形式和结构的SQL。
  • 动态SQL:程序运行时,能够动态改变形式或结构的SQL。

一些思考和想法


在实际的项目中,很多时候无法简单地用一条静态的SQL语句实现复杂的业务逻辑,往往需要通过程序语言动态地生成SQL语句。然而,在代码中通过条件判断语句拼接产生SQL语句,存在诸多缺点,简单列举如下:

  1. 代码杂乱和重复,编码的工作量大,而且容易产生错误。

  2. 拼接SQL语句的过程中,容易引起SQL注入。

  3. 代码与SQL语句混合在一起,代码结构不清晰,SQL语句的可读性不高。

针对以上存在的问题,希望实现以下几个目标:

  1. 提供一套统一的标记语言,编写动态SQL语句。

  2. 提供一个代码解析器解析动态SQL语句,生成真实的SQL。

  3. 避免拼接SQL过程中存在的问题,如:SQL注入,多余的【and】或【or】或【,】等。

这篇文章先定义好要实现的动态SQL语法以及必要的条件判断函数,在后续的文章中,会逐步给出具体的实现方案,最终的代码也将会发布到Github:https://github.com/Lotusun/Robin.git。希望通过这个实践,提高自己对:编译原理、词法分析器、语法分析器、有限状态机以及ScriptEngine的理解。

动态SQL语法


  1. 条件语句(if)

    用法:if( condition ){ body },或if( condition ){ body } else { body }

    说明:condition支持JavaScript语法。

  2. 选择语句(choose)

    用法:choose{ when(condition){ body } else { body } }

    说明:condition支持JavaScript语法;when子句可以存在多个;

  3. 结构语句(where)

    用法:where{ body }

    说明:用于where语句,能够去除body前后多余的【and】或【or】。

  4. 结构语句(set)

    用法:set{ body }

    说明:用于update语句,能够去除body前后多余的【,】。

  5. 结构语句(value)

    用法:value{ body }

    说明:用于insert语句,能够生成insert语句。

  6. 参数语句(#)

    用法:#{name}

    说明:能够将参数替换为【?】,避免SQL注入。

  7. 参数语句($)

    用法:${name}

    说明:能够将参数替换成字符串,存在SQL注入。

  8. 参数语句(@)

    用法:@{name}

    说明:标记存储过程的返回值。

  9. 参数语句(in)

    用法:in{name}

    说明:用于in语句,能够将List参数替换成多个【?】。

  10. 分页语句(page)

    用法:page(a, b){ body } order { column }

    说明:能够动态生成分页语句;其中,a为每页行数,b为当前页数;

条件判断函数


  1. isNull()

    说明:测试对象的值,若为null则为true,否则为false。

  2. isNotNull()

    说明:测试对象的值,功能与isNull()相反。

  3. isAllNull()

    说明:测试多个对象的值,若存在对象使isNotNull()为true则为false,否则为true。

  4. isAnyNull()

    说明:测试多个对象的值,若存在对象使isNull()为true则为true,否则为false。

  5. isEmpty()

    说明:测试对象的值,若为:null或空字符串或数组长度为0,则为true,否则为false。

  6. isNotEmpty()

    说明:测试对象的值,功能与isEmpty()相反。

  7. isAllEmpty()

    说明:测试多个对象的值,若存在对象使isNotEmpty()为true则为false,否则为true。

  8. isAnyEmpty()

    说明:测试多个对象的值,若存在对象使isEmpty()为true则为true,否则为false.

  9. isBlank()

    说明:测试对象的值,若为:null或空字符串或空白字符(\t, \n, \r等)则为true,否则为false。

  10. isNotBlank()

    说明:测试对象的值,功能与isBlanl()相反。

  11. isAllBlank()

    说明:测试多个对象的值,若存在对象使isNotBlank()为true则为false,否则为true。

  12. 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语句:定义(一)的更多相关文章

  1. 动态sql语句基本语法--Exec与Exec sp_executesql 的区别

    http://www.cnblogs.com/goody9807/archive/2010/10/19/1855697.html 动态sql语句基本语法 1   :普通SQL语句可以用Exec执行   ...

  2. IBatis.net动态SQL语句

    在学习动态SQL语句之前,首先必须对条件查询有一定了解,先来学习如何向IBatis.Net的映射文件里传入参数. 一.条件查询 1.传递单个参数 如根据Id查询: <select id=&quo ...

  3. 存储过程中执行动态Sql语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

  4. IBatis.net动态SQL语句(六)

    在学习动态SQL语句之前,首先必须对条件查询有一定了解,先来学习如何向IBatis.Net的映射文件里传入参数. 一.条件查询 1.传递单个参数 如根据Id查询: <select id=&quo ...

  5. Oracle基础 动态SQL语句

    一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...

  6. oracle 存储过程 动态sql语句

    一.在oracle项目开发中越到问题: 在利用ODP向oracle中插入数据时,如果这样写:   insert into clobTable (id, story) values(1,'....'); ...

  7. 处理动态SQL语句的参数

    原文:处理动态SQL语句的参数 经常对SQL进行开发,写动态的SQL语句,是少之不了的,但是在使用动态语句中,常是因为有动态的参数的出现.参考下面代码示例: 正因为有了标记1的动态条件代码,而让SQL ...

  8. MyBatis 源码分析——动态SQL语句

    有几年开发经验的程序员应该都有暗骂过原生的SQL语句吧.因为他们不能一句就搞定一个业务,往往还要通过代码来拼接相关的SQL语句.相信大家会理解SQL里面的永真(1=1),永假(1=2)的意义吧.所以m ...

  9. 怎样SQL存储过程中执行动态SQL语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

随机推荐

  1. C# 通过扩展WebBrowser捕获网络连接错误信息

    想捕获WebBrowser连接指定网站过程中发生的错误信息,包括网络无法连接.404找不到网页等等错误!经过网上的搜集,找到了以下解决方案,该解决方案不会在网站连接前发出多余的测试请求. 向Webbr ...

  2. sql 事务日志传输

    原文:sql 事务日志传输 概述 可以使用日志传送将事务日志不间断地从一个数据库(主数据库)发送到另一个数据库(辅助数据库).不间断地备份主数据库中的事务日志,然后将它们复制并还原到辅助数据库,这将使 ...

  3. Image 对象

    <html> <body> <img id="compman" src="0387.jpg" alt="Computer ...

  4. Ibatis 返回datatable数据类型案例

    /// <summary> /// 查询实体 [DataSet数据集] /// </summary> /// <param name="statementNam ...

  5. EntityFramework中支持BulkInsert扩展

    EntityFramework中支持BulkInsert扩展 本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 Ent ...

  6. MVC应用程序请求密码的功能1

    MVC应用程序请求密码的功能(一) 经过一系列的练习,实现了会员注册<MVC会员注册>http://www.cnblogs.com/insus/p/3439599.html,登录<M ...

  7. Day2:T1搜索 T2最小生成树

    T1:广搜+判断矩形 注:如何判断搜的是否为矩形: 在广搜的时候,记录下边界的坐标,然后枚举一遍过去,如果搜到"."就是牛群,否则就是房间 瞥了一眼ccy的做法,据说是floodf ...

  8. c语言算法题目求职用

    1.栈的压入与压出/* 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.n<=100000 用一个栈作辅助,顺序描述压入序列和弹出序列,如果当前位置上压入序列 ...

  9. TOGAF架构能力框架之架构委员会和架构合规性

    TOGAF架构能力框架之架构委员会和架构合规性 3. 架构委员会 正如前面所说,一个用来对架构治理策略的实现进行监督的跨组织的架构委员会是架构治理策略成功的主要要素之一.架构委员会应该能够代表所有主要 ...

  10. HDU 4618 - Palindrome Sub-Array(2013MUTC2-1008)(DP)

    d(i,j,k)表示左上角坐标为(i,j),k为正方形边长 d(i,j,k)=1,如果d(i+1,j+1,k-2)=0,且上下两个外围的相等且回文,左右两个外围的相等且回文:否则d(i,j,k)=0 ...