【问题标题】:Embedded SQL in OO languages like Java面向 Java 等面向对象语言的嵌入式 SQL
【发布时间】:2014-04-06 00:23:38
【问题描述】:

让我在 OO 语言中使用 SQL 时感到烦恼的一件事是必须在字符串中定义 SQL 语句。

当我以前在 IBM 大型机上工作时,这些语言使用 SQL 预处理器从本机代码中解析 SQL 语句,因此这些语句可以用明文 SQL 编写,而不会混淆字符串,例如在 Cobol 中有一个EXEC SQL .... END-EXEC 语法结构,允许纯 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 语句非常易于阅读和检查错误。在 EXEC SQL .... END-EXEC 标记之间没有缩进、换行等限制,因此您可以根据喜好格式化 SQL 语句。

请注意,此示例适用于单行选择,当需要多行结果集时,编码是不同的(但仍然易于阅读)。

那么,以Java为例

  1. 是什么让 “旧 COBOL” 方法不受欢迎?不仅是 SQL,而且系统调用也可以通过这种方法变得更具可读性。我们称之为嵌入式外语预处理器方法。

  2. 嵌入式外语预处理器用于 SQL 是否有用?您会看到能够在 Java 代码中编写本机 SQL 语句的好处吗?

编辑

我真的想问你是否认为 OO 语言中的 SQL 是一种倒退,如果不是,那么可以做些什么来使它变得更好。

【问题讨论】:

    标签: java sql preprocessor


    【解决方案1】:

    Java 中已经有一个嵌入式 SQL 标准,称为SQLJ

    话虽如此,但我从未见过它在野外使用过,而且我不知道它是否真的是一种选择,使用现代工具。当标准出现时,Oracle 大力支持它,但我认为它已经死了。

    【讨论】:

    • 在某种程度上,我想知道 ORM 的流行程度,并进一步想知道简单直接的 SQL 是否正在成为一门失传的艺术。也许 TTM 项目会拯救我们所有人……
    • 我认为只是大多数程序员讨厌 SQL。当我们的 (Perl) 商店针对所有数据库事务对 DBIx::Class 进行标准化时,率先采用它的人之一直接说:“我讨厌 SQL”。对于生产代码,我仍然有点同意这种心态,主要是因为 SQL 的所有各种方言都非常不兼容。但这些年来,我对普通的 SQL 有点热身,并在我的个人代码中使用了更多。
    • 有趣的 HM 人似乎认为编写特定方言的 SQL 是不可避免的(或无关紧要),不幸的是 DBMS 供应商鼓励这样做来销售产品。一旦你完成了几个大型系统移植,你就会非常喜欢简单的旧 SQL。对我来说,我看不出 ORM 有什么帮助,因为你永远不会移植到同一个数据库结构。
    • 如果我们谈论的是同一个应用程序,ORM 确实有助于移植,结构更改可以在 ORM 级别完成,您无需修改​​代码。
    • 我真的不明白为什么这么多程序员自称“讨厌”SQL。就个人而言,我讨厌 ORM。
    【解决方案2】:

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

    此外,人们通常会使用完整的 ORM(如 Hibernate)来抽象出 SQL。

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

    编辑:我确实认为混合 SQL 和代码(无论是否为 OO)是脆弱且不可取的。有一个集中的地方来存储您的查询要好得多。这就是 iBATIS 方法。

    【讨论】:

      【解决方案3】:

      对象-关系映射工具,例如 Hibernate,理论上可以减少这类问题。 “理论上” ;)

      另外,如果您可以使用 Grails,我听说您可以编写出色的多行字符串,从而更轻松地阅读 SQL 语句。

      【讨论】:

      • re 多行字符串,Python 也是如此
      【解决方案4】:

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

      【讨论】:

      • 问题的一部分是“字符串文字的内部”
      【解决方案5】:

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

      • 如上所述,java 中有技术可以做到这一点:SQLJ 从未采用过。
      • 通常使用 ORM 来获得类似的结果(iBatisHibernate 是我在这里最关心的人
      • C# 的 LINQ 功能类似

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

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

      另一方面,DSL 现在都是炒作。并且有些语言具有 XML 文字。因此,我认为很有可能出现(或已经存在)嵌入了类似 ORM 的功能并允许您在代码中使用 SQL(或 HQL?)如 DSL 的语言。

      【讨论】:

      • 我想是的。这就是为什么我认为 DSL 的炒作和 SQL 的嵌入确实相互关联
      【解决方案6】:

      SQLJ 这样的方法的主要缺点之一是预处理器会阻止将现代 IDE 工具用于您的数据访问逻辑。对于像 EclipseNetBeansIntelliJ IDEA 这样的优秀 IDE,这是反对预处理器 (we also wrote about this in our blog) 的有力论据。

      与此同时,像 Eclipse XtextJetBrains MPS 这样的 DSL 工具仍在努力增强 Java 语言本身,以便拥有像以前在 COBOL 中所拥有的东西。

      一种选择是使用像jOOQ 这样的内部DSL 来完成这项工作,尽管这并不是真正的SQL

      【讨论】:

        【解决方案7】:

        嗯,最简单、最费脑筋的方法就是将 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 的数据库,您可以在代码中直接嵌入查询。

        【讨论】:

        • 它们允许您嵌入“查询”,但不能嵌入 SQL。
        猜你喜欢
        • 1970-01-01
        • 2018-08-02
        • 1970-01-01
        • 1970-01-01
        • 2011-08-01
        • 2011-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多