Heute gibt es eine kleine Erweiterung zu unserem Artikel „Oracle-DB mit Java einbinden“, in dem die Vorgehensweise beschrieben wird, wie man eine Verbindung zwischen einer IBM Notes-und einer Oracle-Datenbank aufbaut.
Im heutigen Beitrag gehe ich auf zwei spezielle Datentypen einer Oracle-Datenbank ein, den Blob und den Clob, und darauf, wie man die in ihnen enthaltenen Daten in einer Notes-Datenbank ablegt.
- Der Blob (Binary Large Object) wird in der Regel verwendet, um ganze Dateien in Form eines BinaryStreams in der Datenbank abzulegen.
- Der Clob (Character Large Object) ist - wie der Name schon sagt - für beliebig große Zeichenketten gedacht.
Beide Feldtypen benötigen allerdings eine leicht gesonderte Behandlung, um sie in eine Notes-Datenbank zu übertragen.
Als Erstes widme ich mich dem Blob:
Ich gehe in diesem Beispiel davon aus das die Datentabelle in der Oracle-Datenbank folgendermaßen konfiguriert ist:

Abb. 1: Aufbau einer Datentabelle in der Oracle-Datenbank
Der folgende Java-Agent erstellt pro Zeile, der Oracle-Datenbanktabelle ein Notes-Dokument, in welches die Daten der Zeile eingetragen werden.
import lotus.domino.*;
import java.io.*;
import java.sql.*;
import oracle.jdbc.internal.OracleResultSet;
import oracle.sql.BLOB;
import de.itwu.xKernel.base.ITOBinderElement;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
Database curdb = session.getCurrentDatabase();
//**1** Verbindung zur Oracle-Datenbank aufbauen
Class.forName("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521/SID", "USER","PASSWORT");
conn.setAutoCommit(false);
//**2** Datensätze aus Oracle anfordern
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("select * from TABELLE order by id");
//**3** Durchlaufen der Datensätze aus Oracle
while (rset.next()) {
try {
//**4** Neues Notesdokument erzeugen
Document newdoc = curdb.createDocument();
newdoc.replaceItemValue("form", "Bild");
newdoc.replaceItemValue("pic_Name", rset.getString("Name"));
newdoc.replaceItemValue("pic_MimeType", rset.getString("MimeType"));
//**5** Pro Tabellenzeile einen Unterordner erzeugen
String Filename = "C:\\Temp\\"+rset.getString("ID")+"\\" + rset.getString("Name");
File dir = new File("C:\\Temp\\"+rset.getString("ID")+"\\");
dir.mkdir();
//**6** Blob aus dem Oracle-Datensatz lesen und auf der Festplatte ablegen
readBLOBToFileStream(((OracleResultSet) rset).getBLOB("Bild"), Filename);
//**10** Datei in ein Richtextitem einfügen
RichTextItem rtitem = newdoc.createRichTextItem("pic_BildDatei");
rtitem.embedObject(EmbeddedObject.EMBED_ATTACHMENT, null,
Filename, rset.getString("Name"));
newdoc.save();
newdoc.recycle();
} catch (Exception e) {
System.out.println("Fehler bei ID " + rset.getString("ID"));
e.printStackTrace();
}
finally
{
System.gc();
}
}
stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void readBLOBToFileStream(BLOB blobdata, String Filename) throws IOException, SQLException
{
File outputBinaryFile = null;
FileOutputStream outputFileOutputStream = null;
InputStream blobInputStream = null;
int chunkSize;
byte[] binaryBuffer;
int bytesRead = 0;
int totBytesRead = 0;
int totBytesWritten = 0;
try {
//**7** Neue Datei erzeugen
outputBinaryFile = new File(Filename);
//**8** OutputStream erzeugen
outputFileOutputStream = new FileOutputStream(outputBinaryFile);
blobInputStream = blobdata.getBinaryStream();
//**9** Byteweise Daten des Blobs in Datei schreiben
chunkSize = blobdata.getChunkSize();
binaryBuffer = new byte[chunkSize];
while ((bytesRead = blobInputStream.read(binaryBuffer)) != -1) {
outputFileOutputStream.write(binaryBuffer, 0, bytesRead);
totBytesRead += bytesRead;
totBytesWritten += bytesRead;
}
outputFileOutputStream.close();
blobInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Erläuterungen:
- Als Erstes muss der JDBC-Treiber geladen werden. Dazu benutzen wir die Funktion "Class.forName". Diese sucht den passenden Treiber aus der Laufzeitumgebung aus. Anschließend bauen wir mit "DriverManager.getConnection" die JDBC-Verbindung auf. Die IP-Adresse sowie SID, USER und PASSWORD sind natürlich durch die entsprechenden tatsächlichen Werte zu ersetzen. Ggf. ist auch der Port anzupassen (1521).
- Hier wird das SQL-Query definiert. Das hier angegebene Query ist natürlich nur als Beispiel zu verstehen. Anschließend wird mithilfe eines Statements und des "ResultSet" das Query ausgeführt.
- Das "ResultSet" wird mit einer while-Schleife durchlaufen, um die Ergebnisse auszulesen.
- Nun erzeugen wir uns in der Notes-Datenbank ein Notesdocument in das wir ein paar Daten eintragen.
- Wir legen für jede Tabellenzeile einen Ordner an (damit wir uns keine Dateien überschreiben), um im Anschluss die Datei aus dem Blob dort abzulegen.
- Nun wird die Methode readBLOBToFileStream mit dem Blob aus der Tabellenzeile und dem Dateinamen aufgerufen.
- Als Erstes legen wir mit dem Dateinamen eine neue Datei an.
- Nun initialisieren wir einen OutputStream mit der Datei und einen InputStream mit den Daten aus dem Blob.
- Im Anschluss werden alle Daten des InputStreams in den OutputStream bzw. in die Datei übertragen.
- Jetzt wird ein RichtextItem im Notesdocument angelegt und die zuvor erzeugte Datei angehängt.
Nun zu den Clobs:
Um Clobs, in meinem Fall einen beliebig langen Text, auszulesen, habe ich den Weg über den BufferedReader und StringBuffer gewählt.
Der Clob wird also mit Hilfe eines BufferedReaders in einen StringBuffer übertragen, wodurch er im Anschluss als normaler String abgegriffen werden kann:
public String ClobToString(Clob clobData)
{
//**1** Prüfen, ob der Clob nicht leer ist
if(clobData != null)
{
BufferedReader br = new BufferedReader(clobData.getCharacterStream());
String aux;
StringBuffer strOut = new StringBuffer();
//**2**Zeilenweise die Daten des Clobs in den StringBuffer übertragen
while ((aux = br.readLine()) != null) {
strOut.append(aux);
strOut.append(System.getProperty("line.separator"));
}
}
return strOut.toString());
}
Erläuterungen:
- Als Erstes prüfen wir, ob der Clob Daten enthält.
- Nun übertragen wir zeilenweise den Text des Clobs in einen StringBuffer und geben ihn als normalen Java String zurück.
Der Methodenaufruf könnte folgendermaßen ausehen:
...
document.replaceItemValue("CBLOBFELD", this.ClobToString(RESULTSET.getClob("CBLOBFELD")));
...
Mit diesen Methoden könnt ihr also auch Daten aus Blobs und Clobs in einer Notes-Datenbank nutzbar machen.
Wenn euch noch andere Stolperfallen bei der Verbindung zwischen Oracle- und Notes-Datenbanken über den Weg laufen, schreibt sie uns doch bitte in die Kommentare.