Perché non avrei bisogno di un ORM in un linguaggio funzionale come Scala?

29

Mi chiedo se posso passare da Java a Scala in un progetto Spring + Hibernate per trarre vantaggio da alcune funzioni di Scala come la corrispondenza dei pattern, Opzione e ciò che mi sembra una sintassi più pulita in generale. Ho cercato l'ORM di default nell'ecosistema Scala e ho trovato che pensa come Activate (ma soprattutto cerco di trovare se Hibernate può essere usato con Scala). Cercando questo ho letto questo in Play documentation su JPA + Scala.

But the most important point is: do you really need a Relationnal to Objects mapper when you have the power of a functional language? Probably not. JPA is a convenient way to abstract the Java’s lack of power in data transformation, but it really feels wrong when you start to use it from Scala.

Non ho una profonda conoscenza di come usare la programmazione funzionale per creare un'applicazione completa (è per questo che intendo usare Scala in modo da poterlo capire in modo incrementale, dal momento che combina OO + Functional), quindi posso ' t capire perché non avrei bisogno di un ORM con un linguaggio funzionale e quale sarebbe l'approccio funzionale per affrontare la persistenza del modello di dominio.

Un approccio DDD per la business logic ha ancora senso con Scala, vero?

    
posta gabrielgiussi 25.11.2015 - 13:10
fonte

4 risposte

30

Bene, una cosa che è importante fare ogni volta che facciamo una discussione come questa è distinguere chiaramente tra mappatori relazionali di oggetti ("ORM") e livelli di astrazione del database . Un ORM è un tipo di livello di astrazione del database, ma non tutti i livelli di astrazione del database sono ORM. Un buon strumento per studiare è la famosa libreria SQLAlchemy di Python, che si autofinanzia come "toolkit SQL e Object Relational Mapper "(my boldface), con l'idea che queste sono cose diverse. Mentre lo inseriscono nella loro pagina delle caratteristiche principali :

No ORM Required

SQLAlchemy consists of two distinct components, known as the Core and the ORM. The Core is itself a fully featured SQL abstraction toolkit, providing a smooth layer of abstraction over a wide variety of DBAPI implementations and behaviors, as well as a SQL Expression Language which allows expression of the SQL language via generative Python expressions. A schema representation system that can both emit DDL statements as well as introspect existing schemas, and a type system that allows any mapping of Python types to database types, rounds out the system. The Object Relational Mapper is then an optional package which builds upon the Core.

La prima pagina descrive l'ORM come questo:

SQLAlchemy is most famous for its object-relational mapper (ORM), an optional component that provides the data mapper pattern, where classes can be mapped to the database in open ended, multiple ways - allowing the object model and database schema to develop in a cleanly decoupled way from the beginning.

L'idea chiave di un ORM è provare a superare il famoso disadattamento dell'impedenza relazionale dell'oggetto . Ciò significa definire le relazioni tra classi definite dall'utente alle tabelle in uno schema di database e fornire operazioni di "salvataggio" e "caricamento" automatiche per le classi dell'applicazione.

Al contrario, i livelli di astrazione del database non-ORM tendono ad essere maggiormente dedicati al modello di dati relazionali e a SQL, e non all'orientamento agli oggetti. Quindi, invece di includere "mappature" tra tabelle e classi e nascondere lo schema del database dal programmatore, tendono a esporre il database al programmatore ma con migliori API e astrazioni. Ad esempio, i creatori di query SQL consentono di generare query SQL complesse a livello di codice, senza manipolazione delle stringhe, come questo ( un esempio dalla libreria jOOQ per Java ):

// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
    create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
          .from(BOOK)
          .join(AUTHOR)
          .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
          .where(BOOK.PUBLISHED_IN.equal(1948))
          .fetch();

Ora, il framework Play non sembra essere al 100% in lega con quello che ho appena descritto , ma la loro argomentazione sembra essere in questo spazio generale: lavorare direttamente con il modello relazionale invece di tradurlo in classi e ritornare da esse.

Vale la pena studiare la libreria jOOQ come contrappunto agli ORM. Hanno anche alcune voci di blog rilevanti che vale la pena leggere:

risposta data 26.11.2015 - 01:08
fonte
17

È un po 'difficile da spiegare finché non hai fatto un sacco di programmazione funzionale. Nella programmazione orientata agli oggetti, i tuoi dati sono bloccati in un oggetto e rimangono lì. Quell'oggetto viene passato un po 'indietro e modificato un po', ma di solito si lavora fondamentalmente con la stessa "identità" nel corso della vita di quei dati.

Gli ORM sono generalmente progettati attorno a quel paradigma. Recuperi alcuni dati dal database, li munge in un oggetto, potenzialmente lo modificano un po 'e quando hai finito, hai ancora lo stesso oggetto che puoi scrivere di nuovo nel database.

La programmazione funzionale funziona diversamente. I tuoi dati non mantengono un'unica identità nel corso della sua vita. Viene diviso, copiato, condiviso e trasformato. In un certo senso scorre attraverso un sacco di funzioni, quindi alla fine viene riassemblato nel modulo di output di cui hai bisogno. Affinché qualsiasi API di database sia naturale in un linguaggio funzionale, deve tenerne conto e JPA no.

    
risposta data 25.11.2015 - 21:52
fonte
8

In scala è comunque utile mappare le tabelle del database agli oggetti, e ci sono diversi modi per farlo.

Un framework popolare nel mondo di Scala è slick . Non è un ORM, perché fa meno (cioè, non recupera le relazioni senza che gli venga detto di fare esplicitamente join).

Quindi mappi ancora gli oggetti alle righe del database, ma i tuoi oggetti sono immutabili, quindi non eseguono il flushing dello stato e esegui esplicitamente query utilizzando un DSL monadico. Il risultato è che ottieni molte delle parti "buone" di un ORM senza i problemi relativi alla mutevolezza e ai problemi N + 1 imprevedibili.

Si noti che le persone hanno ottenuto un grande successo utilizzando librerie molto più sottili, come anorm o JDBC diretto, usando tecniche funzionali per mantieni il codice bello.

Una fantastica libreria che applica tecniche funzionali su JDBC è anche doobie .

Quindi hai molte scelte per l'accesso al database, ma Hibernate (che sembra essere l'ORM de facto) non è tra i migliori, essendo polarizzato verso la mutevolezza.

    
risposta data 26.11.2015 - 22:49
fonte
0

Non hai bisogno di un ORM anche in linguaggi orientati agli oggetti.

Innanzitutto, chi ha detto che i tuoi dati dovrebbero essere copiati fisicamente dalla tua memoria persistente al tuo oggetto? Alan Kay , un uomo dietro Smalltalk, voleva oggetti per sbarazzarsi dei dati . Ha suggerito che un oggetto può avere solo un riferimento ad un'area in cui sono memorizzati i suoi dati.

Secondo: qual è il modo migliore per riuscirci? Raccomando identificare i tuoi oggetti in base alle loro responsabilità e non pensare ai dati che possiedono . Se hai sentito parlare delle carte CRC, è usato esattamente per questo.

E, infine, nel caso in cui dovessi mai tornare al campo OO, ecco un modo per implementarlo .

    
risposta data 25.10.2017 - 18:10
fonte

Leggi altre domande sui tag