【问题标题】:Is there any good dynamic SQL builder library in Java? [closed]Java中有什么好的动态SQL构建器库吗? [关闭]
【发布时间】:2011-08-03 00:30:31
【问题描述】:

任何人都知道一些用于 Java 的优秀 SQL 构建器库,例如 Squiggle(似乎不再维护)。最好是正在积极开发中的项目。

最好使用像Zend_Db_Select 这样的语法,这样就可以进行类似的查询

String query = db.select().from('products').order('product_id');

【问题讨论】:

  • 请问上述语法相对于“SELECT f1..fn FROM products ORDER BY product_id”有什么优势?
  • @ItayMoav-Malimovka,好吧,至少在我的例子中 SQL 查询的语法(如果我们以 JOOQ 为例)在您编写代码时检查。您拥有完整的语法自动完成功能,可加快查询编写速度并使其更容易出错。
  • 我同意这是 IDE 应该改进的地方。
  • @ItayMoav-Malimovka,嗯......在 JOOQ 的情况下,如果我更改我的数据库结构中的某些内容,我的代码将停止编译,直到我根据新的数据库结构修复它。如果您将查询作为文本进行,它们将被破坏。
  • 例如:我目前正在开发一个应用程序,该应用程序需要创建语句才能在大型遗留数据库上工作。许多语句共享我们通过 SQL DSL 构建的自定义约束。多亏了这一点,我们可以轻松地创建在编译时未知的语句。

标签: java sql sqlbuilder


【解决方案1】:

QuerydsljOOQ 是两个流行的选择。

【讨论】:

  • JOOQ 可能是硬核 SQL 开发的更好选择,但 Querydsl 具有更简单的 API 并且还支持其他后端(JPA、JDO、Lucene、Mongodb 等);我也在 Querydsl 背后的公司
  • 我们在一些内部项目中使用 Querydsl SQL。我对jooq没有亲身经历,但听说还不错。
  • QueryDsl 的问题在于您不能将其用作纯查询生成器,因为它本身不会为您提供生成的查询。它也会生成查询并为您执行它。你不能没有另一个。
  • Querydsl 和 jOOQ 似乎是最流行和最成熟的选择,但有一点需要注意:两者都依赖于代码生成的概念,其中为数据库表和字段生成元类。这有利于一个漂亮、干净的 DSL,但是在尝试为仅在运行时知道的数据库创建查询时会遇到问题,就像上面的 OP 示例一样。虽然 jOOQ 支持基于字符串的方法,但存在一些怪癖。 Querydsl 的文档没有提到是否可以不使用代码生成。如果我错了,请纠正我。
  • @SvenJacobs 很老的评论,但要更新,QueryDSL 确实允许在不生成代码的情况下构建 sql:stackoverflow.com/questions/21615956/…
【解决方案2】:

您可以使用以下库:

https://github.com/pnowy/NativeCriteria

该库构建在 Hibernate“创建 sql 查询”之上,因此它支持 Hibernate 支持的所有数据库(支持 Hibernate 会话和 JPA 提供程序)。构建器模式可用等等(对象映射器、结果映射器)。

您可以在 github 页面上找到示例,该库当然可以在 Maven 中心获得。

NativeCriteria c = new NativeCriteria(new HibernateQueryProvider(hibernateSession), "table_name", "alias");
c.addJoin(NativeExps.innerJoin("table_name_to_join", "alias2", "alias.left_column", "alias2.right_column"));
c.setProjection(NativeExps.projection().addProjection(Lists.newArrayList("alias.table_column","alias2.table_column")));

【讨论】:

  • 这比手工写SQL要复杂
  • @EpicPandaForce 我同意非常简单的情况,但是当您需要基于非常复杂的条件(其中有一组不同的条件)连接该字符串时,连接非常复杂。那么正确连接的字符串(就像所有的添加、连接、拥有、参数集等)是一种痛苦。有了这个解决方案,您就有了一个可以为您处理这种复杂性的构建器。
【解决方案3】:

ddlutils是我最好的选择:http://db.apache.org/ddlutils/api/org/apache/ddlutils/platform/SqlBuilder.html

这里是创建示例(groovy):

Platform platform  = PlatformFactory.createNewPlatformInstance("oracle");//db2,...
//create schema    
def db =        new Database();
def t = new Table(name:"t1",description:"XXX");
def col1 = new Column(primaryKey:true,name:"id",type:"bigint",required:true);
t.addColumn(col1);
t.addColumn(new Column(name:"c2",type:"DECIMAL",size:"8,2"));
t.addColumn( new Column(name:"c3",type:"varchar"));
t.addColumn(new Column(name:"c4",type:"TIMESTAMP",description:"date"));        
db.addTable(t);
println platform.getCreateModelSql(db, false, false)

//you can read Table Object from  platform.readModelFromDatabase(....)
def sqlbuilder = platform.getSqlBuilder();
println "insert:"+sqlbuilder.getInsertSql(t,["id":1,c2:3],false);
println "update:"+sqlbuilder.getUpdateSql(t,["id":1,c2:3],false);
println "delete:"+sqlbuilder.getDeleteSql(t,["id":1,c2:3],false);
//http://db.apache.org/ddlutils/database-support.html

【讨论】:

  • 我必须再次定义列,虽然我已经在@Entity 中定义了它们,所以很痛苦。
【解决方案4】:

我可以推荐jOOQ。它提供了很多很棒的功能,还有一个直观的 SQL DSL 和一个极其可定制的逆向工程方法。

jOOQ 在流畅、直观的 DSL 中有效地结合了复杂的 SQL、类型安全、源代码生成、活动记录、存储过程、高级数据类型和 Java。

【讨论】:

  • 你用吗?你是怎么找到的?
  • 我用它从 DDL 生成自定义源代码。效果很好!
  • "虽然 jOOQ 库有一个很棒的用于构建 SQL 语句的 API,但它带有一整套工具来构建语句、连接到数据库、在数据库中写入/读取模型等。由于以 Android 应用 VM 的当前性质,有 64k 的方法引用限制。jOOQ 在使用时可以包含超过 10,000 个引用的方法。与限制相比,这可能看起来并不多,但如果您考虑其他常用的大型库(例如 Guava 和 Google Play Services),达到 64k 限制变得容易得多。” -- android-arsenal.com/details/1/3202 :(
【解决方案5】:

Hibernate Criteria API(虽然不是普通的 SQL,但非常强大且正在积极开发中):

List sales = session.createCriteria(Sale.class)
         .add(Expression.ge("date",startDate);
         .add(Expression.le("date",endDate);
         .addOrder( Order.asc("date") )
         .setFirstResult(0)
         .setMaxResults(10)
         .list();

【讨论】:

  • 问题是它并没有像我理解的那样映射到 SQL,对吧?
  • 这不会生成 SQL,并且当它不遵循最小惊讶规则时调试是一场噩梦(无法按预期工作)
  • 它确实会生成 SQL(在最后),它不会让任何人感到惊讶。好处——它可以跨数据库移植。
  • 在不使查询完全不可读的情况下,您使用 JPA Criteria API 达到的查询复杂程度是多少?您是否有 IN / EXISTS 子句中的嵌套选择示例,或者使用 Sale 实体的别名的自联接等?我很好奇
  • 评论没有太多空间来提供示例,但欢迎您通过docs.jboss.org/hibernate/core/3.5/reference/en/html/…查看它们
猜你喜欢
  • 2011-02-09
  • 2023-03-14
  • 2010-12-09
  • 2011-08-27
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2010-11-06
相关资源
最近更新 更多