代码之家  ›  专栏  ›  技术社区  ›  Steve De Caux

嵌入式SQL在OO语言中的应用

  •  7
  • Steve De Caux  · 技术社区  · 15 年前

    在oo语言中使用sql最让我恼火的事情之一就是必须用字符串定义sql语句。

    当我在IBM大型机上工作时,语言使用一个SQL预处理器来从本机代码中解析SQL语句,因此这些语句可以用明文SQL编写,而不需要混淆字符串,例如在COBOL中 执行SQL…最终执行人 允许 纯SQL语句 成为 嵌入的 在COBOL代码中。

    <pure cobol code, including assignment of value
     to local variable HOSTVARIABLE>    
    
    EXEC SQL
           SELECT COL_A, COL_B, COL_C
           INTO :COLA, :COLB, :COLC
           FROM TAB_A
           WHERE COL_D = :HOSTVARIABLE
    END_EXEC
    
    <more cobol code, variables COLA, COLB, COLC have been set>
    

    …这使得SQL语句非常易于读取和检查错误。之间 执行SQL…最终执行人 标记在缩进、换行等方面没有限制,因此可以根据品味格式化sql语句。

    注意,这个例子是针对一个行选择,当一个多行结果集是预期的,编码是不同的(但仍然v.容易阅读)。

    因此,以Java为例

    1. 是什么造就了 “旧COBOL” 接近不受欢迎?不仅是sql,而且使用这种方法可以使系统调用更具可读性。我们称之为 嵌入式外语预处理器 方法。

    2. 会不会 嵌入式外语预处理器 对于sql的实现有用吗?您能在Java代码中编写本机SQL语句吗?

    编辑

    我真的在问你是否认为oo语言中的sql是一种倒退,如果不是,那么我们可以做些什么来改进它。

    7 回复  |  直到 15 年前
        1
  •  4
  •   skaffman    15 年前

    在Java中已经有了嵌入式SQL的标准,它被称为 SQLJ .

    话虽如此,我从未见过它在野外使用,我也不知道它是否真的是一个选择了,与现代工具。当标准出现时,甲骨文在很大程度上支持它,但我认为它已经死在葡萄树上了。

        2
  •  2
  •   Vinko Vrsalovic    15 年前

    在SQL域中已经有类似于Java和.NET的“嵌入式语言预处理器”: http://ibatis.apache.org/

    另外,人们通常使用成熟的orm,比如 Hibernate ,以抽象出SQL。

    请注意,这些工具不允许在Java代码本身中存储SQL字符串,但服务于类似的意图。我个人认为在代码本身中存储sql字符串没有任何好处,因为这通常比较混乱。将所有sql整齐地写入一个特定的文件有助于sql的可重用性和可维护性。如果需要的话,它们确实允许sql作为字符串,但这通常是作为最后的措施(当orm工具对您的用例没有很好的抽象时)。

    编辑:我认为混合sql和代码(不管是不是oo)是脆弱的,不可取的。最好有一个集中的地方来存储查询。这是iBATIS方法。

        3
  •  1
  •   Timothy    15 年前

    对象关系映射工具(如Hibernate)理论上可以减少此类问题。”理论上“)

    另外,如果您可以使用grails,我听说您可以编写非常好的多行字符串,这使得读取sql语句更加容易。

        4
  •  1
  •   Konstantin Solomatov    15 年前

    你可以用一个像样的ide来解决这样的问题。例如,intellij idea支持一种称为注入式语言的特性。它允许您在字符串文本中使用所需的语言编写代码,并能够使用代码突出显示、完成、导航和其他服务。您可以在这里阅读更多信息: http://blogs.jetbrains.com/idea/2009/03/user-defined-language-injection/

        5
  •  1
  •   Esko    14 年前

    对于目前的情况,我可以提出以下几点

    • 如上所述,Java中有一种技术是这样做的: SQLJ 从来没想过。
    • 通常使用orm得到类似的结果( iBatis Hibernate 是我在这里最关心的人
    • C有一个做类似事情的LINQ

    将SQL作为语言的一部分嵌入有许多问题:

    • 它倾向于将您的语言与数据库供应商联系起来,因为不同的sql方言非常不同。对于大多数现代语言来说,这是不可能的。这对cobol来说不是问题,因为可移植性不是必需的。
    • 它要么使语言方式更复杂,要么需要预处理,两者本身都是坏事。但是在现代ide中,情况更糟,因为它们很难在代码中处理sql(尽管它们实际上已经开始这样做了,即使sql嵌入到字符串中)。这对cobol来说不是问题,因为在现代意义上,cobol是一种难听的语言(尽管当cobol被发明时它可能很好)
    • 它需要难以控制的编译资源(即数据库),并且遵循与“正常”编程完全不同的方法。同样,cobol程序和它的数据库几乎是融合在一起的,所以没有问题。
    • sql不适合oo范式。它返回值的二维数组,而不是对象。所以你还是需要某种虫子。

    另一方面,DSL现在都是大肆宣传。还有一些语言有xml文本。因此,我认为很有可能出现(或已经存在)具有类似orm功能的语言,并允许您使用sql(或hql?)就像代码中的dsl。

        6
  •  0
  •   Lukas Eder    10 年前

    这种方法的主要缺点之一是 SQLJ 事实上,预处理器将阻止为数据访问逻辑使用现代ide工具。具有优秀的IDE,如 Eclipse , NetBeans IntelliJ IDEA ,这是反对预处理器的有力论据。( we also wrote about this in our blog )

    同时,dsl工具 Eclipse Xtext JetBrains MPS 仍在努力增强Java语言本身,以便拥有像以前在COBOL中所拥有的东西。

    一种选择是使用内部DSL jOOQ 尽管这不是真正的sql

        7
  •  -2
  •   Chad Okere    15 年前

    好吧,最简单、最无脑的方法就是将sql作为字符串包含在代码中。

    有点像

       Statement s = new Statement("Select * from wherever");
    

    这可能不是很复杂,但它是有效的。缺点是编译器无法检查您的sql语法。稍微好一点的解决方案是 Prepaired Statements 指定参数模板的位置。所以你可以做如下事情:

    PreparedStatement s = connection.prepareStatement("Select * from wherever where state = ?");
    

    这样,您的jdbc连接 应该 在运行时创建准备好的语句时立即引发异常。因此,如果代码第一次工作,它应该一直工作。

    然后在以后要更改参数时在代码中执行以下操作:

    s.setString(1, "CA");
    

    Microsoft有一种嵌入的.NET查询语言,名为 LINQ . 对于您使用的数据库 LINQ to SQL 它允许您在代码中嵌入查询。