Foxnic-SQL (2) —— SQL表达式(Expr)

LeeFJ
• 阅读 402

Foxnic-SQL (2) —— SQL表达式(Expr)

常规意义的表达式

  表达式是运算符、常量和变量的组合。一个表达式可以由一个或多个操作数和零个或多个运算符组成以产生一个值。常量表达式、数学运算、关系表达式、逻辑表达式、位表达式等。

SQL表达式

  Foxnic-SQL 中所说的表达式,其实是SQL表达式。任何带有变量占位符的字符串就是一个SQL表达式,这些表达式最终可以拼装成一个完整的SQL语句。Foxnic-SQL 支持命名占位符(:NAME)和匿名占位符(?)。Foxnic-SQL 通过 Expr 类构建与解析SQL表达式,例如:

Expr expr1=new Expr("select ?+? as result from dual",8,9);
System.out.println("expr1 = "+expr1);
// 输出:expr1 = select 8 + 9 as result from dual

  这样一个查询语句就是一个表达式,其中的问号(?)就是变量占位符,他们没有名称只有顺序,所以是匿名占位符。

Map<String,Object> namedParam=new HashMap<>();
namedParam.put("P1",18);
namedParam.put("P2",19);
Expr expr2=new Expr("select :P1+:P2 as result from dual",namedParam);
System.out.println("expr2 = "+expr2);
// 输出:expr2 = select 18 + 19 as result from dual

  本示例将原来的问号(?)占位符换成了以冒号(:)开头的有名称的占位符P1、P2,这就是带有命名占位符的SQL表达式。当然表达式还可以更为简单,例如:

Expr expr1=new Expr("age>?",28);
System.out.println("expr1 = "+expr1);
// 输出:expr1 = age> 28

也可以是:

Expr expr1=new Expr("age>? and height>?",28,182);
System.out.println("expr1 = "+expr1);
// 输出:expr1 = age> 28 and height> 182

  就技术角度而言,SQL表达式所关心的核心问题是变量占位符,至于内容是否符合SQL语法,它并不关心

SQL表达式的执行

  当一个SQL表达式完整且符合SQL语法时,它就可以被数据库执行。表达式通过DAO传递给JDBC执行时,这些占位符被解析并处理成绑定变量。当表达式被打印或输出时,占位符会被处理成符合指定数据库语法且变量已代入的SQL字符串。

/**
* 2、表达式通过DAO传递给JDBC执行时,这些占位符被解析并处理成绑定变量。当表达式被打印或输出时,占位符会被处理成符合指定数据库语法且变量已代入的SQL字符串。
* */
public static void  demo2() {

    Date date= DateUtil.parse("2022-12-05");
    Expr expr1=new Expr("select ?+? as result from my_table where create_date>?",8,9,date);
    System.out.println("传递给JDBC的语句(匿名占位符) = "+expr1.getListParameterSQL());
    // 输出:传递给JDBC的语句(匿名占位符) = select ? + ? as result from my_table where create_date> ?
    System.out.println("传递给JDBC的语句(命名占位符) = "+expr1.getNamedParameterSQL());
    // 输出:传递给JDBC的语句(命名占位符) = select :PARAM_1 + :PARAM_2 as result from my_table where create_date> :PARAM_3

    // 指定全局的SQL方言,默认MySQL,特定数据库时自动识别
    GlobalSettings.DEFAULT_SQL_DIALECT= SQLDialect.MySQL;
    System.out.println("开发人员友好的SQL(默认) = "+expr1.getSQL());
    // 输出:开发人员友好的SQL(默认) = select 8 + 9 as result from my_table where create_date> str_to_date('2022-12-05 00:00:00','%Y-%m-%d %H:%i:%s')
    System.out.println("开发人员友好的SQL(Oracle) = "+expr1.getSQL(SQLDialect.PLSQL));
    // 输出:开发人员友好的SQL(Oracle) = select 8 + 9 as result from my_table where create_date> to_date('2022-12-05 00:00:00','yyyy-mm-dd hh24:mi:ss')

    // 执行,此处请关注控制台输出日志
    Expr exprForQuery=new Expr("select * from sys_dict where create_time>?",date);
    RcdSet rs=DBInstance.DEFAULT.dao().query(exprForQuery);
    for (Rcd r : rs) {
        System.out.println(r.toJSONObject());
    }
}

  开发人员可以从表达式(Expr)获得比传统字符串拼接更加灵活,且绑定变量友好的SQL处理方式。也可以高效轻松地通过表达式避免数据库的SQL硬解析,从而获得更佳性能。
  同时,开发人员可以轻松地获得绑定变量已代入的SQL语句,这些语句只要复制就可以粘贴到数据库客户端工具执行,极大地方便了SQL语句的调试与问题排查。

表达式拼装

  Expr 可以通过 append 方法实现两个表达式的拼接,示例代码:

/**
* 3、表达式的拼装
* */
public static void  demo3() {

    // 示例-1
    Expr expr1=new Expr("age>?",28);
    Expr expr2=new Expr("and height>?",182);
    // 通过  append 方法将 expr2 拼接到 expr1
    expr1.append(expr2);
    System.out.println(expr1.getSQL());
    // 输出:age> 28 and height> 182

    // 示例-2
    Expr expr3=new Expr("age>?",28);
    expr3.append("and height>?",182);
    System.out.println(expr1.getSQL());
    // 输出:age> 28 and height> 182

}

总结

  Foxnic-SQL 的 Expr 类负责SQL语句、子语句、语句片段中的绑定变量的解析。其目的是时最终执行的SQL语句对JDBC友好、对开发人员友好。Expr 是 Foxnic-SQL 这个语句体系的基石,后续其它的语句对象都是由 Expr 继承或组合而来。

相关项目

  https://gitee.com/LeeFJ/foxnic
  https://gitee.com/LeeFJ/foxnic-web
  https://gitee.com/lank/eam
  https://gitee.com/LeeFJ/foxnic-samples

官方文档

  http://foxnicweb.com/docs/doc.html

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
SQL条件语句(IF, CASE WHEN, IF NULL)
1.IF  表达式:IF(expr1,expr2,expr3)  expr1条件,条件为true,则值是expr2,false,值就是expr3SELECTo.id,u.account,catagory.name,orderTime,detail.amount,periodtime,if(direc
Wesley13 Wesley13
3年前
INFORMIX MATCHES的使用详解
MATCHES 运算符返回TRUE,如果一个字符串与给定的掩码匹配。语法 expr \NOT\ MATCHES mask \ESCAPE"char"\ expr是任何字符串表达式。mask是定义过滤器的字符串表达式。char是指定转义符号的单个字符。用法该mask可以是字符的任意组
Stella981 Stella981
3年前
Golang(四)正则表达式使用
0\.前言最近用到了regexp包,下面整理下正则表达式相关用法参考 基础知识Golang中的正则表达式(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fgolove%2Fp%2F3269099.htm
Stella981 Stella981
3年前
Scala系列4:轻松搞定Scala中for,if,while,块表达式等
0.条件表达式   条件表达式一般就是if表达式,if表达式可以根据给定的条件是否满足,根据条件的结果(真或假)决定执行对应的操作。scala条件表达式的语法和Java一样。0.1有返回值的if条件表达式_尖叫提示:_在scala中,跟Java不同,条件表达式也是有返回值的s
Wesley13 Wesley13
3年前
MySQL的if,case语句使用总结
Mysql的if既可以作为表达式用,也可在存储过程中作为流程控制语句使用,如下是做为表达式使用:IF表达式IF(expr1,expr2,expr3)如果expr1是TRUE(expr1<0andexpr1<NULL),则IF()的返回值为expr2;否则返回值则为expr3。IF()的返回值为数字值或
Stella981 Stella981
3年前
AJPFX总结关于Java中过滤出字母、数字和中文的正则表达式
1、Java中过滤出字母、数字和中文的正则表达式(1)过滤出字母的正则表达式\^(AZaz)\(2)过滤出数字的正则表达式\^(09)\(3)过滤出中文的正则表达式\^(\\\\u4e00\\\\u9fa5)\(4)过滤出字母、数字和中文的正则表达式\^(azAZ09\\\\u
Easter79 Easter79
3年前
thymeleaf在工作中常用的属性及表达式使用详解(三)
1.1 thymeleaf的基础知识介绍    1.1.1 标准表达式介绍它们分为四类:1.变量表达式2\.选择表达式(星号表达式)3\.消息表达式(井号表达式,资源表达式)通常做国际化4.URL表达式    
Stella981 Stella981
3年前
Python正则表达式精讲
_摘要:_ Python正则表达式精讲一、什么是正则表达式正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:RegularExpression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。Python正则表达式精讲一、什么是正则表达式正则表达式,又称正规表示式、正规表示法、正规表
Stella981 Stella981
3年前
Shell脚本应用(if语句的结构)
1、测试:检测表达式是否成立,成立则返回值为0,否则为非0方法:1)test 表达式2)【表达式】2、文件测试:\d:是否为目录\f:是否为文件\e:是否存在\r:是否有读取权限\w:是否有写入权限\x:是否有执行权限3、整数值比较:\eq:等于\ne:不等于\gt:大于\
LeeFJ LeeFJ
1年前
Foxnic-SQL (1) —— 快速入门(QuickStart)
<aname"k9Sn5"</aFoxnicSQL(1)——简介<aname"XffCP"</a概述FoxnicSQL是基于SpringJDBC开发的SQL语句执行与数据处理框架。她扩展