iBatis Switch zwischen MS SQL und Oracle?

JayGabriel

Aktives Mitglied
Hallo, an alle :)

Ich steh mal wieder vor einem Problem, welches ich nicht ohne einen hilfreichen Stups von euch gelöst bekomme.

Die Datenbanken, auf die über meinen WS zugegriffen werden sollen (mittels MyBatis), sind nicht immer nur MS SQL DBs oder nur Oracle DBs. So kann ich mich nicht auf eine Implementierung festlegen.
Daher würde ich gern wissen, wie man solch ein Problem am besten löst ohne doppelte DB Statements schreiben zu müssen.

Ich hab mir gedacht, dass ich in irgendeiner *properties eine Konfiguration anlege, die angibt, welcher Typ von DB grad verwendet wird und die dann je Projekt gesetzt werden muss. Doch das bringt mich ja bei meinem eigentlichen Problem keinen Schritt weiter.

Oracle und MS SQL Befehle unterschieden sich ja in mehreren Dingen und vorallem in den Stored Procedures und Funktionaufrufen und auch in Date bzw. Datetime. Wie kann ich die Funktionalität erreichen, ohne für jeden DB Aufruf extra Einträge zu erstellen. Oder komm ich da nicht drumherum für jeden einzelnen DB Aufruf ein entsprechend konformes SQL Statement je nach DB Art zu erstellen und im Java Code dann zu entscheiden, welche der Aufrufe nun benutzt werden soll? Wär ja schon doof, weil so doppelter Code gepflegt werden müsste...

Eine Idee war:
"nutzername#.package#.storedProcedure" zu schreiben, die dann je nach Konfiguration entweder alles zwischen #..# wegnimmt (bei MS SQL) oder nur die einzelnen # löscht.
Ist das überhaupt möglich?

Ich bin für Tips jeglicher Art dankbar!
mfg
Jay
 

JayGabriel

Aktives Mitglied
Hallo maki,

danke für deine schnelle Antwort!
Leider hört sie sich nicht gerade sehr aufbauend an. Codedopplung wollte ich eigentlich vermeiden. :(
Vielleicht stoße ich ja noch auf eine Möglichkeit, aber um vorwerts zu kommen, werde ich die DB Statements wohl erst einmal seperat schreiben.

mfg
Jay
 

turtle

Top Contributor
Darum, eventuell doppelte SQL-Statements zu schreiben, wirst Du meiner Meinung nach herum kommen.

Das hat aber auch Vorteile. Einerseits kannst Du ganz spezifisch Besonderheiten der bestimmten DB ausnutzen, indem Du DB-Spezifika ausnutzt. Andererseits sind die SQL Befehle klar von einander getrennt und Du bist Dir sicher, dass in einer anderen DB nicht ein falsches/wenig optimiertes SQL benutzt wird.

Im übrigen sollte man sich auf SQL-Standard (z.B. SQL-92) beschränken. Nun erkennst Du auch, warum einige Dinge, die in JDBC möglich sind, von Puristen ungerne gesehen werden, weil halt die Platformunabhängigkeit auf der Strecke bleibt (weil nicht portabel), z.B. stored procedures. Dein Beispiel mit Datetime sollte da nicht betroffen sein, weil Du das in myBATIS auf ein Date-Objekt abbildest und dann die Arbeit der JDBC-Treiber übernimmt.
 

JayGabriel

Aktives Mitglied
Hallo turtle,

danke auch dir für deine Antwort!

Darum, eventuell doppelte SQL-Statements zu schreiben, wirst Du meiner Meinung nach herum kommen.
Hast du hier das "nicht" vergessen? ;) Würde zumindest mehr Sinn machen, mit deinen folgenden Worten.

Das hat aber auch Vorteile. [...]
Okay, da stimme ich dir zu. Vom Aufbau der Tabellen her unterscheiden sich die DBs aber wohl nicht weiter, wie mir mitgeteilt wurde. Einziger Unterschied: die eine DB ist MS SQL, eine andere Oracle...
Und da hatte ich gehofft, dass man das mit Markern oder Makros oder irgendetwas anpassen kann.
Bei Tabellenfelderunterschieden ist mir jedoch klar, dass ich nicht umhin komme, andere SQL Statements zu benutzen.

Im übrigen sollte man sich auf SQL-Standard (z.B. SQL-92) beschränken.
Erscheint mir auch sinnvoll und normal sind meine Statements auch alle ohne Probleme portierbar. Probleme gibt es eben mit den Prozeduren unf Funktionen, wo ich mich leider aber nicht drumherumdrücken kann. Die müssen verwendet werden (ist so vorgegeben) und um ehrlich zu sein, ich möchte diese Funktionen auch nicht nachprogrammieren, da in diesen schon viiiel Hirnschmalz von anderen drin steckt. Und Nachporgrammierung würde auch wieder das "Code Dopplung" Problem aufwerfen.

Dein Beispiel mit Datetime sollte da nicht betroffen sein, [...]
Das DATE/DATETIME Problem kommt bei mir in einer Abfrage von einer "stored Function" (heißen diese so?) vor.

Code:
DECLARE
  @dtResult DATETIME;
BEGIN
  SET @dtResult = getdate();
  SET @dtResult = sf_hierDieFunktion(#{id});
	
  SELECT @dtResult AS RESULT;
END;

Da ich leider nicht viel mit SQL am Hut habe, habe ich es gerade mal einfach mit
Code:
SELECT sf_hierDieFunktion(#{id});
ausprobiert und siehe da, es funktioniert. ;) Gut, das eine Problem ist nun in dem Fall beseitigt.

Nach langwierigen Erklärungen von dem, der mir bei SQL Fragen hilft, bin ich aber immerhin darauf gekommen, in welchem Fall es unumgänglich ist, den Rückgabewert in einer Variabelen zu speichern (wenn in der Funktion eine Veränderung von Daten vorgenommen wird).
Ist jedoch nicht der Fall bei den zu benutzenden Funktionen. Also: dieses Problem ist beseitigt!


Bleiben nur die Probleme der anderen Schreibweise für Aufrufe von Funktionen und Prozeduren, die also seperat eingefügt werden müssen.

mfg
Jay
 

turtle

Top Contributor
Natürlich habe ich mich da verschrieben;)

Prozeduren in JDBC nennt man häufig stored procedures, da diese in der Datenbank gespeichert sind.

Mit myBATIS rufst Du derartige Prozeduren wie im Beispiel auf:

[XML]<select id="callGetTotalCity" parameterType="Param" statementType="CALLABLE">
{ CALL getTotalCity(#{total, mode=OUT, jdbcType=INTEGER})}
</select>[/XML]
Und Du kannst Parameter, wie bei praktisch allen Methoden, über einen Parameter-Type definieren. Im Beispiel nur ein Integer Wert der Rückgabewert.

Da ich stored procedures (aus genannten Grüden) nicht einsetze, ich aber weiss, dass bei vielen Kunden die "ganze" Business-Logik in derartigen Prozeduren "gekapselt" wird, bleibt der Aufruf von Java (myBATIS), der kein Problem verursacht.

Und wie bereits erwähnt, macht die Trennung von DB-Spezifika in getrennte XML Mapperdateien Sinn.
 

JayGabriel

Aktives Mitglied
Hallo turtle,

danke, für deine Antwort! :)

Das mit den seperaten XML Mappern werde ich mir zu Herzen nehmen! Lässt sich das ja so auch alles deutlich übersichtlicher gestalten.

Wie im allgemeinen eine Prozedur aufgerufen wird, ist mir klar, da ich solche schon länger (zumindest in MS SQL) benutze.

Jetzt weiß ich aber auch, dass das Package, in dem die Funktionen gespeichert sind, bei Oracle mit angegeben werden muss. Also:

Code:
SELECT user.Package.sf_myFunction(#{param1}, #{param2}) FROM DUAL;

Muss dieses Package dann auch bei der Prozedur so angegeben werden?

Code:
{ CALL user.Package.sp_myProcedure(#{param1, jdbcType=INTEGER,mode=OUT})}

Mfg,
Jay
 

Ähnliche Java Themen


Oben