Java'da iyi bir dinamik SQL oluşturucu kitaplığı var mı? [kapalı]


108

Herkes Squiggle gibi Java için bazı iyi SQL oluşturucu kitaplıklarını bilir (artık bakılmıyor gibi görünüyor). Tercihen aktif geliştirme aşamasında bir proje.

Tercihen Zend_Db_Select gibi bir sözdizimi ile, aşağıdaki gibi bir sorgu yapmaya izin verecek bir şey

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

Yukarıdaki sözdiziminin "SELECT f1..fn ürününden ürün_kimliği ile SİPARİŞ VER" e karşı avantajının ne olduğunu sorabilir miyim?
Itay Moav -Malimovka

4
@ ItayMoav-Malimovka, Benim durumumda en azından SQL sorgusunun sözdizimi (JOOQ'u örnek olarak alırsak) kodu yazarken kontrol edilir. Tam sözdizimi otomatik tamamlama özelliğine sahipsiniz, bu da sorgu yazmanızı hızlandırır ve daha fazla hataya açık hale getirir.
Vladislav Rastrusny

Bunun IDE'lerin geliştirmesi gereken bir şey olduğuna katılıyorum.
Itay Moav -Malimovka

1
@ ItayMoav-Malimovka, peki ... JOOQ durumunda, DB yapımda bir şeyi değiştirirsem, kodum yeni DB yapısına göre düzeltene kadar derlemeyi durduracak. Metin olarak sorgularınız varsa, bunlar bozuk kalır.
Vladislav Rastrusny

Örnek olarak: Şu anda devasa bir eski veritabanı üzerinde çalışmak için ifadeler oluşturması gereken bir uygulama üzerinde çalışıyorum. Birçok ifade, bir SQL DSL ile oluşturduğumuz özel kısıtlamaları paylaşır. Bu sayede derleme sırasında bilinmeyen ifadeleri kolaylıkla oluşturabiliyoruz.
Rafael Winterhalter

Yanıtlar:


54

Querydsl ve jOOQ iki popüler seçenektir.


6
JOOQ, zorlu SQL geliştirme için belki daha iyi bir seçimdir, ancak Querydsl daha basit bir API'ye sahiptir ve diğer arka uçları da destekler (JPA, JDO, Lucene, Mongodb vb.); Ben de Querydsl
Timo Westkämper'ın

Querydsl SQL'i şirket içi projelerimizden birkaçında kullanıyoruz. Kişisel jooq deneyimim yok ama oldukça iyi olduğunu duydum.
ponzao

11
QueryDsl ile ilgili sorun, size üretilen sorgunun kendisini vermediği için onu saf bir sorgu oluşturucu olarak kullanamamanızdır. Sorguyu oluşturacak ve sizin için de yürütecektir. Biri olmadan bir tane elde edemezsin.
Abhinav Sarkar

5
Querydsl ve jOOQ en popüler ve olgun seçenekler gibi görünüyor, ancak dikkat edilmesi gereken bir şey var: Her ikisi de, veritabanı tabloları ve alanları için meta sınıfların oluşturulduğu kod üretme kavramına dayanıyor. Bu güzel, temiz bir DSL sağlar, ancak yukarıdaki OP örneğinde olduğu gibi yalnızca çalışma zamanında bilinen veritabanları için sorgular oluşturmaya çalışırken bir sorunla karşılaşır. JOOQ, String tabanlı bir yaklaşımı desteklerken, bazı tuhaflıklar vardır. Querydsl dokümantasyonu, kod üretimini kullanmamanın mümkün olup olmadığını belirtmez. Yanılıyorsam lütfen beni düzeltin.
Sven Jacobs

3
Çok eski yorumunu @SvenJacobs ancak güncelleme, QueryDSL kod oluşturma olmadan sql bina izin vermez: stackoverflow.com/questions/21615956/...
Nagaraj Tantri

7

ddlutils en iyi seçimim: http://db.apache.org/ddlutils/api/org/apache/ddlutils/platform/SqlBuilder.html

İşte örnek oluşturun (harika):

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
Sütunu yeniden tanımlamam gerekiyor, ancak bunları @Entity'de tanımlamış olsam da, çok acı.
huuthang

6

JOOQ'u tavsiye edebilirim . Çok sayıda harika özellik, ayrıca SQL için sezgisel bir DSL ve son derece özelleştirilebilir bir tersine mühendislik yaklaşımı sağlar.

jOOQ, karmaşık SQL, tür güvenliği, kaynak kodu oluşturma, aktif kayıtlar, depolanmış prosedürler, gelişmiş veri türleri ve Java'yı akıcı, sezgisel bir DSL'de etkili bir şekilde birleştirir.


Onu kullanır mısın? Bunu nasıl buluyorsun?
Vladislav Rastrusny

3
DDL'den özel kaynak kodu oluşturmak için kullanıyorum. Harika çalışıyor!
Christopher Klewes

"JOOQ kitaplığı SQL ifadeleri oluşturmak için harika bir API'ye sahip olsa da, ifadeler oluşturmak, veritabanlarına bağlanmak, veritabanlarına / veritabanlarından modeller yazmak / okumak vb. İçin eksiksiz bir araç paketiyle birlikte gelir. Android uygulama sanal makinesinin mevcut yapısı nedeniyle , 64k yöntem referans sınırı vardır. jOOQ, kullanımdayken 10.000'den fazla başvurulan yöntemi içerebilir. Bu, sınıra kıyasla çok fazla görünmeyebilir, ancak yaygın olarak kullanılan diğer büyük kitaplıkları (Guava ve Google Play Hizmetleri gibi) göz önünde bulundurursanız 64k sınırına ulaşmak çok daha kolay hale geliyor. " - android-arsenal.com/details/1/3202 :(
Tomáš Fejfar

3

Hibernate Criteria API (düz SQL değil, ancak çok güçlü ve aktif geliştirme aşamasında):

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
Sorun şu ki anladığım kadarıyla SQL ile eşleşmiyor, değil mi?
Vladislav Rastrusny

7
bu SQL oluşturmaz ve en az şaşkınlık kuralına uymadığında hata ayıklamak için bir

SQL üretir (sonunda) ve kimseyi şaşırtmaz. Fayda - veritabanları arasında taşınabilir.
Vladimir Dyuzhev

3
Sorguyu tamamen okunamaz hale getirmeden, JPA Criteria API ile ulaşmayı başardığınız sorgu karmaşıklığı düzeyi nedir? Bir IN/ EXISTScümlesinde iç içe geçmiş bir seçim veya Salevarlık için takma adlar kullanan bir kendi kendine birleşim , vb. İçin bir örnek var mı? Merak ediyorum
Lukas Eder

1
Yorumlar örnekleri sağlamak için fazla yer vermez, ancak bunları docs.jboss.org/hibernate/core/3.5/reference/en/html/…
Vladimir Dyuzhev

0

Aşağıdaki kitaplığı kullanabilirsiniz:

https://github.com/pnowy/NativeCriteria

Kitaplık, Hazırda Bekletme "sql sorgusu oluştur" un üstüne inşa edilmiştir, böylece Hazırda Bekletme tarafından desteklenen tüm veritabanlarını destekler (Hazırda Bekletme oturumu ve JPA sağlayıcıları desteklenir). Oluşturucu pıtırtı kullanılabilir ve benzeri (nesne eşleyicileri, sonuç eşleyicileri).

Örnekleri github sayfasında bulabilirsiniz, kütüphane elbette Maven merkezinde mevcuttur.

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

Bu, SQL'i elle yazmaktan daha karmaşık
EpicPandaForce

@EpicPandaForce Çok basit durumları kabul ediyorum, ancak bu dizgeyi, bu koşulların farklı bir kümesinin olduğu çok karmaşık koşullara dayanarak birleştirmeniz gerektiğinde çok karmaşıktır. Doğru şekilde birleştirilmiş dize (tüm eklemeler, birleştirmeler, sahip olma, ayarlanan parametreler vb. Gibi) bir acıdır. Çözüm ile bu karmaşıklığı sizin için halledecek bir kurucuya sahip olursunuz.
Przemek Nowak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.