【问题标题】:Runtime SQL Query Builder运行时 SQL 查询生成器
【发布时间】:2014-04-02 05:31:43
【问题描述】:

我的问题类似于

Is there any good dynamic SQL builder library in Java?

然而,从上面的线程中得到一个重要的观点:

Querydsl 和 jOOQ 似乎是最流行和最成熟的选择,但有一点需要注意:两者都依赖于代码生成的概念,其中为数据库表和字段生成元类.这有助于创建一个漂亮、干净的 DSL,但它在尝试为仅在运行时知道的数据库创建查询时会遇到问题

除了使用普通的 JDBC + 字符串连接之外,还有什么方法可以在运行时创建查询?

我正在寻找的是一个可用于构建表单以查询现有数据库的 Web 应用程序。现在,如果已经存在类似产品的链接,也将受到欢迎。

【问题讨论】:

  • 问题是,你真的想要吗?能够自动生成和运行查询可能会对性能产生负面影响。
  • @Ashalynd:动态 SQL 总是会带来轻微的性能影响。我认为您无法完全避免这种情况...

标签: java sql runtime query-builder


【解决方案1】:

虽然数据库元数据的源代码生成无疑为使用jOOQ 增加了很多价值,但这不是先决条件。许多 jOOQ 用户将 jOOQ 用于您设想的相同用例。这也反映在jOOQ tutorials 中,它列出了使用 jOOQ 而不生成代码作为一个完全有效的用例。例如:

String sql = create.select(
                        fieldByName("BOOK","TITLE"), 
                        fieldByName("AUTHOR","FIRST_NAME"), 
                        fieldByName("AUTHOR","LAST_NAME"))
                   .from(tableByName("BOOK"))
                   .join(tableByName("AUTHOR"))
                   .on(fieldByName("BOOK", "AUTHOR_ID").eq(
                        fieldByName("AUTHOR", "ID")))
                   .where(fieldByName("BOOK", "PUBLISHED_IN").eq(1948))
                   .getSQL();

以类似的方式,可以使用Query.getBindValues() 从任何查询中提取绑定值。

对于动态 SQL 语句,这种方法仍然优于普通的 JDBC + 字符串连接,因为您无需担心:

  • 语法正确性
  • 跨数据库兼容性
  • SQL 注入
  • 绑定变量索引

(免责声明:我为 jOOQ 的供应商工作)

【讨论】:

    【解决方案2】:

    SQLBuilder http://openhms.sourceforge.net/sqlbuilder/ 对我非常有用。 一些简单的例子:

        String query1 = new InsertQuery("table1")
                .addCustomColumn("s01", "12")
                .addCustomColumn("stolbez", 19)
                .addCustomColumn("FIRSTNAME", "Alexander")
                .addCustomColumn("LASTNAME", "Ivanov")
                .toString();
    
        String query2 = new UpdateQuery("table2")
                .addCustomSetClause("id", 1)
                .addCustomSetClause("FIRSTNAME", "Alexander")
                .addCustomSetClause("LASTNAME", "Ivanov")
                .toString();
    

    结果:

    INSERT INTO table1 (s01,stolbez,FIRSTNAME,LASTNAME) VALUES ('12',19,'Alexander','Ivanov')
    UPDATE table2 SET id = 1,FIRSTNAME = 'Alexander',LASTNAME = 'Ivanov'
    

    【讨论】:

      【解决方案3】:

      我有一个自定义解决方案,用于动态生成此类 SQL 查询,只需 2-3 个类即可满足类似要求。这是一个简单的方法。

      这可以参考Creating Dynamic SQL queries in Java

      对于更简单的用例,例如基于从 UI 中选择的输入的动态过滤条件,可以通过直接修改以下样式的查询来使用以下更简单的方法:

      select t1.id, t1.col1, t1.col2,
        from table1 t1
      where (:col1Value is null or t1.col1 = :col1Value)
          and (:col2Value is null or t1.col2 = :col2Value);
      

      这里 col1 或 col2 的值可以为 null,但查询可以正常工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多