Esiste una buona libreria di SQL Builder dinamico in Java? [chiuso]


108

Qualcuno conosce qualche buona libreria di SQL builder per Java come Squiggle (non più mantenuta a quanto pare). Preferibilmente, un progetto in sviluppo attivo.

Preferibilmente con una sintassi come Zend_Db_Select , qualcosa che consentirà di fare una query come

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

Posso chiedere qual è il vantaggio della sintassi precedente rispetto a "SELECT f1..fn FROM products ORDER BY product_id"?
Itay Moav -Malimovka

4
@ ItayMoav-Malimovka, Beh, almeno la sintassi della query SQL nel mio caso (se prendiamo JOOQ come esempio) viene controllata al momento della scrittura del codice. Hai il completamento automatico della sintassi completa che accelera la scrittura delle query e la rende più soggetta a errori.
Vladislav Rastrusny

Sono d'accordo che questo è qualcosa su cui gli IDE dovrebbero migliorare.
Itay Moav -Malimovka

1
@ ItayMoav-Malimovka, beh ... nel caso di JOOQ, se cambio qualcosa nella mia struttura DB, il mio codice smetterà di compilarsi fino a quando non lo aggiusterò secondo la nuova struttura DB. Se hai domande come testo, non funzioneranno.
Vladislav Rastrusny

Ad esempio: attualmente sto lavorando su un'applicazione che deve creare istruzioni per lavorare su un enorme database legacy. Molte istruzioni condividono vincoli personalizzati che creiamo da un DSL SQL. Grazie a ciò possiamo facilmente creare istruzioni che non sono note in fase di compilazione.
Rafael Winterhalter

Risposte:


53

Querydsl e jOOQ sono due scelte popolari.


6
JOOQ è forse una scelta migliore per lo sviluppo SQL hardcore, ma Querydsl ha un'API più semplice e supporta anche altri backend (JPA, JDO, Lucene, Mongodb ecc.); Sono anche nella compagnia dietro Querydsl
Timo Westkämper

Usiamo Querydsl SQL in alcuni dei nostri progetti interni. Non ho esperienza personale di jooq ma ho sentito che è abbastanza ok.
ponzao

11
Il problema con QueryDsl è che non puoi usarlo come puro generatore di query in quanto non ti fornisce la query generata stessa. Genererà la query e la eseguirà anche per te. Non puoi averne uno senza un altro.
Abhinav Sarkar

5
Querydsl e jOOQ sembrano essere le scelte più popolari e mature, tuttavia c'è una cosa di cui essere consapevoli: entrambi si basano sul concetto di generazione di codice, in cui vengono generate meta classi per tabelle e campi di database. Ciò facilita un DSL piacevole e pulito, ma deve affrontare un problema quando si tenta di creare query per database noti solo in fase di esecuzione, come nell'esempio dell'OP sopra. Sebbene jOOQ supporti un approccio basato su String, ci sono alcune stranezze. La documentazione di Querydsl non menziona se è possibile non utilizzare la generazione di codice. Per favore correggimi se sbaglio.
Sven Jacobs

3
@SvenJacobs molto vecchio commento, ma per l'aggiornamento, QueryDSL non permette la costruzione di SQL senza la generazione di codice: stackoverflow.com/questions/21615956/...
Nagaraj Tantri

7

ddlutils è la mia scelta migliore: http://db.apache.org/ddlutils/api/org/apache/ddlutils/platform/SqlBuilder.html

ecco un esempio di creazione (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
Devo definire di nuovo le colonne anche se le ho già definite in @Entity, quindi dolore.
Huuthang

6

Posso consigliare jOOQ . Fornisce molte fantastiche funzionalità, anche un DSL intuitivo per SQL e un approccio di reverse engineering estremamente personalizzabile.

jOOQ combina efficacemente SQL complesso, sicurezza dei tipi, generazione di codice sorgente, record attivi, procedure memorizzate, tipi di dati avanzati e Java in un DSL fluido e intuitivo.


Lo usi? Come lo trovi?
Vladislav Rastrusny

3
Lo uso per generare codice sorgente personalizzato da DDL. Funziona alla grande!
Christopher Klewes

"Sebbene la libreria jOOQ abbia un'ottima API per la creazione di istruzioni SQL, viene fornita con un'intera suite di strumenti per creare istruzioni, connettersi a database, scrivere / leggere modelli a / da database, ecc. A causa della natura attuale delle VM dell'applicazione Androids , esiste un limite di riferimento del metodo di 64k. jOOQ può contenere oltre 10.000 metodi di riferimento quando è in uso. Potrebbe non sembrare molto rispetto al limite, ma se si considerano altre librerie di grandi dimensioni comunemente usate (come Guava e Google Play Services) , raggiungere quel limite di 64k diventa molto più facile. " - android-arsenal.com/details/1/3202 :(
Tomáš Fejfar

3

Hibernate Criteria API (non semplice SQL, ma molto potente e in fase di sviluppo attivo):

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
Il problema è che non si associa a SQL come ho capito, giusto?
Vladislav Rastrusny

7
questo non genera SQL ed è un incubo per il debug quando non segue la regola del minimo stupore (non funziona come previsto)

Genera SQL (alla fine) e non sorprende nessuno. Vantaggio: è portabile tra database.
Vladimir Dyuzhev

3
Qual è il livello di complessità della query che hai raggiunto per raggiungere con l'API dei criteri JPA, senza rendere la query del tutto illeggibile? Hai un esempio di una selezione nidificata in una clausola IN/ EXISTSo di un auto-join che utilizza alias per l' Saleentità, ecc.? Sono curioso
Lukas Eder

1
I commenti non danno molto spazio per fornire gli esempi, ma puoi esaminarli su docs.jboss.org/hibernate/core/3.5/reference/en/html/…
Vladimir Dyuzhev

0

Puoi usare la seguente libreria:

https://github.com/pnowy/NativeCriteria

La libreria è costruita sulla parte superiore della "crea query sql" di Hibernate, quindi supporta tutti i database supportati da Hibernate (la sessione Hibernate e i provider JPA sono supportati). Lo schema del builder è disponibile e così via (mappatori di oggetti, mappatori di risultati).

Puoi trovare gli esempi sulla pagina github, la libreria è ovviamente disponibile presso Maven central.

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

questo è più complicato della semplice scrittura manuale
dell'SQL

@EpicPandaForce Sono d'accordo per casi molto semplici ma la concatenazione è molto complicata quando è necessario concatenare quella stringa in base a condizioni molto complicate in cui esiste un diverso insieme di queste condizioni. La stringa correttamente concatenata quindi (come tutte le aggiunte, i join, gli aver, i parametri impostati, ecc.) È un dolore. Con la soluzione hai un costruttore che si occuperà di questa complessità per te.
Przemek Nowak
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.