动态SQL语句:定义

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态SQL语句:定义相关的知识,希望对你有一定的参考价值。

文章系列


 

  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语句

    1 select id, account, name, sex from user where{
    3     if(isNotEmpty(name)){
    5         name = #{name}
    7     }
    9 }
  • update语句

     1 update user set{
     3     if(isNotEmpty(name)){
     5         name = #{name},
     7     }
     9     if(isNotEmpty(sex)){
    11         sex = #{sex},
    13     }
    15 }
  • insert语句

    1 insert user values{
    2     id = #{id}, account = #{account}, name = #{name}
    3     if(isNotEmpty(sex)){
    4         sex = #{sex}
    5     }
    6 }
  • delete语句

    1 delete from user where{
    2     if(isNotEmpty(id)){
    3          id = #{id}
    4     }else{ 
    5         1 = 2
    6     }
    7 }

以上是关于动态SQL语句:定义的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis超强大的动态SQL大全

动态 SQL 语句大全

MyBatis高级特性

MYBATIS05_ifwherechoosewhentrimsetforEach标签sql片段

mybatis入门基础----动态SQL

动态SQL语句:定义