嵌入式SQL,如Java等OO语言

时间:2010-01-08 08:53:40

标签: java sql preprocessor

让我在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语句真的很容易阅读&amp;检查错误。在 EXEC SQL .... END-EXEC 标记之间,对缩进,换行等没有限制,因此您可以根据品味格式化SQL语句。

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

所以,以Java为例

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

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

  3. 修改

    我真的在问你是否认为OO语言中的SQL是一种回归,如果没有,那么可以采取哪些措施来改善它。

7 个答案:

答案 0 :(得分:4)

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

话虽如此,我从未见过它在野外使用,我不知道它是否真的是一个选项,现代工具。当标准出现时,甲骨文大力支持它,但我认为它在藤蔓上死了。

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:1)

对象关系映射工具,例如Hibernate,理论上会使这类东西成为一个问题。 “理论上”;)

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

答案 3 :(得分:1)

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

  • 如上所述,java中的技术有:SQLJ从未使用过。
  • 通常使用ORM来获得类似的结果(iBatisHibernate是我最常见的结果
  • C#有LINQ做类似的事情

嵌入sql作为语言的一部分存在许多问题:

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

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

答案 4 :(得分:1)

您可以使用体面的IDE解决此类问题。例如,IntelliJ IDEA支持称为注入语言的功能。它允许您在字符串文字内以您想要的语言编写代码,并能够使用代码突出显示,完成,导航和其他服务。您可以在此处详细了解:http://blogs.jetbrains.com/idea/2009/03/user-defined-language-injection/

答案 5 :(得分:0)

SQLJ这样的方法的一个主要缺点是预处理器会阻止现代IDE工具用于数据访问逻辑。借助优秀的IDE,例如EclipseNetBeansIntelliJ IDEA,这是针对预处理器(we also wrote about this in our blog)的强大参数。

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

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

答案 6 :(得分:-2)

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