SQL mit Java

+ andere TechDocs
+ SQL
+ MySQL
+ PostgreSQL
+


SQL (Structured Query Language) hat sich als Abfragesprache für relationale Datenbanken durchgesetzt.
Java ist eine verbreitete moderne Programmiersprache, die wie SQL plattformunabhängig ist, sehr gut mit SQL zusammenarbeitet und besonders auf der Serverseite optimal auch für komplexe Anwendungen geeignet ist.



Inhalt

  1. Objektrelationales Mapping
  2. Datenbankanbindung mit Java per JDBC
    1. JDBC Type 4
    2. Connection Pooling
    3. hSqlDb
    4. MySQL
    5. PostgreSQL
    6. Oracle
    7. DB2
    8. InterBase und Firebird
    9. Sybase
    10. Microsoft
    11. ODBC
  3. Programmierbeispiele
    1. Einfaches Programmierbeispiel zum Auslesen einer Tabelle aus einer SQL-Datenbank
    2. Einfaches Programmierbeispiel zum Auslesen einer Tabelle mit JSP
    3. Binärdaten als BLOB (Binary Large Object) in SQL-Datenbanktabellen
    4. Programmierbeispiel zum Speichern einer Binärdatei als BLOB
    5. Programmierbeispiel zum Anzeigen als BLOB gespeicherter Bilder
  4. Weiterführende Informationen


Objektrelationales Mapping

Persistenz per objektrelationalem Mapping (O/R-Mapping) ist nicht Thema der folgenden Beschreibungen, sondern nur direkte Zugriffe per JDBC.

Weiteres zu O/R finden Sie unter java-hibernate.htm.



Datenbankanbindung mit Java per JDBC


JDBC Type 4

Java-Anwendungen greifen auf SQL-Datenbanken über einen JDBC-Treiber zu (Java DataBase Connectivity). Dadurch kann der Java-Source-Code weitgehend datenbankunabhängig gehalten werden, so dass ein späterer Wechsel der SQL-Datenbank leicht möglich ist. Genaueres zu JDBC erfahren Sie unter http://www.oracle.com/technetwork/java/javase/jdbc.

In den meisten Fällen sind JDBC-Type-4-Treiber optimal. Sie sind sehr schnell und sehr einfach zu installieren.

Einen zu Ihrer Datenbank passenden JDBC-Treiber finden Sie am leichtesten unter http://industry.java.sun.com/products/jdbc/drivers.


Connection Pooling

Bei Multiuser-Anwendungen (z.B. in Webservern) greifen oft viele Benutzer gleichzeitig auf eine Datenbank zu. Um ressourcenschonend mit nur wenigen Datenbankverbindungen auskommen zu können und diese auch nicht immer wieder neu aufbauen zu müssen, wird Connection Pooling eingesetzt. Während hierfür früher externe Erweiterungen notwendig waren, ist dies mittlerweile Teil der JDBC2-Spezifikation und in Java-EE-Produkten integriert. Näheres hierzu finden Sie unter http://www.oracle.com/technetwork/java/javase/jdbc.


Anbindung an hSqlDb

  1. Infos zur Java-Datenbank hSqlDb gibt es unter http://hsqldb.org und im Javamagazin 2003.03 ab Seite 97.
    Anders als bei den im Folgenden genannten Datenbanktreibern enthält die hSqlDb.jar-Datei nicht nur den JDBC-Treiber, sondern die gesamte Datenbank.
  2. Das hSqlDb-Paket (z.B. 'hsqldb_1_8_0_7.zip') von http://hsqldb.org laden und entpacken. Benötigt wird die darin enthaltene Datei 'hsqldb.jar'.
  3. CLASSPATH muss die Datei 'hsqldb.jar' beinhalten.
  4. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "org.hsqldb.jdbcDriver" );
    cn = DriverManager.getConnection( "jdbc:hsqldb:file:C:/hSqlDbData/MeineDb", "sa", dbPwd );

    Dabei muss 'C:/hSqlDbData/' durch den Pfad eines existierenden Verzeichnisses ersetzt werden (auch unter Windows mit Schrägstrichen statt Backslashes). 'MeineDb' ist der Name der Datenbank innerhalb dieses Datenbankverzeichnisses.
  5. Erzeugen Sie eine erste Tabelle zum Testen mit dem Programmaufruf
    java -classpath <path>\hsqldb.jar org.hsqldb.util.DatabaseManager
    bzw.
    java -classpath <path>\hsqldb.jar org.hsqldb.util.DatabaseManager -url "jdbc:hsqldb:file:C:/hSqlDbData/MeineDb"
    (oder der Hilfsbatch '.../hsqldb/demo/runManager.bat'):
    Type: HSQL Database Engine Standalone
    Driver:org.hsqldb.jdbcDriver
    URL: jdbc:hsqldb:file:C:/hSqlDbData/MeineDb
    User: sa
    Command | Create Table: CREATE TABLE xx ( i INTEGER, s VARCHAR, d DATE );
    Command | Insert: INSERT INTO xx VALUES ( 123, 'abcABC', '2004-01-01' );
    Command | Insert: INSERT INTO xx VALUES ( 789, 'äöüߧ€', '2005-12-31' );
    Command | Select: SELECT * FROM xx;
    View | Refresh Tree: [+] XX

Anbindung an MySQL

  1. Zur Installation von MySQL siehe: mysql.htm#InstallationUnterWindows.
  2. MySQL-JDBC-Type-4-Treiber (z.B. 'mysql-connector-java-5.1.16-bin.jar' aus 'mysql-connector-java-5.1.16.zip') downloaden von: http://www.mysql.com.
  3. CLASSPATH muss JDBC-Treiber beinhalten.
  4. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "com.mysql.jdbc.Driver" );
    cn = DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName", dbUsr, dbPwd );


Anbindung an PostgreSQL

  1. Zur Installation von PostgreSQL siehe: postgresql.htm#InstallationUnterLinux.
  2. PostgreSQL-JDBC-Type-4-Treiber ('pgjdbc2.jar' oder 'postgresql.jar') laden von:
    http://jdbc.postgresql.org/download.html.
  3. CLASSPATH muss JDBC-Treiber beinhalten.
  4. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "org.postgresql.Driver" );
    cn = DriverManager.getConnection( "jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName", dbUsr, dbPwd );


Anbindung an Oracle

  1. Oracle-JDBC-Type-4-Treiber ojdbc7.jar laden von:
    http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html
  2. CLASSPATH muss Oracle-JDBC-Treiber beinhalten:
    set CLASSPATH=<...>\ojdbc7.jar
  3. Connection-Url nach dem Schema 'drivername@HostName_or_IP:port:sid' (siehe auch unten 'Programmierbeispiele'):
    Class.forName( "oracle.jdbc.OracleDriver" );
    cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", dbUsr, dbPwd );

Sehen Sie sich die weiteren Hinweise unter oraclexe-db.htm und die Oracle-Doku unter Oracle 11.1 und Oracle XE 11.2 an.


Anbindung an DB2

  1. JDBC-Treiber: 'db2java.zip'
  2. CLASSPATH muss JDBC-Treiber beinhalten.
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "COM.ibm.db2.jdbc.app.DB2Driver" );
    cn = DriverManager.getConnection( "jdbc:db2:myDatabaseName", dbUsr, dbPwd );

DB2/400 auf AS/400 (iSeries):

  1. JDBC-Treiber: 'jt400-7.1.0.10.jar' (aus JTOpen). Siehe: http://jt400.sourceforge.net, .../faqjdbc.html, .../modsreleases.html.
  2. CLASSPATH muss JDBC-Treiber beinhalten.
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "com.ibm.as400.access.AS400JDBCDriver" );
    cn = DriverManager.getConnection( "jdbc:as400://MyDbComputerNameOrIP/MyLib", dbUsr, dbPwd );

    oder bei mehreren Libs:
    cn = DriverManager.getConnection( "jdbc:as400://MyDbComputerNameOrIP;naming=system;libraries=,lib1,lib2,lib3", dbUsr, dbPwd );
    Weitere Optionen siehe JDBC Properties.
    (Falls Sie Exceptions ähnlich zu "java.sql.SQLException: [SQL0204] MeineTabelle der Art *FILE in MeineLib nicht gefunden." erhalten: Prüfen Sie, ob Sie bei libraries=... alle Bibliotheken eingetragen haben und die Kommata korrekt gesetzt sind sowie ob naming=... korrekt gesetzt ist.)
    (Falls Sie bei Schreiboperationen Exceptions ähnlich zu "[SQL7008] MeineTabelle in MeineLib für Operation ungültig" erhalten: Denken Sie daran, das Journaling zu aktivieren.)

DB2/400 auf AS/400 (iSeries), DataSource für XA-Two-Phase-Commit:

  1. 'jt400-7.1.0.10.jar' (aus JTOpen), com.ibm.as400.access.AS400JDBCXADataSource,
    'db2jcc.jar', com.ibm.db2.jcc.DB2XADataSource,
    'wldb2.jar', weblogic.jdbcx.db2.DB2DataSource.
  2. Obwohl zum Beispiel in http://e-docs.bea.com/wls/docs81/jdbc_drivers/db2.html#1076245 die DB2-Versionen V5R1 bis V5R3 für iSeries aufgeführt sind, funktioniert für diese AS/400-Versionen die XA-Two-Phase-Commit-Unterstützung noch nicht, da erst ab Version V5R4 das TMJOIN-Flag unterstützt wird. Siehe hierzu auch:
    http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/rzahh/javadoc/com/ibm/as400/access/AS400JDBCXAResource.html,
    http://e-docs.bea.com/wls/certifications/certs_610/as400_v5r1.html,
    http://e-docs.bea.com/wls/docs81/jdbc_drivers/db2.html#1076987,
    AS/400-JDBC-Treiber mit XA-Two-Phase-Commit ohne JTA/JTS ansteuern

DB2-Dokus:


Anbindung an Borland InterBase und an Firebird

  1. Zur Installation der Borland InterBase Datenbank siehe: http://www.borland.com/interbase, http://www.borland.com/products/downloads/download_interbase.html, http://info.borland.com/devsupport/interbase/opensource, ftp:...InterBase_WI-V6.0.1-server.ZIP.
  2. Mit '...\InterBase\bin\ibserver.exe' kann InterBase gestartet werden (wenn es nicht als Service installiert wurde).
    Mit '...\InterBase\bin\IBConsole.exe' kann eine Database eingerichtet oder angesehen werden (oder eine Beispieldatenbank von '...\InterBase\examples\Database' geladen werden).
  3. InterClient-JDBC-Treiber laden und installieren von:
    http://info.borland.com/devsupport/interbase/opensource, ftp:...IC20001winJRE12.exe.
    Achtung: InterClient ist erst ab Version 3.0 (IC3.0 aus IB7) ein echter JDBC-Type-4-Treiber.
    InterClient bis Version 2.5 (IC2.5 aus IB6.5) benötigt die Middlewarekomponente InterServer ('interserver.exe'), normalerweise auf dem InterBase-Datenbank-Server, wo 'ibserver.exe' läuft (siehe: http://bdn.borland.com/article/0,1410,29284,00.html und http://bdn.borland.com/article/0,1410,29974,00.html).
  4. CLASSPATH muss JDBC-Treiber 'interclient.jar' samt Pfad beinhalten.
    Achtung: Die InterClient-Installationsroutine setzt den CLASSPATH eventuell nur auf die 'interclient.jar'-Datei ohne das aktuelle Verzeichnis einzubinden. Damit direkte Kommandozeilencompilierungen funktionieren, sollte aber immer auch das aktuelle Verzeichnis "." im CLASSPATH enthalten sein, z.B. so: 'CLASSPATH=.;C:\Programme\Borland\InterClient\interclient.jar'.
  5. Connection (siehe auch unten 'Programmierbeispiele') (Default-Username/Password: "sysdba"/"masterkey"):
    Class.forName( "interbase.interclient.Driver" );
    cn = DriverManager.getConnection( "jdbc:interbase://MyDbComputerNameOrIP/myDatabasePath/myDatabaseFile", dbUsr, dbPwd );

    getConnection-Beispiel für Windows:
    cn = DriverManager.getConnection( "jdbc:interbase://MyServer/C:/InterBase-Data/MyDbFile.gdb", dbUsr, dbPwd );
    getConnection-Beispiel für Linux:
    cn = DriverManager.getConnection( "jdbc:interbase://MyServer//usr/local/InterBase-Data/MyDbFile.gdb", dbUsr, dbPwd );
  6. Zur Kontrolle das Beispiel '...\InterClient\examples\DriverExample.java' anpassen, compilieren und ausführen:
    1.) Im Taskmanager ('Strg+Alt+Entf') unter 'Prozesse' überprüfen, ob 'ibserver.exe' läuft
    2.) Eventuell '...\InterClient\bin\interserver.exe' starten
    3.) In 'DriverExample.java' Anpassung (s.o.) der Zeile
        'String databaseURL = "jdbc:interbase:.../InterBase/examples/Database/employee.gdb'
    4.) 'javac DriverExample.java'
    5.) 'java DriverExample'
  7. Falls Sie die Fehlermeldung 'Exception in thread "main" java.lang.NoClassDefFoundError: DriverExample' erhalten, enthält der 'CLASSPATH' nicht das aktuelle Verzeichnis, s.o.
  8. Falls Sie die Fehlermeldung 'Exception in thread "main" java.lang.VerifyError: (class: interbase/interclient/ErrorKey, method: _$372 ...' erhalten, beachten Sie bitte, dass nicht alle InterClient-Versionen zu allen Java-Versionen passen (siehe: http://community.borland.com/article/0,1410,27509,0.html).
  9. Falls Sie die Fehlermeldung '[interclient] Communication error ... "Connection refused: connect" ... SQL State: ICJE2' erhalten, läuft 'interserver.exe' nicht (siehe Taskmanager und s.o.).
  10. Falls Sie die Fehlermeldung 'no permission for read-write access to database' erhalten, haben Sie vielleicht keine Lese- oder Schreibrechte auf die .gdb-Datenbankdatei (z.B. von CD).
  11. Bei Problemen mit dem InterClient-JDBC-Treiber sollten Sie den Firebird/JayBird-JDBC-Treiber (z.B. 'firebirdsql-full.jar') probieren, siehe http://sourceforge.net/projects/firebird.
    Connection per Firebird/JayBird-JDBC-Treiber (siehe auch unten 'Programmierbeispiele'):
    Class.forName( "org.firebirdsql.jdbc.FBDriver" );
    cn = DriverManager.getConnection( "jdbc:firebirdsql://MyDbComputerNameOrIP/myDatabasePath/myDatabaseFile", dbUsr, dbPwd );

    Falls Sie das Beispiel '...\InterClient\examples\DriverExample.java' mit dem Firebird/JayBird-JDBC-Treiber testen wollen, ändern Sie zumindest Folgendes:
    1.) databaseURL = "jdbc:firebirdsql://localhost/C:/Programme/Borland/InterBase/examples/Database/employee.gdb";
    2.) driverName = "org.firebirdsql.jdbc.FBDriver";
    3.) An drei Stellen im Code (nicht in Kommentaren) muss geändert werden: "interbase.interclient.Driver" --> driverName

Anbindung an Sybase Adaptive Server Anywhere

  1. Sybase-JCONNECT-JDBC-Type-4-Treiber ('jconn2.jar', 900 KByte) laden von:
    http://downloads.sybase.com/swx.
  2. CLASSPATH muss JDBC-Treiber beinhalten.
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" );
    cn = DriverManager.getConnection( "jdbc:sybase:Tds:MyDbComputerNameOrIP:2638", dbUsr, dbPwd );

    (Default-Username/Password: "dba"/"sql")
  4. Alternativ kann eventuell auch das eigentlich für den Microsoft SQL Server vorgesehene jTDS versucht werden, siehe: http://jtds.sourceforge.net.

Anbindung an Microsoft SQL Server

  1. jTDS (basierend auf dem früheren FreeTDS) laden von:
    http://jtds.sourceforge.net.
  2. CLASSPATH muss JDBC-Treiber beinhalten.
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "net.sourceforge.jtds.jdbc.Driver" );
    cn = DriverManager.getConnection( "jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master", dbUsr, dbPwd );

  4. Alternativ kann auch der JDBC-Treiber von Microsoft verwendet werden, siehe http://www.microsoft.com/sql:
    JDBC-Treiber: 'mssqlserver.jar', 'msbase.jar', 'msutil.jar'
    Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
    cn = DriverManager.getConnection( "jdbc:microsoft:sqlserver://MyDbComputerNameOrIP:1433", dbUsr, dbPwd );

  5. Neuerdings steht mit 'sqljdbc_1.0.809.102_enu.exe' ein weiterer JDBC-Treiber von Microsoft zur Verfügung, siehe http://www.microsoft.com/downloads/details.aspx?FamilyID=e22bc83b-32ff-4474-a44a-22b6ae2c4e17&DisplayLang=en.

Anbindung per ODBC (z.B. für MS-Access)

  1. Java-Anwendungen sollten auf SQL-Datenbanken nicht per ODBC, sondern möglichst nur per direktem JDBC-Type-4-Treiber zugreifen. Ein Zugriff über die ODBC-JDBC-Bridge ist wesentlich aufwändiger und langsamer.
  2. Zur Einrichtung von ODBC und DSN siehe SQL-ODBC.
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
    Connection cn = DriverManager.getConnection( "jdbc:odbc:" + sDsn, dbUsr, dbPwd );



Programmierbeispiele


Einfaches Programmierbeispiel zum Auslesen einer Tabelle aus einer SQL-Datenbank

Voraussetzung für das folgende einfache Beispiel ist eine aktive SQL-Datenbank, die bereits eine Tabelle enthält. Anleitungen zum Anlegen einer Database und einer Tabelle finden Sie unter sql.htm, mysql.htm und postgresql.htm.
Der unten gezeigte Code muss in eine Datei 'DbTableShow.java' gespeichert werden und folgendermaßen compiliert und gestartet werden:

set classpath=.;<JdbcTreiberPfad>\<JdbcTreiberDatei>

javac DbTableShow.java

java DbTableShow

Das Programm erfragt dann die erforderlichen Parameter.

Alternativ können die Parameter auch direkt auf der Kommandozeile beim Aufruf übergeben werden:

set classpath=.;<JdbcTreiberPfad>\<JdbcTreiberDatei>

javac DbTableShow.java

java DbTableShow <TabellenName> <JdbcTreiberKlasse> <DatenbankUrl> <Benutzer> <Passwort>

(Falls Ihr Webbrowser Zeilen umgebrochen hat: Es müssen drei Zeilen eingegeben werden.)

<JdbcTreiberPfad> und <JdbcTreiberDatei> müssen Sie durch den Pfad und den Namen des zu Ihrer Datenbank passenden JDBC-Treibers ersetzen. <JdbcTreiberDatei> sollte ein JDBC-Type-4-Treiber sein und muss im Classpath enthalten sein.

<JdbcTreiberKlasse> muss durch den zur <JdbcTreiberDatei> passenden Treiber-Klassennamen ersetzt werden.

<DatenbankUrl> muss durch die URL-Adresse der Datenbank ersetzt werden.

<TabellenName> muss durch den Namen der in der Datenbank enthaltenen Tabelle ersetzt werden.

Eine konkrete Sequenz könnte für hSqlDb zum Beispiel folgendermaßen lauten:

set CLASSPATH=.;hsqldb.jar

java org.hsqldb.util.DatabaseManager -url "jdbc:hsqldb:file:C:/hSqlDbData/MeineDb"

javac DbTableShow.java

java xx DbTableShow org.hsqldb.jdbcDriver jdbc:hsqldb:file:C:/hSqlDbData/MeineDb sa

(Falls Ihr Webbrowser Zeilen umgebrochen hat: Es müssen vier Zeilen eingegeben werden.)

Für MySQL könnte eine konkrete Sequenz zum Beispiel folgendermaßen lauten:

set CLASSPATH=.;mysql-connector-java-5.1.16-bin.jar

javac DbTableShow.java

java DbTableShow MeineTestTabelle com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/MeineDb root mysqlpwd

(Falls Ihr Webbrowser Zeilen umgebrochen hat: Es müssen drei Zeilen eingegeben werden.)

Für viele weitere Datenbanken finden Sie Beispiele für <JdbcTreiberDatei>, <JdbcTreiberKlasse> und <DatenbankUrl> oben unter java-sql.htm#JDBC.


// DbTableShow.java

import java.io.*;
import java.sql.*;

public class DbTableShow
{
  public static void main( String[] args )
  {
    String dbTbl=null, dbDrv=null, dbUrl=null, dbUsr="", dbPwd="";
    if( args.length > 2 ) {
      dbTbl = args[0];
      dbDrv = args[1];
      dbUrl = args[2];
      if( args.length > 3 )  dbUsr = args[3];
      if( args.length > 4 )  dbPwd = args[4];
    } else {
      try {
        BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
        System.out.println( "Name der Tabelle eingeben (z.B. MeineTestTabelle):" );
        dbTbl = in.readLine();
        System.out.println( "Name des Datenbanktreibers eingeben (z.B. com.mysql.jdbc.Driver):" );
        dbDrv = in.readLine();
        System.out.println( "Url der Datenbank eingeben (z.B. jdbc:mysql://localhost:3306/MeineDb):" );
        dbUrl = in.readLine();
        System.out.println( "Benutzername (z.B. root):" );
        dbUsr = in.readLine();
        System.out.println( "Passwort (z.B. mysqlpwd):" );
        dbPwd = in.readLine();
      } catch( IOException ex ) {
        System.out.println( ex );
      }
    }
    showDbTable( dbTbl, dbDrv, dbUrl, dbUsr, dbPwd );
  }

  static void showDbTable( String dbTbl, String dbDrv, String dbUrl, String dbUsr, String dbPwd )
  {
    if( dbTbl == null || dbTbl.length() == 0 ||
        dbDrv == null || dbDrv.length() == 0 ||
        dbUrl == null || dbUrl.length() == 0 ) {
      System.out.println( "Fehler: Parameter fehlt." );
      return;
    }
    Connection cn = null;
    Statement  st = null;
    ResultSet  rs = null;
    try {
      // Select fitting database driver and connect:
      Class.forName( dbDrv );
      cn = DriverManager.getConnection( dbUrl, dbUsr, dbPwd );
      st = cn.createStatement();
      rs = st.executeQuery( "select * from " + dbTbl );
      // Get meta data:
      ResultSetMetaData rsmd = rs.getMetaData();
      int i, n = rsmd.getColumnCount();
      // Print table content:
      for( i=0; i<n; i++ )
        System.out.print( "+---------------" );
      System.out.println( "+" );
      for( i=1; i<=n; i++ )    // Attention: first column with 1 instead of 0
        System.out.print( "| " + extendStringTo14( rsmd.getColumnName( i ) ) );
      System.out.println( "|" );
      for( i=0; i<n; i++ )
        System.out.print( "+---------------" );
      System.out.println( "+" );
      while( rs.next() ) {
        for( i=1; i<=n; i++ )  // Attention: first column with 1 instead of 0
          System.out.print( "| " + extendStringTo14( rs.getString( i ) ) );
        System.out.println( "|" );
      }
      for( i=0; i<n; i++ )
        System.out.print( "+---------------" );
      System.out.println( "+" );
    } catch( Exception ex ) {
      System.out.println( ex );
    } finally {
      try { if( rs != null ) rs.close(); } catch( Exception ex ) {/* nothing to do*/}
      try { if( st != null ) st.close(); } catch( Exception ex ) {/* nothing to do*/}
      try { if( cn != null ) cn.close(); } catch( Exception ex ) {/* nothing to do*/}
    }
  }

  // Extend String to length of 14 characters
  static final String extendStringTo14( String s )
  {
    if( s == null ) { s = ""; }
    final String sFillStrWithWantLen = "              ";
    final int iWantLen = sFillStrWithWantLen.length();
    final int iActLen  = s.length();
    if( iActLen < iWantLen )
      return (s + sFillStrWithWantLen).substring( 0, iWantLen );
    if( iActLen > 2 * iWantLen )
      return s.substring( 0, 2 * iWantLen );
    return s;
  }
}

Ein weiteres ähnliches Beispiel finden Sie unter java-sql-csv-html.htm.



Einfaches Programmierbeispiel zum Auslesen einer Tabelle mit JSP

... gibt es in jsp-grundlagen.htm.



Binärdaten als BLOB (Binary Large Object) in SQL-Datenbanktabellen

Um Binärdaten (z.B. Bilder) in einer SQL-Datenbank zu speichern, muss die Tabellenspalte für das 'Binary Large Object' je nach SQL-Datenbank als BLOB, LONGBLOB, LONG RAW oder BYTEA definiert sein (siehe sql.htm#SQL-Datentypen).

Für MySQL zum Beispiel so:

CREATE TABLE MyTable ( Name VARCHAR PRIMARY KEY, MyImage BLOB );

Und für PostgreSQL 7.2 zum Beispiel so:

CREATE TABLE MyTable ( Name VARCHAR PRIMARY KEY, MyImage BYTEA );


Der folgende Code-Ausschnitt zeigt, wie beliebige Binärdaten in einer SQL-RDBMS gespeichert werden können. Es wird hier von einer Datei ausgegangen ('sFilePathAndName'). Stattdessen kann natürlich auch direkt ein Stream gespeichert werden. Im Beispiel ist noch keine Fehlerbehandlung implementiert.


  Class.forName( ... );
  Connection        dbCon = DriverManager.getConnection( ... );
  File              fl    = new File( sFilePathAndName );
  FileInputStream   fis   = new FileInputStream( fl );
  PreparedStatement pstmt = dbCon.prepareStatement(
                            "update MyTable set MyImage = ? where ..." );
  pstmt.setBinaryStream( 1, fis, (int)fl.length() );
  pstmt.executeUpdate();
  pstmt.close();
  dbCon.close();
  fis.close();

Der folgende Code-Ausschnitt zeigt, wie Binärdaten aus einer SQL-RDBMS geladen werden. Hier im Beispiel werden die Binärdaten in eine Datei gespeichert ('sFilePathAndName'). Stattdessen kann natürlich auch direkt der Stream verwertet werden, wie das Image-Beispiel weiter unten zeigt. Im Beispiel ist noch keine Fehlerbehandlung implementiert. Statt mit 'getBinaryStream()' kann bei den meisten Datenbanken (und Treibern) auch mit 'getBytes()' gelesen werden.


  Class.forName( ... );
  Connection dbCon = DriverManager.getConnection( ... );
  Statement  st    = dbCon.createStatement();
  ResultSet  rs    = st.executeQuery(
                     "select MyImage from MyTable where ..." );
  if( rs.next() )
  {
    InputStream      is  = rs.getBinaryStream( "MyImage" );
    FileOutputStream fos = new FileOutputStream( sFilePathAndName );
    byte[] buff = new byte[8192];
    int len;
    while( 0 < (len = is.read( buff )) )
      fos.write( buff, 0, len );
    fos.close();
    is.close();
  }
  rs.close();
  st.close();
  dbCon.close();


Programmierbeispiel zum Speichern einer Binärdatei als BLOB

Ein komplettes Programmierbeispiel zum Speichern von Binärdateien (z.B. Bildern) in eine Datenbank könnte folgendermaßen aussehen:

import java.io.*;
import java.sql.*;

public class DbImgStore
{
  public static void main( String[] args )
  {
    if( 9 != args.length ) {
      System.out.println(
        "Usage:\n" +
        "  java DbImgStore drv url usr pwd tbl keyColumn keyValue imgColumn imgFile\n" +
        "e.g.\n" +
        "  java DbImgStore com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/MeineDb" +
        " root mysqlpwd MeineAdressen Name Torsten Foto img/Torsten-Horn.jpg" );
      System.exit( 1 );
    }
    FileInputStream   fis = null;
    Connection        cn  = null;
    PreparedStatement st  = null;
    try {
      File fl = new File( args[8] );                                  // imgFile
      fis     = new FileInputStream( fl );
      Class.forName( args[0] );                                       // drv
      cn = DriverManager.getConnection( args[1], args[2], args[3] );  // url, usr, pwd
      // update tbl set imgColumn = 'imgFile?' where keyColumn = 'keyValue?':
      st = cn.prepareStatement( "update " + args[4] + " set " + args[7] +
                                " = ? where " + args[5] + " = ?" );
      st.setBinaryStream( 1, fis, (int)fl.length() );                 // imgFile
      st.setString( 2, args[6]  );                                    // keyValue
      st.executeUpdate();
      System.out.println( fl.length() + " Bytes successfully loaded." );
    } catch( Exception ex ) {
      System.out.println( ex );
    } finally {
      try { if( null != st  ) st.close();  } catch( Exception ex ) {/*ok*/}
      try { if( null != cn  ) cn.close();  } catch( Exception ex ) {/*ok*/}
      try { if( null != fis ) fis.close(); } catch( Exception ex ) {/*ok*/}
    }
  }
}

Programmierbeispiel zum Anzeigen als BLOB gespeicherter Bilder

Ein komplettes Programmierbeispiel zum Anzeigen in einer Datenbank als BLOB gespeicherter Bilder könnte folgendermaßen aussehen:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.sql.*;
import java.util.Vector;
import javax.imageio.ImageIO;

public class DbImgShow extends Frame
{
  public static void main( String[] args )
  {
    if( 6 != args.length ) {
      System.out.println(
        "Usage:\n" +
        "  java DbImgShow drv url usr pwd tbl imgColumn\n" +
        "e.g.\n" +
        "  java DbImgShow com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/MeineDb" +
        " root mysqlpwd MeineAdressen Foto" );
      System.exit( 1 );
    }
    new DbImgShow( args );
  }

  DbImgShow( String[] args )
  {
    setSize( 100, 100 );
    setVisible( true );
    add( new ImgShowCanvas( args ) );
    pack();
    addWindowListener(
      new WindowAdapter() {
        public void windowClosing( WindowEvent ev ) {
          dispose();
          System.exit( 0 ); } } );
  }
}

class ImgShowCanvas extends Canvas
{
  private String[]        ss;
  private BufferedImage[] imgs;

  ImgShowCanvas( String[] args )
  {
    Vector     vStr = new Vector();
    Vector     vImg = new Vector();
    Connection cn   = null;
    Statement  st   = null;
    ResultSet  rs   = null;
    try {
      Class.forName( args[0] );
      cn = DriverManager.getConnection( args[1], args[2], args[3] );
      st = cn.createStatement();
      rs = st.executeQuery( "select * from " + args[4] );
      while( rs.next() ) {
        InputStream is = rs.getBinaryStream( args[5] );
        if( null != is ) {
          vStr.add( rs.getString( 1  ) );
          vImg.add( ImageIO.read( is ) );
          try { is.close(); } catch( Exception ex ) {/*ok*/}
        }
      }
    } catch( Exception ex ) {
      System.out.println( ex );
    } finally {
      try { if( null != rs ) rs.close(); } catch( Exception ex ) {/*ok*/}
      try { if( null != st ) st.close(); } catch( Exception ex ) {/*ok*/}
      try { if( null != cn ) cn.close(); } catch( Exception ex ) {/*ok*/}
    }
    ss   = (String[])(vStr.toArray( new String[vStr.size()] ));
    imgs = (BufferedImage[])(vImg.toArray( new BufferedImage[vImg.size()] ));
  }

  public void paint( Graphics g )
  {
    int w = 0;
    g.drawString( "Error", 30, 40 );
    for( int i=0; i<ss.length && i<imgs.length; i++ ) {
      g.drawString( ss[i], w, 15 );
      g.drawImage( imgs[i], w, 20, this );
      w += imgs[i].getWidth( this );
    }
  }

  public Dimension getPreferredSize()
  {
    int w=0, h=80;
    for( int i=0; i<imgs.length; i++ ) {
      w += imgs[i].getWidth( this );
      h  = Math.max( h, imgs[i].getHeight( this ) );
    }
    w  = Math.max( w, 100 );
    h += 20;
    return new Dimension( w, h );
  }

  public Dimension getMinimumSize()
  {
    return getPreferredSize();
  }
}


Weiterführende Informationen





Weitere Themen: andere TechDocs | JSP | Hibernate | SQL | MySQL | PostgreSQL | Webanwendungen
© 1998-2007 Torsten Horn, Aachen