让我在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为例
是什么让“旧COBOL”方法不受欢迎?不仅是SQL,而且使用该方法可以使系统调用更具可读性。我们称之为嵌入式外语预处理器方法。
用于SQL的嵌入式外语预处理器是否可用于实现?您是否会看到能够在Java代码中编写本机SQL语句的好处?
我真的在问你是否认为OO语言中的SQL是一种回归,如果没有,那么可以采取哪些措施来改善它。
答案 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)
对于目前的情况,我可以提供以下几点
嵌入sql作为语言的一部分存在许多问题:
另一方面,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,例如Eclipse,NetBeans或IntelliJ IDEA,这是针对预处理器(we also wrote about this in our blog)的强大参数。
与此同时,像Eclipse Xtext或JetBrains 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的数据库,您可以在代码中嵌入查询。