Java中是否有任何好的动态SQL构建器库?[关闭]


108

任何人都知道Java的一些不错的SQL构建器库,例如Squiggle(似乎不再维护了)。最好是积极发展的项目。

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

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

请问上面的语法对“ SELECT f1..fn FROM products ORDER BY product_id”有什么好处?
伊泰·莫阿夫

4
@ ItayMoav-Malimovka,好吧,至少在我的情况下,SQL语法的语法(如果我们以JOOQ为例)在编写代码时已经过检查。您具有完整的语法自动完成功能,可加快查询编写速度,并使其更易于出错。
弗拉迪斯拉夫·拉斯特鲁尼(Fladislav Rastrusny),2013年

我同意这是IDE应当改进的地方。
伊泰·莫阿夫

1
@ ItayMoav-Malimovka,好吧...就JOOQ而言,如果我更改数据库结构,我的代码将停止编译,直到根据新的数据库结构对其进行修复为止。如果您有文字查询,这些查询将不完整。
弗拉迪斯拉夫·拉斯特鲁尼(Fladislav Rastrusny),2013年

举个例子:我目前正在开发一个需要创建语句才能在大型遗留数据库上工作的应用程序。许多语句共享我们通过SQL DSL构建的自定义约束。因此,我们可以轻松创建在编译时未知的语句。
拉斐尔·温特豪德

Answers:


53

QuerydsljOOQ是两个流行的选择。


6
JOOQ可能是进行核心SQL开发的更好选择,但是Querydsl具有更简单的API,并且还支持其他后端(JPA,JDO,Lucene,Mongodb等);我也在Querydsl背后的公司里
TimoWestkämper2011年

我们在一些内部项目中使用Querydsl SQL。我没有jooq的个人经历,但听说还可以。
ponzao 2011年

11
QueryDsl的问题在于您不能将其用作纯查询生成器,因为它不提供生成的查询本身。它将生成查询并为您执行它。你不能一无所有。
Abhinav Sarkar

5
Querydsl和jOOQ似乎是最受欢迎和最成熟的选择,但是需要注意的一件事:两者都依赖于代码生成的概念,其中为数据库表和字段生成元类。这有助于建立一个漂亮,干净的DSL,但在尝试为仅在运行时才知道的数据库创建查询时会遇到问题,例如上述OP的示例。尽管jOOQ支持基于字符串的方法,但仍有一些怪癖。Querydsl的文档没有提到是否可以不使用代码生成。如果我错了,请纠正我。
Sven Jacobs

3
@SvenJacobs很老的评论,而是要更新,QueryDSL确实允许构建SQL没有代码生成:stackoverflow.com/questions/21615956/...
Nagaraj Tantri

7

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

这是创建示例(常规):

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

1
尽管我已经在@Entity中定义了列,但我不得不再次定义列,所以很痛苦。
huuthang

6

我可以推荐jOOQ。它提供了许多强大的功能,还提供了用于SQL的直观DSL和极其可定制的逆向工程方法。

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


你会用吗?你是怎么找到它的?
Vladislav Rastrusny 2011年

3
我用它从DDL生成自定义源代码。效果很好!
Christopher Klewes 2011年

“尽管jOOQ库具有用于构建SQL语句的出色API,但它附带了一整套工具来构建语句,连接数据库,向数据库写入模型/从数据库读取模型等。由于Android应用程序VM的当前性质, ,方法引用的上限为64k。jOOQ在使用时可以包含10,000多个引用的方法,与该限制相比似乎不算多,但是如果您考虑其他常用的大型库(例如Guava和Google Play服务) ,达到64k的限制变得容易得多。” - android-arsenal.com/details/1/3202 :(
托马什Fejfar

3

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();

1
问题在于,据我了解,它不会映射到SQL,对吗?
Vladislav Rastrusny 2011年

7
这不会生成SQL,并且在不遵循最小惊讶规则(无法按预期工作)时进行调试也是噩梦

它确实生成了SQL(最后),并且没有人感到惊讶。好处-它可跨数据库移植。
Vladimir Dyuzhev 2011年

3
您使用JPA Criteria API达到的查询复杂程度是什么,而又使查询完全不可读?您是否有一个IN/ EXISTS子句中的嵌套select的示例,或使用Sale实体别名的自联接的示例,等等?我很好奇
Lukas Eder

1
注释没有足够的空间提供示例,但是欢迎您在docs.jboss.org/hibernate/core/3.5/reference/en/html/…上
Vladimir Dyuzhev 2011年

0

您可以使用以下库:

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

@EpicPandaForce我同意非常简单的情况,但是当您需要基于非常复杂的条件(其中存在一组不同的条件)来连接该字符串时,连接非常复杂。这样,正确连接的字符串(就像所有添加,联接,具有,参数集等)非常麻烦。使用该解决方案,您将拥有一个可以为您解决这种复杂性的构建器。
Przemek Nowak
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.