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. InterBase und Firebird
    7. Oracle
    8. DB2
    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://java.sun.com/products/jdbc.

In den meisten Fällen sind JDBC-Type-4-Treiber optimal. Sie sind sehr schnell und sehr einfach zu installieren. Die Unterschiede zwischen den JDBC-Typen sind erklärt unter http://java.sun.com/products/jdbc/driverdesc.html.

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://java.sun.com/products/jdbc/articles/package2.html und http://java.sun.com/products/jdbc/jdbc20.stdext.javadoc.


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 (eventuell reicht Kopieren nach '%JAVA_HOME%\jre\lib\ext').
  4. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "org.hsqldb.jdbcDriver" );
    cn = DriverManager.getConnection( "jdbc:hsqldb:file:C:/hSqlDbData/MeineDb", "sa", sPwd );

    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.11-bin.jar' aus 'mysql-connector-java-5.1.11.zip') downloaden von: http://www.mysql.com.
  3. CLASSPATH muss JDBC-Treiber beinhalten (eventuell reicht Kopieren nach '%JAVA_HOME%\jre\lib\ext').
  4. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "com.mysql.jdbc.Driver" );
    cn = DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName", sUsr, sPwd );


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 (eventuell reicht Kopieren nach '%JAVA_HOME%\jre\lib\ext').
  4. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "org.postgresql.Driver" );
    cn = DriverManager.getConnection( "jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName", sUsr, sPwd );


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 (eventuell reicht Kopieren von 'interclient.jar' nach '%JAVA_HOME%\jre\lib\ext').
    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", sUsr, sPwd );

    getConnection-Beispiel für Windows:
    cn = DriverManager.getConnection( "jdbc:interbase://MyServer/C:/InterBase-Data/MyDbFile.gdb", sUsr, sPwd );
    getConnection-Beispiel für Linux:
    cn = DriverManager.getConnection( "jdbc:interbase://MyServer//usr/local/InterBase-Data/MyDbFile.gdb", sUsr, sPwd );
  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", sUsr, sPwd );

    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 Oracle

  1. Oracle-JDBC-Type-4-Treiber laden von:
    http://www.oracle.com/technology//software/tech/java/sqlj_jdbc
    "Oracle8i JDBC Drivers for use with JDK 1.2.x"
    "JDBC-Thin, 100% Java ('classes12.zip')".
  2. Datei 'classes12.zip' nicht entzippen, sondern:
    CLASSPATH muss Oracle-JDBC-Treiber beinhalten:
    set CLASSPATH=<...>\classes12.zip
    (eventuell reicht Kopieren des JDBC-Treibers nach '%JAVA_HOME%\jre\lib\ext').
  3. Connection-Url nach dem Schema 'drivername@HostName_or_IP:port:sid' (siehe auch unten 'Programmierbeispiele'):
    Class.forName( "oracle.jdbc.driver.OracleDriver" );
    cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd );


Anbindung an DB2

  1. JDBC-Treiber: 'db2java.zip'
  2. CLASSPATH muss JDBC-Treiber beinhalten (eventuell reicht Kopieren nach '%JAVA_HOME%\jre\lib\ext').
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "COM.ibm.db2.jdbc.app.DB2Driver" );
    cn = DriverManager.getConnection( "jdbc:db2:myDatabaseName", sUsr, sPwd );

DB2/400 auf AS/400 (iSeries):

  1. JDBC-Treiber: 'jt400-5.4.0.2.jar'. Siehe: http://jt400.sourceforge.net, http://www-03.ibm.com/servers/eserver/iseries/toolbox, .../faqjdbc.html, .../modsreleases.html.
  2. CLASSPATH muss JDBC-Treiber beinhalten (eventuell reicht Kopieren nach '%JAVA_HOME%\jre\lib\ext').
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "com.ibm.as400.access.AS400JDBCDriver" );
    cn = DriverManager.getConnection( "jdbc:as400://MyDbComputerNameOrIP/MyName", sUsr, sPwd );

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

  1. 'jt400-5.4.0.2.jar', 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

DB2-Dokus:


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 (eventuell reicht Kopieren nach '%JAVA_HOME%\jre\lib\ext').
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" );
    cn = DriverManager.getConnection( "jdbc:sybase:Tds:MyDbComputerNameOrIP:2638", sUsr, sPwd );

    (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 (eventuell reicht Kopieren nach '%JAVA_HOME%\jre\lib\ext').
  3. Connection (siehe unten 'Programmierbeispiele'):
    Class.forName( "net.sourceforge.jtds.jdbc.Driver" );
    cn = DriverManager.getConnection( "jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master", sUsr, sPwd );

  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", sUsr, sPwd );

  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, sUsr, sPwd );



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 <JdbcTreiberKlasse> <DatenbankUrl> <TabellenName> <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=.;C:\Program Files\Java\jdk1.6\jre\lib\ext\hsqldb.jar

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

javac DbTableShow.java

java DbTableShow org.hsqldb.jdbcDriver jdbc:hsqldb:file:C:/hSqlDbData/MeineDb xx 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=.;C:\Program Files\Java\jdk1.6\jre\lib\ext\mysql-connector-java-5.1.11-bin.jar

javac DbTableShow.java

java DbTableShow com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/MeineDb MeineTestTabelle 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[] argv )
  {
    String sDbDrv=null, sDbUrl=null, sTable=null, sUsr="", sPwd="";
    if( 3 <= argv.length ) {
      sDbDrv = argv[0];
      sDbUrl = argv[1];
      sTable = argv[2];
      if( 4 <= argv.length )  sUsr = argv[3];
      if( 5 <= argv.length )  sPwd = argv[4];
    } else {
      try {
        BufferedReader in = new BufferedReader(
                            new InputStreamReader( System.in ) );
        System.out.println( "Name des Datenbanktreibers eingeben (z.B. com.mysql.jdbc.Driver):" );
        sDbDrv = in.readLine();
        System.out.println( "Url der Datenbank eingeben (z.B. jdbc:mysql://localhost:3306/MeineDb):" );
        sDbUrl = in.readLine();
        System.out.println( "Name der Tabelle eingeben (z.B. MeineTestTabelle):" );
        sTable = in.readLine();
        System.out.println( "Benutzername (z.B. root):" );
        sUsr = in.readLine();
        System.out.println( "Passwort (z.B. mysqlpwd):" );
        sPwd = in.readLine();
      } catch( IOException ex ) {
        System.out.println( ex );
      }
    }
    if( null != sDbDrv && 0 < sDbDrv.length() &&
        null != sDbUrl && 0 < sDbUrl.length() &&
        null != sTable && 0 < sTable.length() ) {
      Connection cn = null;
      Statement  st = null;
      ResultSet  rs = null;
      try {
        // Select fitting database driver and connect:
        Class.forName( sDbDrv );
        cn = DriverManager.getConnection( sDbUrl, sUsr, sPwd );
        st = cn.createStatement();
        rs = st.executeQuery( "select * from " + sTable );
        // 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( null != rs ) rs.close(); } catch( Exception ex ) {}
        try { if( null != st ) st.close(); } catch( Exception ex ) {}
        try { if( null != cn ) cn.close(); } catch( Exception ex ) {}
      }
    }
  }

  // Extend String to length of 14 characters
  private static final String extendStringTo14( String s )
  {
    if( null == s ) 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 ) {}
      try { if( null != cn  ) cn.close();  } catch( Exception ex ) {}
      try { if( null != fis ) fis.close(); } catch( Exception ex ) {}
    }
  }
}

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 ) {}
        }
      }
    } catch( Exception ex ) {
      System.out.println( ex );
    } finally {
      try { if( null != rs ) rs.close(); } catch( Exception ex ) {}
      try { if( null != st ) st.close(); } catch( Exception ex ) {}
      try { if( null != cn ) cn.close(); } catch( Exception ex ) {}
    }
    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