Ein paar Fragen zur DB-Programmierung

Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hallo!

Ich bin noch nicht sehr erfahren in der DB-Programmierung und habe deshalb ein paar Fragen zur dazu:

(1) Ich habe mal gehört, dass PreparedStatements Vorteile gegenüber Statements haben, wenn man bestimmte Sonderzeichen in den zu speichernden/lesenden Daten hat. Stimmt das und warum ist das so?

(2) Gibt es bestimmte Richtlinien, wann man PreparedStatements und wann man Statements verwenden soll?

(3) Ändern von Daten: Ich habe eine Eingabemaske in der die Daten eingegeben und angezeigt werden können. D.h. die Eingabemaske spiegelt immer den aktuellsten Zustand eines Datensatzes wider. Wenn der Benutzer nun Daten ändert und diese speichern will, ist es dann sinnvoll den ganzen Datensatz zu löschen und neu anzulegen, oder sollte man die alten Daten mit den Neuen vergleichen und nur die Änderungen speichern? Diese Frage interessiert mich auch deshalb, weil man, im Prinzip ein PreparedStatement für jedes Datum der Tabelle brauchen würde, wenn man nur die Änderungen eines Datensatzes speichern will.

(4) Gibt es irgendwelche guten Tutorials im Netz, die sich mit den Konzepten (Best practices, etc) der Datenbankprogrammierung beschäftigen (die eben Fragen wie (3) beantworten)? Alles was ich bis jetzt gefunden habe, beschäftigt sich nur mit der Syntax von JDBC.
 

Bleiglanz

Gesperrter Benutzer
1) weil jede db etwas anderes mit literalen (datum, escape-sequenzen bei strings, ...) umgeht

und weil man dadurch gegen sql-injection etwas besser abgesichert ist

2) IMMER

- wenn "dynamisch", d.h. der SQL-String zur Compilezeit nicht feststeht

- wenn die Abfrage "mehrfach" ausgeführt wird und die DB und der Treiber eine entsprechende optimierung erlauben

ansonsten tuts auch ein fester SQL-String als normales Statement

3) NIE LÖSCHEN, DAS IST UNSINN

ob man bei einem UPDATE alle Spalten überschreibt (ist einfacher) oder nur die, die sich geändert haben (ist etwas aufwändiger) ist geschmackssache

Wenns Trigger o.ä. gibt, ist der zweite weg oft besser

4) http://www.google.com/search?client...l=en&q=jdbc+best+practices&btnG=Google+Search
 
G

Guest

Gast
Hallo!

Danke für die Antworten auf meine Fragen. Ich hab jetzt allerdings noch eine Frage zur Verwendung von Statements/PreparedStatements und ResultSets.

Ist es richtig, dass man bei der Verwendung von PreparedStatements diese beim Applikationsstart bzw. ersten Zugriff auf die DB erstellt und erst beim Programmende wieder schließt, während man Statements sofort nach dem Gebrauch wieder schliesst? Schließt man ResultSets auch gleich nach deren Verwendung? Etwa so:
Code:
Statement stmnt = null;
ResultSet res = null;
try
{
   res = stmnt.executeQuery("Select * FROM ......");
   // Verarbeite res
} finally
{
    if (stmnt != null) stmnt.close();
    if (res != null) res.close();
}
 

Bleiglanz

Gesperrter Benutzer
hängt davon ab, eher nein

am besten ist es, ALLES immer sofort wieder zu schliessen (und ggf. einen Connection-Pool verwenden); also eine Hit-And-Run Strategie

muss gut überlegt sein, wenn man irgendein mit der DB verbundenes Ding länger als 1 Minute "offen" hält...



Code:
Connection conn=null;
Statement st = null;
ResultSet rs = null;
try
{
    conn = X.getConnection); // X=?
    st = conn.createStatement();
    rs = st.executeQuery("...");
    //
    // jetzt ARBEITEN
    //
    rs.close();
    rs = null;
    st.close();
    st = null;
    conn.close();
    conn = null;
}
catch(SQLException e)
{
    // oder weiterwerfen
}
finally
{
    // wenn != null dann gabs nen Fehler
    if(rs!=null)
    {
      try{rs.close();}catch(Exception e){//meistens nix zu tun??}
    }
    if(st!=null)
    {
      try{st.close();}catch(Exception e){}
    }
    if(conn!=null)
    {
      try{conn.close();}catch(Exception e){}
    }
}
 
G

Guest

Gast
Danke für die Antwort. Das hat mir jetzt schon mal sehr geholfen. :toll:

Was mir allerdings noch nicht klar ist, ist ob man das mit PreparedStatements auch so machen soll wie mit normalen Statements? Denn wenn ich ein PreparedStatement erst in der Methode erzeuge in der es gebraucht wird, dann würde das ja mit jedem Aufruf dieser Methode erneut "vor-kompiliert" und der Vorteil von PreparedStatement doch wieder weg, oder sehe ich da was falsch?
 

Bleiglanz

Gesperrter Benutzer
im prinzip ja

hängt aber vom jdbc-treiber ab, ob er dieses statement nicht doch cached (eigentlich soll die vor-kompilierung in der DB stattfinden)

richtig sinn manchen die IMHO nur, wenn du schnell hintereinander mehrere Queriys absetzen musst, bei denen sich nur ein parameter ändert (clear - setString(1,"foo"); - clear - setString(1,"bar") usw.

schöner wärs natürlich

prepStatement öffenen

was tun

3 Minuten warten

nochmal was mit dem prep tun

nochmal 5 Minuten warten

usw.


=> aber wie schon gesagt, dass "offenhalten" von Connections ist etwas diffizil und muss sauber "ausprogrammiert" werden :)
 

Bleiglanz

Gesperrter Benutzer
ähh, hab mich verschrieben

"richtig Sinn" machen prepStatements auch dann, wenn dynamisch Werte in einen SQL-String eingesetzt werden, weil dann das "Escapen" und "Quoten" vom Treiber übernommen wird

+ arbeitserleichterung
+ portabilität
+ sicherheit
 

pro_evo

Aktives Mitglied
kurze Frage:

Sind die PreparedStatements auch für SELECT Abfragen geeignet ?

Hab die nämlich nur bei Update Anweisungen gesehen ....
 
G

Guest

Gast
pro_evo hat gesagt.:
kurze Frage:

Sind die PreparedStatements auch für SELECT Abfragen geeignet ?

Hab die nämlich nur bei Update Anweisungen gesehen ....
Ja.
z.B.
Code:
SELECT feld1, feld2, feld3...
FROM Tabelle
WHERE feld1 BETWEEN ? AND ?
  AND feld2 LIKE ?
  AND feld3 = ?
 

pro_evo

Aktives Mitglied
Anonymous hat gesagt.:
pro_evo hat gesagt.:
kurze Frage:

Sind die PreparedStatements auch für SELECT Abfragen geeignet ?

Hab die nämlich nur bei Update Anweisungen gesehen ....
Ja.
z.B.
Code:
SELECT feld1, feld2, feld3...
FROM Tabelle
WHERE feld1 BETWEEN ? AND ?
  AND feld2 LIKE ?
  AND feld3 = ?


hmm sry aber den Code hab ich ned verstanden ???:L

edit : sowas geht schomma ned ...
Code:
PreparedStatement ps = con.prepareStatement("Select ? FROM Mannschaft");
			ps.setString(1,"*");
			ResultSet rs = ps.executeQuery();
 
G

Guest

Gast
Der Platzhalter gelten nur für die WHERE-Klausel.
Das, was Du haben möchtest, kannst Du mit z.B.
java.text.MessageFormat oder auch, wenn's sein
muss, mit StringBuffer oder RegEx erreichen.
 

Bleiglanz

Gesperrter Benutzer
DP hat gesagt.:
Bleiglanz hat gesagt.:
wenn du schnell hintereinander mehrere Queriys absetzen musst

wieviele sind mehrere?

thx

das wieviel ist ganz egal, solange es in einem Rutsch durchläuft

Ich meinte damit nur, dass man das preparedStatement beim "Sammeln von Ergebnissen" aus N Abfragen

Query1 (mit Param1)
Query2 (mit Param2)
...
QueryN (mit ParamN)

sicher gut brauchen kann, solange zwischen den Abfragen nicht auf einen Mausklick / IO / irgendwas gewartet werden muss. In obigem Fall wäre aber wohl ein handgestricktes WHERE ..IN (...) besser :)

BTW: ich nehme IMMER preparedStatements, wenn ein dynamischer Parameter drinsteckt (auch wenn ich das nur einmal brauche)
 

pro_evo

Aktives Mitglied
Anonymous hat gesagt.:
Der Platzhalter gelten nur für die WHERE-Klausel.
Das, was Du haben möchtest, kannst Du mit z.B.
java.text.MessageFormat oder auch, wenn's sein
muss, mit StringBuffer oder RegEx erreichen.

acho ok , und woran liegt das, macht der da evtl. Hochkommas mit rein der setString oder wie ?
 

Bleiglanz

Gesperrter Benutzer
ja (zumindest bei allen DBs die ich kenne)

ganz sicher kann man sich aber nie sein, weil es nicht möglich ist, den erzeugen SQL-String auszulesen

BTW hab ich das auch schon oft verflucht, wär halt so schön gewesen, wenn man beim
Code:
ORDER BY ? ?
die Spalte und ein "ASC" oder "DESC" einfügen könnte

die spalte geht meistens, weil integers ja normalerweise nicht gequotet werden, aber das ASC oder DESC muss man sich dann immer mit Stringbearbeitung hinkleben
 

pro_evo

Aktives Mitglied
Alles klar ! thx

Bleiglanz hat gesagt.:
ganz sicher kann man sich aber nie sein, weil es nicht möglich ist, den erzeugen SQL-String auszulesen
oh genau danach hab ich die API letztens abgegrast, aber nat. nix gefunden ...
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben