Apakah ada pustaka pembuat SQL dinamis yang bagus di Java? [Tutup]


108

Ada yang tahu beberapa pustaka pembuat SQL yang bagus untuk Java seperti Squiggle ( sepertinya tidak dipertahankan lagi). Lebih disukai, proyek dalam pengembangan aktif.

Lebih disukai dengan sintaks seperti Zend_Db_Select , sesuatu yang memungkinkan untuk membuat kueri seperti

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

Bolehkah saya bertanya apa keuntungan sintaks di atas terhadap "SELECT f1..fn FROM products ORDER BY product_id"?
Itay Moav -Malimovka

4
@ ItayMoav-Malimovka, Yah, setidaknya sintaks kueri SQL dalam kasus saya (jika kita mengambil JOOQ sebagai contoh) diperiksa pada saat Anda menulis kode. Anda memiliki pelengkapan otomatis sintaks penuh yang mempercepat penulisan kueri Anda dan membuatnya lebih rentan terhadap kesalahan.
Vladislav Rastrusny

Saya setuju bahwa ini adalah sesuatu yang harus ditingkatkan oleh IDE.
Itay Moav -Malimovka

1
@ ItayMoav-Malimovka, yah ... dalam kasus JOOQ, jika saya mengubah sesuatu dalam struktur DB saya, kode saya hanya akan berhenti mengkompilasi sampai saya memperbaikinya sesuai dengan struktur DB yang baru. Jika Anda memiliki pertanyaan sebagai teks, mereka akan meninggalkan rusak.
Vladislav Rastrusny

Sebagai contoh: Saat ini saya sedang mengerjakan aplikasi yang perlu membuat pernyataan untuk bekerja pada database warisan yang sangat besar. Banyak pernyataan yang memiliki batasan khusus yang kami buat dengan SQL DSL. Berkat itu kita dapat dengan mudah membuat pernyataan yang tidak diketahui pada waktu kompilasi.
Rafael Winterhalter

Jawaban:


54

Querydsl dan jOOQ adalah dua pilihan populer.


6
JOOQ mungkin merupakan pilihan yang lebih baik untuk pengembangan SQL hardcore, tetapi Querydsl memiliki API yang lebih sederhana dan juga mendukung backend lain (JPA, JDO, Lucene, Mongodb, dll.); Saya juga berada di perusahaan di belakang Querydsl
Timo Westkämper

Kami menggunakan Querydsl SQL dalam beberapa proyek internal kami. Saya tidak memiliki pengalaman pribadi tentang jooq tetapi saya telah mendengar bahwa itu cukup baik.
ponzao

11
Masalah dengan QueryDsl adalah Anda tidak dapat menggunakannya sebagai generator kueri murni karena tidak memberi Anda kueri yang dihasilkan itu sendiri. Ini akan menghasilkan kueri dan menjalankannya untuk Anda juga. Anda tidak bisa mendapatkannya tanpa yang lain.
Abhinav Sarkar

5
Querydsl dan jOOQ tampaknya merupakan pilihan yang paling populer dan matang, namun ada satu hal yang harus diperhatikan: Keduanya bergantung pada konsep pembuatan kode, di mana kelas meta dibuat untuk tabel dan bidang database. Ini memfasilitasi DSL yang bagus dan bersih tetapi menghadapi masalah saat mencoba membuat kueri untuk database yang hanya dikenal saat runtime, seperti dalam contoh OP di atas. Sementara jOOQ mendukung pendekatan berbasis String, ada beberapa kebiasaan. Dokumentasi Querydsl tidak menyebutkan apakah mungkin untuk tidak menggunakan pembuatan kode. Harap perbaiki saya jika saya salah.
Sven Jacobs

3
@SvenJacobs komentar yang sangat lama, tetapi untuk memperbarui, QueryDSL mengizinkan pembangunan sql tanpa pembuatan kode: stackoverflow.com/questions/21615956/…
Nagaraj Tantri

7

ddlutils adalah pilihan terbaik saya: http://db.apache.org/ddlutils/api/org/apache/ddlutils/platform/SqlBuilder.html

berikut ini buat contoh (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

1
Saya harus mendefinisikan kolom lagi meskipun saya sudah mendefinisikannya di @Entity, sangat menyakitkan.
huuthang

6

Saya dapat merekomendasikan jOOQ . Ini menyediakan banyak fitur hebat, juga DSL intuitif untuk SQL dan pendekatan rekayasa terbalik yang sangat dapat disesuaikan.

jOOQ secara efektif menggabungkan SQL kompleks, keamanan jenis, pembuatan kode sumber, rekaman aktif, prosedur tersimpan, tipe data tingkat lanjut, dan Java dalam DSL yang lancar dan intuitif.


Apakah Anda menggunakannya? Bagaimana Anda menemukannya?
Vladislav Rastrusny

3
Saya menggunakannya untuk menghasilkan kode sumber khusus dari DDL. Ini bekerja dengan baik!
Christopher Klewes

"Meskipun pustaka jOOQ memiliki API yang bagus untuk membuat pernyataan SQL, ia hadir dengan seluruh rangkaian alat untuk membuat pernyataan, menghubungkan ke database, menulis / membaca model ke / dari database, dll. Karena sifat VM aplikasi Android saat ini , ada batas referensi metode 64k. jOOQ dapat berisi lebih dari 10.000 metode referensi saat digunakan. Ini mungkin tidak terlihat banyak dibandingkan dengan batas tersebut, tetapi jika Anda mempertimbangkan pustaka besar lainnya yang biasa digunakan (seperti Jambu dan Layanan Google Play) , mencapai batas 64 ribu itu menjadi jauh lebih mudah. ​​" - android-arsenal.com/details/1/3202 :(
Tomáš Fejfar

3

Hibernate Criteria API (bukan SQL biasa, tetapi sangat kuat dan dalam pengembangan aktif):

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
Masalahnya adalah itu tidak memetakan ke SQL seperti yang saya mengerti, bukan?
Vladislav Rastrusny

7
ini tidak menghasilkan SQL dan merupakan mimpi buruk untuk di-debug ketika tidak mengikuti aturan yang paling tidak mengherankan (tidak berfungsi seperti yang diharapkan)

Itu menghasilkan SQL (pada akhirnya) dan tidak mengejutkan siapa pun. Manfaat - portabel di seluruh database.
Vladimir Dyuzhev

3
Berapa tingkat kerumitan kueri yang Anda capai dengan API Kriteria JPA, tanpa membuat kueri sama sekali tidak dapat dibaca? Apakah Anda memiliki contoh pemilihan bersarang di klausa IN/ EXISTS, atau penggabungan mandiri menggunakan alias untuk Saleentitas, dll? Saya penasaran
Lukas Eder

1
Komentar tidak memberikan banyak ruang untuk memberikan contoh, tetapi Anda dipersilakan untuk memeriksanya di docs.jboss.org/hibernate/core/3.5/reference/en/html/…
Vladimir Dyuzhev

0

Anda dapat menggunakan pustaka berikut:

https://github.com/pnowy/NativeCriteria

Pustaka dibangun di atas Hibernate "create sql query" sehingga mendukung semua database yang didukung oleh Hibernate (sesi Hibernate dan penyedia JPA didukung). Pola pembangun tersedia dan seterusnya (pembuat peta objek, pembuat peta hasil).

Anda dapat menemukan contohnya di halaman github, perpustakaan tersedia di pusat Maven tentunya.

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

ini lebih rumit dari sekedar menulis SQL dengan tangan
EpicPandaForce

@EpicPandaForce Saya setuju untuk kasus yang sangat sederhana tetapi penggabungannya jauh lebih rumit saat Anda perlu menggabungkan string tersebut berdasarkan kondisi yang sangat rumit di mana terdapat kumpulan ketentuan yang berbeda. String yang digabungkan dengan benar (seperti semua penambahan, gabungan, memiliki, set parameter, dll.) Sangat merepotkan. Dengan solusi tersebut Anda memiliki pembangun yang akan menangani kerumitan ini untuk Anda.
Przemek Nowak
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.