运行时SQL查询构建器

4
我的问题与以下讨论类似:Java中有没有好的动态SQL构建库?。其中有一点需要注意: Querydsl 和 jOOQ 似乎是最受欢迎和成熟的选择,但要注意的一点是:这两个工具都依赖于代码生成的概念,这就意味着为数据库表和字段生成元类。这样可以提供一个漂亮、清晰的 DSL,但是当尝试在运行时为仅在运行时已知的数据库创建查询时就会面临一个问题。除了使用纯 JDBC + 字符串拼接之外,是否有其他方法可以在运行时创建查询?我正在寻找一种可用于构建表单以查询现有数据库的 Web 应用程序。如果已经存在这样的产品,那么该产品的链接也将是受欢迎的。

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

2
尽管为数据库元数据生成源代码确实为使用 jOOQ 增加了很多价值,但这不是必需的。许多 jOOQ 用户使用 jOOQ 来完成您所设想的相同用例。这也反映在jOOQ 教程中,列出了使用 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的供应商工作)

1

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'

0

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

可以参考在Java中创建动态SQL查询

对于像基于从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,但查询仍然可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接