Quali sono i vantaggi dell’utilizzo di un ORM?

Come sviluppatore web che cerca di passare da siti PHP codificati a mano a siti basati su framework, ho visto molte discussioni sui vantaggi di un ORM rispetto a un altro. Sembra essere utile per progetti di una certa (?) Dimensione, e ancora più importante per le applicazioni di livello enterprise.

Cosa mi dà come sviluppatore? In che modo il mio codice differirà dalle singole istruzioni SELECT che uso ora? Come aiuterà l’accesso e la sicurezza del DB? Come viene informato sullo schema del DB e sulle credenziali dell’utente?

Modifica: @duffymo ha sottolineato cosa dovrebbe essere ovvio per me: ORM è utile solo per il codice OOP. Il mio codice non è OO, quindi non ho incontrato i problemi risolti da ORM.

Direi che se non hai a che fare con gli oggetti non ha molto senso usare un ORM.

Se le tue tabelle / colonne relazionali mappano 1: 1 con oggetti / attributi, non ha molto senso usare un ORM.

Se i tuoi oggetti non hanno alcuna relazione 1: 1, 1: mom: n con altri oggetti, non ha molto senso usare un ORM.

Se si dispone di SQL complesso, sintonizzato a mano, non è molto importante utilizzare un ORM.

Se hai deciso che il tuo database avrà le stored procedure come interfaccia, non ha molto senso usare un ORM.

Se si dispone di uno schema legacy complesso che non può essere refactored, non c’è molto senso nell’utilizzo di un ORM.

Quindi ecco il contrario:

Se si dispone di un modello di object solido, con relazioni tra gli oggetti 1: 1, 1: m e m: n, non si dispone di stored procedure e, come l’SQL dinamico che una soluzione ORM fornisce, con tutti i mezzi usa un ORM.

Decisioni come queste sono sempre una scelta. Scegli, implementa, misura, valuta.

Gli ORM vengono proposti per essere la soluzione ai problemi di accesso ai dati. Personalmente, dopo averli utilizzati in un Enterprise Project, sono ben lungi dall’essere la soluzione per lo sviluppo di applicazioni aziendali. Forse lavorano in piccoli progetti. Ecco i problemi che abbiamo riscontrato con loro specificamente nibernate:

  1. Configurazione: le tecnologie ORM richiedono file di configurazione per mappare schemi di tabelle in strutture di oggetti. Nei sistemi aziendali di grandi dimensioni, la configurazione cresce molto rapidamente e diventa estremamente difficile da creare e gestire. Anche il mantenimento della configurazione diventa noioso e non gestibile in quanto i requisiti e i modelli aziendali cambiano e si evolvono costantemente in un ambiente agile.

  2. Query personalizzate: la possibilità di mappare query personalizzate che non rientrano in alcun object definito non è supportata o non è raccomandata dai fornitori di framework. Gli sviluppatori sono costretti a trovare soluzioni alternative scrivendo oggetti e query ad hoc o scrivendo codice personalizzato per ottenere i dati di cui hanno bisogno. Potrebbe essere necessario utilizzare stored procedure su base regolare per qualcosa di più complesso di una semplice selezione.

  3. Binding di proprietà: questi framework richiedono l’uso di librerie proprietarie e linguaggi di query di oggetti proprietari che non sono standardizzati nell’industria informatica. Queste librerie e linguaggi di query proprietari legano l’applicazione all’implementazione specifica del provider con poca o nessuna flessibilità di modifica, se necessario, e l’assenza di interoperabilità per collaborare tra loro.

  4. Lingue di interrogazione degli oggetti: sono disponibili nuovi linguaggi di query denominati query di oggetti per eseguire query sul modello di oggetti. Generano automaticamente query SQL contro il database e l’utente viene estratto dal processo. Agli sviluppatori orientati agli oggetti questo può sembrare un vantaggio poiché ritengono che il problema della scrittura di SQL sia risolto. Il problema nella praticità è che questi linguaggi di query non supportano alcuni dei costrutti SQL da intermedio ad avanzato richiesti dalla maggior parte delle applicazioni del mondo reale. Inoltre, impediscono agli sviluppatori di modificare le query SQL se necessario.

  5. Prestazioni: i livelli ORM utilizzano la riflessione e l’introspezione per creare un’istanza e popolare gli oggetti con i dati del database. Si tratta di operazioni costose in termini di elaborazione e di aumento delle prestazioni delle operazioni di mapping. Le query object che vengono tradotte per produrre query non ottimizzate senza la possibilità di regolarle causando perdite di prestazioni significative e sovraccarico dei sistemi di gestione del database. La regolazione delle prestazioni dell’SQL è quasi imansible poiché i framework forniscono poca flessibilità rispetto al controllo dell’SQL che viene generato automaticamente.

  6. Accoppiamento stretto: questo approccio crea una stretta dipendenza tra gli oggetti del modello e gli schemi del database. Gli sviluppatori non vogliono una correlazione uno a uno tra i campi del database e i campi delle classi. La modifica dello schema del database ha effetti di increspatura nel modello di oggetti e nella configurazione di mapping e viceversa.

  7. Cache: questo approccio richiede anche l’uso di cache di oggetti e di contesti che sono necessari per maintian e tracciare lo stato dell’object e ridurre i roundtrip del database per i dati memorizzati nella cache. Queste cache, se non mantenute e sincronizzate in un’implementazione a più livelli, possono avere conseguenze significative in termini di accuratezza dei dati e concorrenza. Spesso è necessario colbind cache di terze parti o cache esterne per risolvere questo problema, aggiungendo un notevole carico al livello di accesso ai dati.

Per ulteriori informazioni sulla nostra analisi è ansible leggere: http://www.orasissoftware.com/driver.aspx?topic=whitepaper

Ad un livello molto alto: gli ORM aiutano a ridurre il disadattamento di impedenza Oggetto-Relazionale. Consentono di archiviare e recuperare oggetti live completi da un database relazionale senza eseguire personalmente parsing / serializzazione.

Cosa mi dà come sviluppatore?

Per i principianti ti aiuta a rimanere ASCIUTTO. Sia lo schema che le classi del modello sono autorevoli e l’altro viene generato automaticamente che riduce il numero di errori e la quantità di codice della piastra della caldaia.

Aiuta con il marshalling. Gli ORM generalmente gestiscono il marshalling dei valori delle singole colonne nei tipi appropriati in modo da non dover analizzare / serializzare da soli. Inoltre, ti permette di recuperare oggetti completamente formati dal DB piuttosto che semplicemente oggetti riga che devi avvolgere.

In che modo il mio codice differirà dalle singole istruzioni SELECT che uso ora?

Poiché le query restituiranno oggetti anziché solo righe, sarà ansible accedere agli oggetti correlati utilizzando l’accesso agli attributi anziché creare una nuova query. Generalmente si è in grado di scrivere direttamente SQL quando è necessario, ma per la maggior parte delle operazioni (CRUD) l’ORM renderà più semplice il codice per interagire con gli oggetti persistenti.

Come aiuterà l’accesso e la sicurezza del DB?

In generale, gli ORM dispongono di una propria API per la creazione di query (ad esempio l’accesso agli attributi) e quindi sono meno vulnerabili agli attacchi di SQL injection; tuttavia, spesso ti permettono di iniettare il tuo SQL nelle query generate in modo che tu possa fare cose strane se necessario. Tale SQL iniettato è responsabile per la sanificazione di te stesso, ma, se non stai utilizzando queste funzionalità, l’ORM dovrebbe occuparsi di disinfettare automaticamente i dati dell’utente.

Come viene informato sullo schema del DB e sulle credenziali dell’utente?

Molti ORM sono dotati di strumenti che controllano uno schema e creano un insieme di classi di modelli che consentono di interagire con gli oggetti nel database. [Database] le credenziali dell’utente sono generalmente memorizzate in un file di impostazioni.

Se si scrive a mano il proprio livello di accesso ai dati, si sta essenzialmente scrivendo il proprio ORM scadente.

Oren Eini ha un bel blog che riassume le caratteristiche essenziali di cui potresti avere bisogno nel tuo DAL / ORM e perché scrivere una tua idea diventa una ctriggers idea dopo il tempo: http://ayende.com/Blog/archive/2006/05/12 /25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspx

EDIT: l’OP ha commentato in altre risposte che il suo codice base non è molto orientato agli oggetti. Gestire la mapping degli oggetti è solo un aspetto degli ORM. Il pattern Active Record è un buon esempio di come gli ORM siano ancora utili in scenari in cui gli oggetti mappano 1: 1 alle tabelle.

Non posso parlare per altri ORM, solo Hibernate (per Java).

Hibernate mi dà il seguente:

  • Aggiorna automaticamente lo schema per le tabelle sul sistema di produzione in fase di esecuzione. A volte devi ancora aggiornare manualmente alcune cose.
  • Crea automaticamente chiavi esterne che ti impediscono di scrivere codice errato che sta creando dati orfani.
  • Implementa il pooling delle connessioni. Sono disponibili più provider di pool di connessioni.
  • Memorizza i dati nella cache per un accesso più rapido. Sono disponibili più provider di memorizzazione nella cache. Ciò consente anche di raggruppare insieme molti server per aiutarti a scalare.
  • Rende l’accesso al database più trasparente in modo da poter facilmente trasferire l’applicazione su un altro database.
  • Rende le query più facili da scrivere. La seguente query che normalmente richiede di scrivere ‘join’ tre volte può essere scritta in questo modo:
    • “da Invoice i dove i.customer.address.city =?” questo recupera tutte le fatture con una città specifica
    • viene restituito un elenco di oggetti della fattura. Posso quindi chiamare invoice.getCustomer (). GetCompanyName (); se i dati non sono già nella cache, il database viene interrogato automaticamente in background

È ansible decodificare un database per creare lo schema di ibernazione (non averlo provato personalmente) oppure è ansible creare lo schema da zero.

C’è ovviamente una curva di apprendimento come con qualsiasi nuova tecnologia, ma penso che ne valga la pena.

Se necessario, è ancora ansible passare al livello SQL inferiore per scrivere una query ottimizzata.

Vantaggi principali:

  1. Database Abstraction
  2. Mentalità progettuale API-centrica
  3. Alto livello == Meno di cui preoccuparsi al livello fondamentale (è stato pensato per te)

Devo dire che lavorare con un ORM è davvero l’evoluzione delle applicazioni basate su database. Ti preoccupi meno del codice SQL che scrivi sempre e più su come le interfacce possono lavorare insieme per creare un sistema molto semplice.

Mi piace non dover preoccuparsi di INNER JOIN e SELECT COUNT (*). Lavoro solo nella mia astrazione di alto livello e allo stesso tempo mi sono occupato dell’astrazione del database.

Detto questo, non mi sono mai imbattuto in un problema in cui avevo bisogno di eseguire lo stesso codice su più di un sistema di database alla volta realisticamente. Tuttavia, questo non vuol dire che il caso non esista, è un problema molto reale per alcuni sviluppatori.

La maggior parte dei database utilizzati sono database relazionali che non si traducono direttamente in oggetti. Ciò che fa un Object-Relational Mapper è prendere i dati, creare una shell attorno ad esso con funzioni di utilità per l’aggiornamento, la rimozione, l’inserimento e altre operazioni che possono essere eseguite. Quindi, invece di considerarlo come una serie di righe, ora hai una lista di oggetti che puoi manipolare come faresti con qualsiasi altro e semplicemente chiamare obj.Save () quando hai finito.

Ti suggerisco di dare un’occhiata ad alcuni degli ORM che sono in uso, uno dei miei preferiti è l’ORM usato nel framework python, django . L’idea è di scrivere una definizione di come i dati vengono visualizzati nel database e l’ORM si occupa della convalida, dei controlli e di eventuali meccanismi che devono essere eseguiti prima che i dati vengano inseriti.

Personalmente non ho avuto una grande esperienza con l’utilizzo della tecnologia ORM fino ad oggi. Attualmente sto lavorando per una società che utilizza l’ibernazione e non riesco davvero a farcela. Dammi un proc memorizzato e DAL ogni giorno! Più codice sicuro … ma anche più controllo e codice che è più facile eseguire il debug – dalla mia esperienza con l’uso di una versione precedente di nibernate deve essere aggiunto.

Cosa mi dà come sviluppatore?

Ti fa risparmiare tempo, dal momento che non devi codificare la porzione di accesso db.

In che modo il mio codice differirà dalle singole istruzioni SELECT che uso ora?

Utilizzerai gli attributi o i file xml per definire il mapping delle classi alle tabelle del database.

Come aiuterà l’accesso e la sicurezza del DB?

La maggior parte dei framework tenta di aderire alle best practice db ove applicabile, come SQL parametrizzato e simili. Poiché i dettagli dell’implementazione sono codificati nel framework, non devi preoccuparti di ciò. Per questo motivo, tuttavia, è anche importante capire il framework che si sta utilizzando ed essere a conoscenza di eventuali difetti di progettazione o bug che potrebbero aprire buchi imprevisti.

Come viene informato sullo schema del DB e sulle credenziali dell’utente?

Fornisci la stringa di connessione come sempre. I provider di framework (ad es. Classi specifiche SQL, Oracle, MySQL) forniscono l’implementazione che interroga lo schema db, elabora i mapping di class e esegue il rendering / esecuzione del codice di accesso db secondo necessità.

L’uso di un ORM rimuoverà le dipendenze dal codice su un particolare dialetto SQL. Invece di interagire direttamente con il database, interagirai con un livello di astrazione che fornisce isolamento tra il tuo codice e l’implementazione del database. Inoltre, gli ORM forniscono in genere protezione dall’iniezione SQL costruendo query parametrizzate. Certo, potresti farlo tu stesso, ma è bello avere la garanzia quadro.

Gli ORM funzionano in due modi: alcuni scoprono lo schema da un database esistente – il designer LINQToSQL lo fa -, altri richiedono di mappare la class su un tavolo. In entrambi i casi, una volta che lo schema è stato mappato, l’ORM potrebbe essere in grado di creare (ricreare) la struttura del database per te. Probabilmente le autorizzazioni DB devono ancora essere applicate a mano o tramite SQL personalizzato.

Tipicamente, le credenziali fornite in modo programmatico tramite l’API o utilizzando un file di configurazione – o entrambi, i valori predefiniti provenienti da un file di configurazione, ma in grado di essere sovrascrivibili nel codice.

Per un podcast che discute di ORM in dettaglio, vedi il seguente link. http://se-radio.net/podcast/2008-12/episode-121-or-mappers-michael-ploed

Mentre sono quasi completamente d’accordo con la risposta accettata, penso che possa essere modificato con alternative leggere in mente.

  • Se hai un SQL complesso, sintonizzato a mano
  • Se i tuoi oggetti non hanno alcuna relazione 1: 1, 1: mom: n con altri oggetti
  • Se si dispone di uno schema legacy complesso che non può essere refactored

… quindi si potrebbe trarre vantaggio da un ORM leggero in cui SQL non è oscurato o astratto al punto in cui è più facile scrivere la propria integrazione del database.

Questi sono alcuni dei molti motivi per cui il team di sviluppatori della mia azienda ha deciso che dovevamo realizzare un’astrazione più flessibile per risiedere sulla JDBC.

Ci sono molte alternative open source in giro che realizzano cose simili, e JORM è la nostra soluzione proposta.

Consiglierei di valutare alcuni dei candidati più forti prima di scegliere un ORM leggero. Sono leggermente diversi nel loro approccio ai database astratti, ma potrebbero sembrare simili da una vista dall’alto.

  • Jorm
  • ActiveJDBC
  • ORMLite

la mia preoccupazione per i framework ORM è probabilmente la cosa che lo rende attraente per molti sviluppatori.

nameley che ovvia alla necessità di “preoccuparsi” di ciò che sta accadendo a livello di DB. La maggior parte dei problemi che vediamo durante l’esecuzione quotidiana delle nostre app sono legati ai problemi del database. Mi preoccupo un po ‘di un mondo che è al 100% ORM che le persone non sapranno su quali query stanno colpendo il database, o se lo fanno, non sono sicuri su come cambiarle o ottimizzarle.

{Mi rendo conto che questa potrebbe essere una risposta contrariata :)}