Datenanbindung

Werbung
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
K10 Datenanbindung
•
Inhalt
1. Files
1. Text-Files
2. StreamTokanizer
3. Objekt-Serialisierung
2. Datenbanken
1.
2.
3.
4.
JDBC Driver
JDBC Connection
JDBC Statement
ResultSets
3. JTable
1. ResultSet TableModel
2. Editieren
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 1
Lernziele
• Sie können Textfiles Einlesen und in Token zerlegen
• Sie wissen, was Persistenz ist und wie der Zustand
von Objekten gesichert/gelesen werden kann
• Sie kennen die Arbeitsweise/Architektur von JDBC
• Sie können über JDBC
–
–
–
–
eine Verbindung zu einer Datenbank herstellen
eine Abfrage absetzen
die Resultate auswerten
Daten verändern
• Sie wissen, wie Datenbanken in TableModel
verwendet werden
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 2
Seite 1
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
1.1 Text in "data1.txt" schreiben: Beispiel (1)
import java.io.*;
import java.text.*;
public class WriteTextFile1 {
public static void main(String[] args) {
String fileName = "data1.txt";
File aFile = new File(fileName);
if (!aFile.exists()) {
try {
FileWriter aFileWriter = new FileWriter(aFile);
BufferedWriter aBufferedWriter =
new BufferedWriter(aFileWriter);
PrintWriter aPrintWriter =
new PrintWriter(aBufferedWriter);
aPrintWriter.println("This is the 1. line.");
aPrintWriter.println("This is the 2. line.");
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 3
1.1 Text in "data1.txt" schreiben: Beispiel (2)
DecimalFormat df =
new DecimalFormat("' '0000.000;-0000.000");
aPrintWriter.print(df.format(12.3));
aPrintWriter.print("
");
aPrintWriter.print(df.format(10));
aPrintWriter.println();
aPrintWriter.print(df.format(1111.22222));
aPrintWriter.print("
");
aPrintWriter.print(df.format(-10.1));
aPrintWriter.flush();
aFileWriter.close();
}
catch (IOException e) {
System.out.println("Exception: " + e.getMessage());
return;
}
}
}
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 4
Seite 2
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
1.1 Text von "data1.txt" lesen: Beispiel (1)
public class ReadTextFile1 {
public static void main(String[] args) {
String fileName = "data1.txt";
File aFile = new File(fileName);
if (aFile.exists()) {
try {
FileReader aFileReader = new FileReader(aFile);
BufferedReader aBufferedReader =
new BufferedReader(aFileReader);
System.out.println(aBufferedReader.readLine());
System.out.println(aBufferedReader.readLine());
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 5
1.1 Text von "data1.txt" lesen: Beispiel (2)
String line;
StringTokenizer sT;
double d;
while ((line = aBufferedReader.readLine()) != null) {
sT = new StringTokenizer(line);
while (sT.hasMoreTokens()) {
d = (Double.valueOf(
sT.nextToken())).doubleValue();
// Put your code here
System.out.println(d);
}
}
aFileReader.close();
}
catch (IOException e) {
System.out.println("Exception: " + e.getMessage());
return;
}
}
}
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 6
Seite 3
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
1.2 Klasse StreamTokenizer (1)
• Klasse StreamTokenizer
– Auch in Package java.io definiert
– Nützliche Methoden zur lexikalischen Analyse
• Groben Syntaxanalyse eines Datenstroms
StreamTokenizer
nval:double
sval:String
ttype:int
commentChar(int ch):void
nextToken():int
ordinaryChar(int ch):void
resetSyntax():void
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 7
1.2 Klasse StreamTokenizer (2)
StreamTokenizer wird an Datenstrom angehängt
• Methoden
– Beschränkte Definition einer Syntax
•
•
•
•
Whitespace
Normale Zeichen
Sonderzeichen
Kommentare
• Aufruf
nextToken() entnimmt dem Datenstrom das
nächste Token
– Zeichenketten und Zahlenwerte werden automatisch in
Strings bzw. double-Werte umgewandelt.
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 8
Seite 4
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
1.2 Klasse StreamTokenizer (3)
• Beispiel
– Von einem Textfile sollen, abgesehen von Kommentaren,
Zeichenketten und Zahlenwerte eingelesen werden:
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 9
1.2 Klasse StreamTokenizer: Beispiel (1)
import java.io.*;
import java.util.StringTokenizer;
public class TokenizerDemo {
public static void main(String[] args) throws IOException {
if (args.length == 1) {
Reader aReader = new FileReader(args[0]);
StreamTokenizer sT = new StreamTokenizer(aReader);
sT.ordinaryChar('/');
// recognizes C++-style comments
sT.slashSlashComments(true);
// recognizes C-style comments
sT.slashStarComments(true);
// numbers should be parsed
sT.parseNumbers();
// treats end of lines as tokens
sT.eolIsSignificant(true);
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 10
Seite 5
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
1.2 Klasse StreamTokenizer: Beispiel (2)
int tval;
while ((tval = sT.nextToken()) != StreamTokenizer.TT_EOF)
{
switch (tval) {
case StreamTokenizer.TT_NUMBER :
System.out.print("[N: " + sT.nval + " ]");
break;
case StreamTokenizer.TT_WORD :
System.out.print("[S: " + sT.sval + " ]");
break;
case StreamTokenizer.TT_EOL :
System.out.println();
break;
default :
System.out.print("[X: " + sT.ttype + " ]");
}
}
aReader.close();
}
else {
System.exit(1);
}
}}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 11
1.3 Objekt-Serialisierung (1)
• Bisherige I/O-Möglichkeiten
– Elementare Datentypen: byte, char, int, String
• Wunsch, Anforderung der OOP
– Ein-/ Ausgabe von Objekten
Objekte
ObjektSerialisierung
Werte der
Instanzvariablen
Byte-Datenstrom
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 12
Seite 6
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
1.3 Objekt-Serialisierung (2)
• Objekt-Serialisierung
– Speichern und wieder Einlesen von Objekten
• Auf anderem Rechner oder via Internet
• Objekte, die ausserhalb eines Laufzeitsystems existieren werden
persistente Objekte genannt
– Instanzvariablen werden in Byte-Datenstrom geschrieben
• Marshalling/Unmarshalling
– Klassenvariablen werden nicht serialisiert!
ObjectOutputStream, ObjectInputStream
• Ausgabestrom kann mit FileOutputStream verbunden werden
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 13
1.3 Objekt-Serialisierung (3)
• Modifier transient
– Instanzvariablen werden nicht serialisiert
• Hilfsvariablen
• Sicherheitsgründe
transient int currentVolume;
• Interface Serializable
– Klassen, die serialisiert werden sollen müssen das
Interface Serializable implementieren
– Leeres Interface
• Marker-Interface
• Erlaubt durch Überprüfung des Klassen-Typs die Serialisierung
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 14
Seite 7
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
1.3 Objekt-Serialisierung: Beispiel (1)
import java.io.*;
public class SerializationDemo {
public static void main(String[] args) throws Exception {
// Integer implements interface Serializable
Integer i = new Integer(2000);
System.out.println("i = " + i);
// Write Object
FileOutputStream aFileOutputStream =
new FileOutputStream("temp.dat");
ObjectOutputStream aObjectOutputStream =
new ObjectOutputStream(aFileOutputStream);
aObjectOutputStream.writeObject(i);
aFileOutputStream.close();
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 15
1.3 Objekt-Serialisierung: Beispiel (2)
// Read Object
FileInputStream aFileInputStream =
new FileInputStream("temp.dat");
ObjectInputStream aObjectInputStream =
new ObjectInputStream(aFileInputStream);
Object o = aObjectInputStream.readObject();
aFileInputStream.close();
Integer j = (Integer)o;
System.out.println("j = " + j);
}
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 16
Seite 8
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.1 JDBC Driver (1)
• Vor dem Öffnen einer Verbindung muss der
JDBC-Driver geladen werden
– Über statische Methode
Class.forName("Drivername");
– Über Konstruktor
Class.forName("Drivername").newInstance();
– Über statische Methode
DriverManager.registerDriver( new Drivername() );
– Typische Driver-Namen
sun.jdbc.odbc.JdbcOdbcdriver
oracle.jdbc.driver.OracleDriver
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 17
2.2 JDBC Connection (1)
• Die Klasse Connection dient zur Verbindung mit
einer Datenbank
• Erzeugt wird diese Verbindung vom
JDBC DriverManager
Connection con = DriverManager.getConnection(String url);
• Varianten von getConnection
static Connection getConnection(String url)
static Connection getConnection(String url,
String user,
String password)
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 18
Seite 9
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.2 JDBC Connection (2)
• Der URL hat eine der folgenden Formen:
– Lokale Datenbank mit JDBC-Driver
jdbc:protocol:databasename
– Datenbank auf anderem Rechner mit JDBC-Driver
jdbc:protocol://hostname:port/databasename
– Lokale ODBC Datenbank mit JDBC-ODBC-Driver
jdbc:odbc:datasourcename
– ODBC Datenbank auf anderem Rechner mit
JDBC-ODBC-Driver
jdbc:odbc://hostname/datasourcename
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 19
2.2 JDBC Connection (3)
• Wichtigste Methoden
Methode
Beschreibung
Statement createStatement()
Erzeugt ein Statement für die Ausführung
von SQL-Befehlen
PreparedStatement prepareStatement(String sql)
Erzeugt ein Prepared Statement für die optimierte
Ausführung von SQL-Befehlen
DatabaseMetaData getMetaData()
Liefert Metadaten (DDL) der Datenbank
void setReadOnly(boolean readOnly)
true: Es werden nur Datenbankabfragen durchgeführt
false: Abfragen und Updates sind möglich
void setAutoCommit(boolean autoCommit)
true: Jedes SQL-Statement wird als eigene Transaktion
ausgeführt
false: Mehrere SQL-Statements müssen mit commit()
und rollback() zu einer Transaktion zusammengefasst werden
void commit()
Beendet eine Transaktion erfolgreich
void rollback()
Beendet eine Transaktion im Fehlerfall. Alle
Änderungen seit Beginn der Transaktion werden
rückgängig gemacht
void close()
Beendet die Verbindung mit der Datenbank
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 20
Seite 10
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.3 JDBC Statement (1)
• Das Interface Statement definiert Methoden zur
Ausführung eines oder mehrerer SQL-Statements
• Erzeugt wird diese Statement von der Connection
Statement stmt = con.createStatement();
• Wichtigste Methoden
Methode
Beschreibung
ResultSet executeQuery(String sql)
Führt SQL-Statement aus und gibt Resultat als
ResultSet zurück
int executeUpdate(String sql)
Führt SQL-Statement aus, das kein Resultat liefert.
Rückgabewert ist Anzahl Records, die vom Befehl
betroffen waren
boolean execute(String sql)
Führt SQL-Statement aus, das mehrere ResultSets
liefern kann
void setQueryTimeout(int seconds)
Setzt Zeitlimit für die Durchführung von Abfragen
void close()
Beendet Statement
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 21
2.3 JDBC Statement (2)
• Beispielskizze für Abfrage
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery
("SELECT LastName, Salary, Age FROM Employees");
...
stmt.close();
• Beispielskizze für Update
Statement stmt = con.createStatement();
int rowCount = stmt.executeUpdate("UPDATE Employees" +
"SET Salary = 50000.0 WHERE LastName = 'Bieri' ");
...
stmt.close();
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 22
Seite 11
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4 ResultSet (1)
• ResultSet
– ist das Ergebnis einer SQL-Abfrage
– enthält einen oder mehrere Records
– bietet Methoden um auf Datenfelder zuzugreifen
• Scrolling
– ResultSet kann vorwärts/rückwärts durchlaufen werden
– Auch sensitive ResultSets möglich (dynamische Sicht)
• Updates
– Tupel und Ergebnisse sind änderbar
– Änderungen können sich auch auf Datenbank auswirken
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 23
2.4 ResultSet (2)
• Wichtigste Methoden
Methode
Beschreibung
boolean next()
Setzt den Cursol auf den ersten bzw. nächsten Record innerhalb von
ResultSet
boolean previous()
Setzt den Cursol auf den vorhergehenden Record innerhalb von
ResultSet (ab JDBC 2.0)
boolean getBoolean(String name)
Liefert den Wert des Feldes mit angegebenem name (case-insensitiv)
int getInt(String name)
Liefert den Wert des Feldes mit angegebenem name (case-insensitiv)
float getFloat(String name)
Liefert den Wert des Feldes mit angegebenem name (case-insensitiv)
double getDouble(String name)
Liefert den Wert des Feldes mit angegebenem name (case-insensitiv)
String getString(String name)
Liefert den Wert des Feldes mit angegebenem name (case-insensitiv)
boolean getBoolean(int n)
Liefert den Wert des n-ten Feldes (von 1 an gezählt)
int getInt(int n)
Liefert den Wert des n-ten Feldes (von 1 an gezählt)
float getFloat(int n)
Liefert den Wert des n-ten Feldes (von 1 an gezählt)
double getDouble(int n)
Liefert den Wert des n-ten Feldes (von 1 an gezählt)
String getString(int n)
Liefert den Wert des n-ten Feldes (von 1 an gezählt)
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 24
Seite 12
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4.1 ResultSet Typen (1)
• Drei ResultSet Typen
– vorwärts (TYPE_FORWARD_ONLY)
• Navigation nur vorwärts möglich
• Statische Sicht auf Daten
– scroll-insensitive (TYPE_SCROLL_INSENSITIVE)
• Navigation in beliebiger Richtung möglich
• Statische Sicht auf Daten
– scroll-sensitive (TYPE_SCROLL_SENSITIVE)
• Navigation in beliebiger Richtung möglich
• Änderungen auf der Datenbank sind sichtbar
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 25
2.4.1 ResultSet Typen (2)
• Zusätzlich Charakteristik von ResultSets
– Änderbarkeit
– Synchronisationsverhalten
– nicht änderbar (CONCUR_READ_ONLY)
• Keine Änderungen der Daten sind im ResultSet erlaubt
– änderbar (CONCUR_UPDATABLE)
• Änderungen erlaubt
• Löschen erlaubt
• Einfügen erlaubt
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 26
Seite 13
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4.2 Erzeugen von ResultSets (1)
• Konstanten für ResultSet Typen
Konstante
Beschreibung
static int TYPE_FORWARD_ONLY
Navigation nur vorwärts möglich, statische Sicht auf Daten
static int TYPE_SCROLL_INSENSITIVE
Navigation in beliebiger Richtung möglich, statische Sicht auf Daten
static int TYPE_SCROLL_SENSITIVE
Navigation in beliebiger Richtung möglich, Änderungen erlaubt
static int CONCUR_READ_ONLY
Keine Änderungen der Daten sind im ResultSet erlaubt
static int CONCUR_UPDATABLE
Änderungen erlaubt, Update, Insert, Delete
• Beispiel
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT * FROM Employees");
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 27
2.4.2 Erzeugen von ResultSets (2)
• Abfrage der Eigenschaften über Metadaten
Methode
Beschreibung
boolean supportsResultSetType(int ResultSetType)
Abfrage der unterstützten Typen
boolean supportsResultSetConcurrency(int ResultSetType)
Abfrage der Änderbarkeit
• Abfrage der Eigenschaften beim ResultSet
Methode
Beschreibung
int getType()
Abfrage der unterstützten Typen
int getConcurrency()
Abfrage der Änderbarkeit
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 28
Seite 14
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4.3 Scrollen in ResultSets (1)
• Scrollbare ResultSets in JDBC 2 erlauben freies
Navigieren über die Ergebnismenge
• Methoden zum Positionieren
Methode
Beschreibung
void beforeFirst()
Setzt Cursor vor das erste Tupel
void afterLast()
Setzt Cursor hinter das letzte Tupel
boolean first()
Setzt Cursor direkt auf das erste Tupel. False wenn keine Tupel vorhanden sind
boolean last()
Setzt Cursor direkt auf das letzte Tupel. False wenn keine Tupel vorhanden sind
• Bei leerer Ergebnismenge liefert first(), last()
das Ergebnis false
• Initiale Position ist immer vor dem ersten Tupel
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 29
2.4.3 Scrollen in ResultSets (2)
• Cursor kann auch direkt auf ein bestimmtes Element
gesetzt werden
Methode
Beschreibung
boolean absolute(int row)
Absolute Positionierung von 1 an gezählt
boolean relative(int row)
Relative Positionierung vom aktuellen Tupel aus
• Aktuelle Position des Cursors
Methode
Beschreibung
int getRow()
Aktuelle, absolute Position des Cursors
boolean isLast()
True, wenn Cursor auf dem letzten Tupel steht
boolean isFirst()
True, wenn Cursor auf dem ersten Tupel steht
boolean isAfterLast()
True, wenn Cursor hinter dem letzten Tupel steht
boolean isBeforeFirst()
True, wenn Cursor vor dem ersten Tupel steht
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 30
Seite 15
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4.4 Updates in ResultSets
• Methoden für Updates in ResultSets
Methode
Beschreibung
void updateRow()
Schreibt Inhalt der Zeile in die Datenbank
void cancelRowUpdates()
Macht Änderungen auf dem ResultSet rückgängig
void updateBoolean(String columnName, boolean x)
void updateBoolean(int columnIndex, boolean x)
Setzt den Wert des Feldes (name case-insensitiv)
Setzt den Wert des Feldes (Index)
void updateInt(String columnName, int x)
void updateInt(int columnIndex, int x)
Setzt den Wert des Feldes (name case-insensitiv)
Setzt den Wert des Feldes (Index)
void updateLong(String columnName, long x)
void updateLong(int columnIndex, long x)
Setzt den Wert des Feldes (name case-insensitiv)
Setzt den Wert des Feldes (Index)
void updateFloat(String columnName, float x)
void updateFloat(int columnIndex, float x)
Setzt den Wert des Feldes (name case-insensitiv)
Setzt den Wert des Feldes (Index)
void updateDouble(String columnName, double x)
void updateDouble(int columnIndex, double x)
Setzt den Wert des Feldes (name case-insensitiv)
Setzt den Wert des Feldes (Index)
void updateString(String columnName, String x)
void updateString(int columnIndex, String x)
Setzt den Wert des Feldes (name case-insensitiv)
Setzt den Wert des Feldes (Index)
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 31
2.4.4 Updates in ResultSets: Beispiel
• Änderung an einem bestehenden Tupel
ResultSet rs = stmt.executeQuery("SELECT * FROM Employees");
if(rs.first())
{
rs.updateInt("BirthYear", 1972);
rs.updateRow();
}
stmt.close();
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 32
Seite 16
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4.5 Einfügen in ResultSets
• Das Einfügen eines Tuples erfolgt an einer
speziellen Einfügeposition
• Die Einfügeposition wird mit der Methode
moveToInsertRow() erreicht
• Die Einfügeposition wird anschliessend über die
updateXXX()-Methoden mit Werten belegt
• Zum Schluss werden diese mit insertRow()
gespeichert
• Beim Wechsel zur Einfügeposition merkt sich das
ResultSet die aktuelle Cursor-Position
• Nach dem Einfügen kann mit der Methode
moveToCurrentRow() zurückgesprungen werden
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 33
2.4.5 Einfügen in ResultSets: Beispiel
• Neues Tupel einfügen
ResultSet rs = stmt.executeQuery("SELECT * FROM Employees");
if(rs.absolute(10))
{
rs.moveToInsertRow(); // Move to special row for inserts
rs.updateString("FirstName", "Freddy");
rs.updateString("LastName", "Schnell");
rs.updateInt("BirthYear", 1981);
rs.updateFloat("Salary", 65100.0);
rs.insertRow();
//Zurück zu Tupel #10
rs.moveToCurrentRow(); // Move back to current row
}
stmt.close();
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 34
Seite 17
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4.6 Löschen in ResultSets
• Zum Löschen eines Tuples aus einem ResultSet
muss der Cursor entsprechend positioniert werden
• Anschliessend kann das Tupel durch Aufruf von
deleteRow() gelöscht werden
• Ob das Tupel physisch aus dem ResultSet gelöscht
wird oder nur als gelöscht markiert wird, ist von der
Implementierung des Treibers abhängig
• Alle Änderungen über ResultSets lassen sich
natürlich auch mit SQL-Operationen ausführen
– Nicht alle Anfragen führen zu änderbaren ResultSets
– Änderungen über ResultSets sind mehr für interaktive
Anwendungen geeignet
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 35
2.4.6 Löschen in ResultSets: Beispiel
• Tupel löschen
ResultSet rs = stmt.executeQuery("SELECT * FROM Employees");
if(rs.absolute(10))
{
rs.deleteRow();
rs.absolute(10))
}
stmt.close();
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 36
Seite 18
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
2.4.7 Limiten für ResultSets (1)
• Die meisten Treiber limitieren die Anzahl der
Datensätze innerhalb eines ResultSets
• Diese maximale erlaubte Anzahl Datensätze kann
auf dem Statement–Objekt erfragt und konfiguriert
werden
int max = myStatement.getMaxRows();
myStatement.setMaxRows(1000);
• Die Limitierung kann auch wieder aufgehoben
werden
myStatement.setMaxRows(0);
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 37
2.4.7 Limiten für ResultSets (2)
• Es gibt auch Feld-Typen, welche eine grosse Anzahl an
binären Daten aufnehmen können
– BINARY Fields
– BLOB (Binary Large Object, SQL-99)
– CLOB (Character Large Object, SQL-99)
• Die Limitierung der Feldgrösse kann auf dem Statement–
Objekt erfragt und konfiguriert werden
int max = myStatement.getMaxFieldSize();
myStatement.setMaxFieldSize(4096);
• Die Limitierung kann auch wieder aufgehoben werden
myStatement.setMaxFieldSize(0);
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 38
Seite 19
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
3.1.1 ResultSet TableModel: Version 1 (1)
• Version 1 mit Daten-Vektor
class ResultSetModel1 extends AbstractTableModel {
private
private
private
private
private
private
ResultSet rs;
// Ref to ResultSet
int cols;
// nbr of columns in rs
int rows;
// nbr of rows in rs
ResultSetMetaData rsmd;
// Ref to Metadata
Vector vRows = new Vector(); // Data-Vector
String[] columnNames = new String[0];
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 39
3.1.1 ResultSet TableModel: Version 1 (2)
public int getColumnCount() {
return cols ;
}
public String getColumnName(int col) {
return columnNames[col];
}
public int getRowCount() {
return vRows.size();
}
public Object getValueAt(int row, int col) {
Vector vOneRow = (Vector) vRows.elementAt(row);
return vOneRow.elementAt(col);
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 40
Seite 20
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
3.1.1 ResultSet TableModel: Version 1 (3)
public void setResultSet(ResultSet rs) {
try {
rsmd = rs.getMetaData();
// build a string array of column names
cols = rsmd.getColumnCount();
columnNames = new String[cols];
for(int i = 0; i < cols; i++) {
columnNames[i] = rsmd.getColumnLabel(i + 1);
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 41
3.1.1 ResultSet TableModel: Version 1 (4)
// build data vector of vectors
while(rs.next()) {
Vector vOneRow = new Vector();
for(int i = 0; i < cols; i++) {
vOneRow.addElement(rs.getString(i + 1));
}
vRows.addElement(vOneRow) ;
}
fireTableChanged(null) ;
// tell JTable to update
}
catch (SQLException sqle) {}
}
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 42
Seite 21
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
3.1.2 ResultSet TableModel: Version 2 (1)
• Version 2 mit direktem Zugriff auf ResultSet
class ResultSetModel2 extends AbstractTableModel {
private
private
private
private
ResultSet rs;
// Ref to ResultSet
int cols;
// nbr of columns in rs
ResultSetMetaData rsmd;
// Ref to Metadata
String[] columnNames = new String[0];
public int getColumnCount() {
return cols;
}
public String getColumnName(int col) {
return columnNames[col];
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 43
3.1.2 ResultSet TableModel: Version 2 (2)
public int getRowCount() {
if (rs == null) return 0;
try {
rs.last();
return rs.getRow();
}
catch (SQLException sqle) { return 0; }
}
public Object getValueAt(int row, int col) {
try {
rs.absolute(row + 1);
return rs.getString(col + 1);
}
catch ( SQLException sqle ) { return null ; }
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 44
Seite 22
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
3.1.2 ResultSet TableModel: Version 2 (3)
public Class getColumnClass( int col ) {
String className = new String();
try {
className = rsmd.getColumnClassName(col);
}
catch (SQLException e) { }
if (className.endsWith("String")) return String.class;
else if(className.endsWith("Boolean")) return Boolean.class;
else if(className.endsWith("Short")) return Short.class;
else if(className.endsWith("Integer")) return Integer.class;
else if(className.endsWith("Long")) return Long.class;
else if(className.endsWith("Double")) return Double.class;
else if(className.endsWith("Date")) return java.sql.Date.class;
else return Object.class;
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 45
3.1.2 ResultSet TableModel: Version 2 (4)
public void setResultSet(ResultSet rs) {
this.rs = rs; // set the table model's data source
try {
rsmd = rs.getMetaData();
// build a string array of column names
cols = rsmd.getColumnCount();
columnNames = new String[cols];
for(int i = 0; i < cols; i++) {
columnNames[i] = rsmd.getColumnLabel(i + 1);
}
fireTableChanged(null); // tell JTable to update
}
catch(SQLException sqle) {}
}
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 46
Seite 23
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
3.2 JTable: Editieren
•
•
1.
2.
Wenn das TableModel von der Klasse
AbstractTableModel abgeleitet wird, so sind die
Zellen read-only
So werden die Zellen editierbar gemacht:
JTable myTable = new JTable(myTableModel);
myTable.setCellSelectionEnabled(true);
public boolean isCellEditable(int row, int col) {
// lock first column
if (col == 0) return false;
return true; //otherwise can edit
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 47
3.2 JTable: Editieren: Version 1
• Version 1 mit Daten-Vektor
public void setValueAt(Object value, int row, int
try {
vOneRow = (Vector)vRows.elementAt(row);
vOneRow.setElementAt(value, col);
vRows.setElementAt(vOneRow, row);
col){
// SQL UPDATE um Daten in Datenbank zu schreiben
...
}
catch (SQLException e) {}
}
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 48
Seite 24
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
3.2 JTable: Editieren: Version 2
• Version 2 mit direktem Zugriff auf ResultSet
public void setValueAt(Object value, int row, int
try {
rs.absolute(row + 1);
col){
// Strings only, need other code for other types
rs.updateString(col + 1, value.toString());
rs.updateRow(); // where supported
}
catch (SQLException e) {}
}
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 49
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 50
Seite 25
FHZ
Hochschule Technik+Architektur Luzern
Abteilung Informatik, Swing/JFC
K10 Datenanbindung
Zusammenfassung
• Beim Einlesen von Text-Files können einzelne
Felder durch StringTokanizer oder StreamTokanizer
isoliert werden
• Bei der Objekt-Serialisierung werden ObjektZustände gesprichert/gelesen
– Speichern/ Einlesen von Instanzvariablen
• Um ein Objekt serialisierbar zu machen genügt es,
das Marker-Interface Serializable zu
"implementieren"
• Mit dem Modifier transient wird das Serialisieren
einzelner Instanzvariablen unterdrückt
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10 Datenanbindung
Folie 51
Zusammenfassung
• Ab JDBC 2 sind Scrolling und Updates direkt auf
ResultSets möglich
• Änderungen in Result-Sets beziehen sich immer auf
das Tupel an der aktuellen Cursor-Position
• Das Einfügen eines Tuples erfolgt an einer
speziellen Einfügeposition
• Zum Löschen eines Tuples aus einem ResultSet
muss der Cursor entsprechend positioniert werden
• ResultSet und TableModel lassen sich kombinieren:
– statische Sicht auf Datenbank
– dynamische sicht auf die Datenbank
Abteilung Informatik, JFC/Swing
2004 © Diego Schmidlin V2.2
K10_Datenanbindung-P.ppt, V2.2
2004 © Diego Schmidlin
K10 Datenanbindung
Folie 52
Seite 26
Herunterladen