Warum brauche ich kein ORM in einer funktionalen Sprache wie Scala?

30

Ich frage mich, ob ich in einem Spring + Hibernate-Projekt von Java auf Scala umsteigen kann, um einige Scala-Funktionen wie Pattern Matching, Option und eine für mich allgemein sauberere Syntax zu nutzen. Ich habe im Scala-Ökosystem standardmäßig nach dem ORM gesucht und denke dabei an "Aktivieren" (aber meistens versuche ich herauszufinden, ob Hibernate mit Scala verwendet werden kann). Auf der Suche habe ich dies in der Play-Dokumentation zu JPA + Scala gelesen .

Der wichtigste Punkt ist jedoch: Brauchen Sie wirklich einen Relationnal to Objects-Mapper, wenn Sie die Macht einer funktionalen Sprache haben? Wahrscheinlich nicht. JPA ist eine bequeme Methode, um die mangelnde Leistungsfähigkeit von Java bei der Datentransformation zu verdeutlichen, aber es fühlt sich wirklich falsch an, wenn Sie es von Scala aus verwenden.

Ich verstehe nicht genau, wie man mit funktionaler Programmierung eine vollständige Anwendung erstellt (deshalb beabsichtige ich, Scala zu verwenden, um dies schrittweise zu verstehen, da es OO + Functional kombiniert), sodass ich es nicht herausfinden kann Warum brauche ich kein ORM mit einer funktionalen Sprache und was wäre der funktionale Ansatz, um die Persistenz des Domänenmodells in Angriff zu nehmen?

Ein DDD-Ansatz für die Geschäftslogik macht bei Scala immer noch Sinn, nicht wahr?

gabrielgiussi
quelle
3
Dies ist eine meinungsbasierte Frage. Scala ist nicht rein funktional, es ist auch eine OO-Sprache, weshalb Sie immer noch ein ORM-Tool verwenden möchten. Informationen zum DB-Mapping finden Sie beispielsweise unter: Slick , SORM , Anorm .
Jesper
Ich suche keine Meinung, ich frage etwas mit tiefem Verständnis des Funktionsparadigmas, wie Persistenz erreicht werden kann. Ich weiß, dass Scala ein Hybrid ist und ich möchte seinen OO-Teil für DDD verwenden. Sie sagen also, wenn ich selbst mit Scala einen DDD-Ansatz verfolge, ist ein ORM der richtige Weg?
Gabrielgiussi
In funktionalen Sprachen beschäftigen Sie sich hauptsächlich mit Werten, die keine Identität wie Objekte haben. Daher benötigen Sie keine Änderungsnachverfolgung, die eine der Hauptaufgaben eines ORM ist.
Lee
2
Dieser Vortrag könnte Ihnen gefallen: Von funktionalen zu reaktiven Mustern in der Domänenmodellierung
Jesper
5
Sie müssen nicht brauchen ein ORM in jeder wichtigen Sprache.
GroßmeisterB

Antworten:

30

Nun, eine Sache, die wichtig ist, wenn wir eine Diskussion wie diese haben, ist die klare Unterscheidung zwischen objektrelationalen Mappern ("ORM") und Datenbankabstraktionsebenen . Ein ORM ist eine Art Datenbankabstraktionsschicht, aber nicht alle Datenbankabstraktionsschichten sind ORMs. Ein gutes Werkzeug, um dies zu verstehen, ist die beliebte SQLAlchemy- Bibliothek von Python , die sich selbst als "SQL-Toolkit und objektrelationaler Mapper" (meine Fettschrift) mit der Idee ausgibt, dass dies verschiedene Dinge sind. Wie sie es auf ihrer Hauptmerkmalseite formulieren :

Kein ORM erforderlich

SQLAlchemy besteht aus zwei unterschiedlichen Komponenten, dem Core und dem ORM . Der Core selbst ist ein voll ausgestattetes SQL-Abstraktions-Toolkit, das eine reibungslose Abstraktionsebene für eine Vielzahl von DBAPI-Implementierungen und -Verhalten sowie eine SQL-Ausdruckssprache bietet, mit der die SQL-Sprache über generative Python-Ausdrücke ausgedrückt werden kann. Ein Schemadarstellungssystem, das sowohl DDL-Anweisungen ausgeben als auch vorhandene Schemata prüfen kann, und ein Typsystem, das die Zuordnung von Python-Typen zu Datenbanktypen ermöglicht, runden das System ab. Der Object Relational Mapper ist dann ein optionales Paket, das auf dem Core aufbaut.

Die Titelseite beschreibt den ORM folgendermaßen:

SQLAlchemy ist am bekanntesten für seinen objektrelationalen Mapper (ORM), eine optionale Komponente, die das Daten-Mapper-Muster bereitstellt, mit dem Klassen der Datenbank auf verschiedene Arten zugeordnet werden können, so dass sich das Objektmodell und das Datenbankschema in einer Weise entwickeln können Von Anfang an sauber entkoppelt.

Die Schlüsselidee eines ORM besteht darin, die berühmte Fehlanpassung der objektrelationalen Impedanz zu überbrücken . Dies bedeutet, dass Beziehungen zwischen benutzerdefinierten Klassen zu Tabellen in einem Datenbankschema definiert und automatische Vorgänge zum Speichern und Laden für die Klassen Ihrer Anwendung bereitgestellt werden.

Im Gegensatz dazu tendieren Nicht-ORM-Datenbankabstraktionsebenen eher zum relationalen Datenmodell und zu SQL und überhaupt nicht zur Objektorientierung. Anstatt also die „Zuordnungen“ zwischen Tabellen und Klassen und Ausblenden des Datenbankschemas von dem Programmierer, neigen sie zu entlarven , die Datenbank für den Programmierer aber mit besserer APIs und Abstraktionen. Mit SQL Query Buildern können Sie beispielsweise komplexe SQL-Abfragen programmgesteuert ohne Manipulation von Zeichenfolgen wie folgt generieren ( ein Beispiel aus der jOOQ-Bibliothek für 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();

Nun scheint das Play-Framework nicht zu 100% mit dem übereinzustimmen , was ich gerade beschrieben habe , aber ihr Argument scheint in diesem allgemeinen Raum zu liegen: Arbeiten Sie direkt mit dem relationalen Modell, anstatt es in Klassen und umgekehrt zu übersetzen.

Die jOOQ-Bibliothek ist als Kontrapunkt zu ORMs lohnenswert. Sie haben auch einige relevante Blog-Einträge, die es wert sind, gelesen zu werden:

Sacundim
quelle
19

Es ist schwer zu erklären, bis Sie eine Menge funktionale Programmierung gemacht haben. Bei der objektorientierten Programmierung bleiben Ihre Daten sozusagen in einem Objekt stecken und bleiben dort. Dieses Objekt wird ein wenig herumgereicht und einiges verändert, aber normalerweise arbeiten Sie während der gesamten Lebensdauer dieser Daten mit derselben "Identität".

ORMs basieren im Allgemeinen auf diesem Paradigma. Sie rufen einige Daten aus der Datenbank ab, fügen sie in ein Objekt ein, ändern sie möglicherweise ein paar Mal, und wenn Sie fertig sind, haben Sie immer noch dasselbe Objekt, das Sie in die Datenbank zurückschreiben können.

Die funktionale Programmierung funktioniert anders. Ihre Daten behalten während ihrer gesamten Lebensdauer keine einzige Identität. Es wird aufgeteilt, kopiert, geteilt und transformiert. Es fließt durch eine Reihe von Funktionen und wird schließlich wieder in die Ausgabeform zusammengesetzt, die Sie benötigen. Damit sich eine Datenbank-API in einer funktionalen Sprache natürlich anfühlt, muss dies berücksichtigt werden, und JPA nicht.

Karl Bielefeldt
quelle
1
+1000 Leute, die darauf bestehen, Scala wie Java ++ zu benutzen, machen mir Angst um die Zukunft der Sprache :(
Andres F.
9

In scala ist es immer noch nützlich, Datenbanktabellen Objekten zuzuordnen, und es gibt verschiedene Möglichkeiten, dies zu tun.

Ein beliebtes Framework in der Welt von Scala ist Slick . Es ist kein ORM, weil es weniger leistet (dh es ruft keine Beziehungen ab, ohne explizit dazu aufgefordert zu werden, Verknüpfungen auszuführen).

Sie ordnen Objekte weiterhin Datenbankzeilen zu, aber Ihre Objekte sind unveränderlich (daher kein State-Flush), und Sie führen Abfragen explizit mit einer monadischen DSL aus. Das Ergebnis ist, dass Sie viele der "guten" Teile eines ORM erhalten, ohne die Probleme in Bezug auf die Wandlungsfähigkeit und unvorhersehbare N + 1-Probleme.

Man sollte beachten, dass die Verwendung von viel dünneren Bibliotheken, wie Anorm oder JDBC, mit funktionalen Techniken, die den Code schön halten, große Erfolge erzielt hat .

Eine fantastische Bibliothek, die zusätzlich zu JDBC funktionale Techniken anwendet, ist auch doobie .

Sie haben also eine Menge Auswahlmöglichkeiten für den Datenbankzugriff, aber Hibernate (scheinbar der De-facto-ORM) ist nicht der beste, da er auf Veränderlichkeit ausgerichtet ist.

triggerNZ
quelle
0

Sie benötigen kein ORM, auch nicht in objektorientierten Sprachen.

Erstens, wer hat gesagt, dass Ihre Daten physisch aus Ihrem dauerhaften Speicher in Ihr Objekt kopiert werden sollen? Alan Kay , ein Mann hinter Smalltalk, wollte, dass Objekte Daten loswerden . Er schlug vor, dass ein Objekt nur einen Verweis auf einen Bereich haben kann, in dem seine Daten gespeichert sind.

Zweitens - wie kann man das am besten erreichen? Ich empfehle , Ihre Objekte anhand ihrer Verantwortlichkeiten zu identifizieren und nicht an die Daten zu denken, die sie besitzen. Wenn Sie von CRC-Karten gehört haben, wird sie genau dafür verwendet.

Und für den Fall, dass Sie jemals wieder zu OO-field zurückkehren, finden Sie hier eine Möglichkeit, dies umzusetzen .

Zapadlo
quelle