如何在源代码中处理巨大的SQL字符串

时间:2008-12-19 22:07:14

标签: java sql coding-style

我正在开发一个项目,目前代码中的SQL字符串大约有3000行。

该项目是一个java项目,但这个问题可能适用于任何语言。

无论如何,这是我第一次看到这么糟糕的事情。 代码库是遗留的,因此我们可以突然迁移到Hibernate或类似的东西。

如何处理非常大的SQL字符串?

我知道它很糟糕,但我不确切地知道解决方案的最佳建议是什么。

12 个答案:

答案 0 :(得分:11)

在我看来,将这些硬编码的值转换为存储过程并从代码中引用sprocs可能会产生高产量和低成本。

答案 1 :(得分:6)

SQL是否有很多变量的字符串连接?

如果没有,您可以将它们提取出来放入资源文件中。但是你必须删除换行符中的字符串conatentation。

您使用的存储过程方法非常好,但有时当需要了解SQL正在做什么时,您必须从工作区切换到您喜欢的SQL IDE。这是唯一的坏事。

对于我的建议,它会是这样的:

String query = "select ......."+
3000 lines.

ResourceBundle bundle = ResourceBundle.getBundle("queries");
String query = bundle.getString( "customerQuery" );

那就是这个想法。

答案 2 :(得分:3)

我想第一个问题是,你应该用它做什么?如果它没有被打破,请静静地将它关闭并假装你从未见过它。否则,重构就像疯了一样 - 希望某些退出条件看起来像合同。

答案 3 :(得分:2)

到目前为止,我能想出的最好的事情是将查询放入几个存储过程,就像我在Java中处理一个太长的方法一样。

答案 4 :(得分:2)

我和你在同一个地方......我的计划是将SQL拉入项目中的separate.sql文件,并创建一个实用程序方法,以便在需要查询时读取文件。

string sql = "select asd,asdf,ads,asdf,asdf," 
           + "from asdfj asfj as fasdkfjl asf"
           + "..........................."
           + "where user = @user and ........";

查询被转储到名为usageReportByUser.sql的文件中 而这就变成了这样。

string sql = util.queries("usageReportByUser");

确保以文件无法公开访问的方式完成。

答案 5 :(得分:1)

我在PHP中做的是:

$query = "SELECT * FROM table WHERE ";
$query .= "condition < 5 AND ";
$query .= "condition2 > 10 AND ";

然后,在$query上完成分层后:

mysql_query($query);

答案 6 :(得分:1)

使用框架iBatis

答案 7 :(得分:1)

我暂时写了toolkit并在几个项目中使用过它。它允许您将查询放在大多数文本文件中,并为它们生成绑定和文档。

查看this exampleexample use(它几乎只是编译为带有早期绑定/类型安全查询绑定的java类的预准备语句)。

它也产生了一些不错的javadoc,但我目前还没有任何在线版本。

答案 8 :(得分:1)

我的第二个iBatis推荐。至少,您可以从最可能使用StringBuffer的Java代码中取出SQL,并将String concat追加到XML中,这样可以更容易维护。

我为遗留的Web应用程序做了这个,我打开调试并运行DAO的单元测试,并将生成的每个语句的sql复制到iBatis xml中。工作得相当顺利。

答案 9 :(得分:0)

一种简单的方法是将它们分解成某种常量。这至少会使代码更具可读性。

答案 10 :(得分:0)

我将它们存储在文件(或资源)中,然后在应用程序启动时读取并缓存它们(如果是服务或其他内容,则更改)。

或者,只需将它们放入一个大的旧SqlQueries类中作为consts或readonlys。

答案 11 :(得分:0)

我已成功将大型动态查询转换为linq查询。 (1K行+)这适用于在相对较少数量的表上进行大量动态过滤和动态分组的报告场景。为这些表创建一个edmx,您可以编写出色的强类型可组合查询。

我发现性能实际上得到了改善,并且生成的sql更加简单。 我相信你会得到与Hibernate类似的里程 - 除了能够使用linq ofcourse。但一般来说,如果生成的sql需要高度动态,那么它不是存储过程的良好候选者。在存储过程中编写动态sql是两个世界中最糟糕的。 sql生成框架将是我首选的方式。如果你挖掘Hibernate,我认为这将是一个很好的解决方案。

话虽如此,如果查询只是带参数的简单字符串,那么只需将它们放入存储过程中即可完成。 - 但是你错过了使用对象的结果。