Illustration einer tropischen Insel mit Palmen und einem hohen Berg

Java Blog für Programmierer

Ein paar (F)AQs, Teil 2

· Christian Ullenboom

Wie kann man in Java einzelne Strings de/komprimieren. So wie man es in einem Zip-File machen kann nur eben ohne Zip.

Nehme ein String und trage es in einen ByteArray[Output|Input]Stream ein. Dann nehme den GZIPOutputStream/..InputStream und komprimiere den String in einen ByteArrayXXXStream. Diesen kannst du dann wieder zu einem Bytefeld konvertieren.

Kennt jemand eine einfache Möglichkeit in Java Dateien zu kürzen?

Du kannst eine Datei kürzen, indem du von RandomAccessFile die setLength() Methode nutzt. Leider kann man vorne keine Blöcke ausschneiden (und das möchte man ja eigentlich).

Ich möchte gerne mit JDOM ein XML-Dokument ohne Attribute ausgeben. Gibt es eine Möglichkeit, das mit dem Outputter einfach zu realisieren?

Baue eine Unterklasse von XMLOutputter. Dann kann man schön das Template-Pattern in Anwendung sehen, in dem man die Methode printAttributes() leer lässt:

protected void printAttributes( Writer out, List attributes,
                                Element parent, NamespaceStack namespaces)
  throws IOException { }

Anstatt dann den XMLOutputter einfach die eigene Klasse nehmen.

Der SAX Parser parst doch sequentiell immer die folgende Reihenfolge 1. startDocument(), 2. startElement(), 3. characters(), 4. endElement(), 5. endDocument(), oder?

Durch Character-Chunking kann characters() auch öfters hintereinander aufgerufen werden. Siehe dazu /blog/javainsel/2007/01/character-%E2%80%9Echunking%E2%80%9C-bei-sax/. So etwas wie processingInstruction() kann natürlich auch noch kommen.

Ich würde gerne aus einer MySQL-Datenbank jeweils eine Zeile auslesen, manche Spalten davon bearbeiten und letztendlich alles wieder in eine andere Datenbank schreiben. Im Moment sieht’s ungefähr so aus: a) Verbindung zur Datenbank, b) ResultSet holen, c) Zeile verarbeiten und was machen. Jetzt hab ich aber beim Einlesen schon ein Problem. Ich bekomme bei dem ResultSet (mit "SELECT * FROM DB") einen Speicherüberlauf. Die Datenbank besteht aus mehreren 100.000 Zeilen und ich weiß leider nicht, wie ich das sonst lösen sollte. Kann man zum Beispiel das ResultSet begrenzen? Also beispielsweise immer wieder 1000 Zeilen lesen oder so? Oder gibt’s noch eine elegantere Lösung?

MySQL kennt leider kein echtes Cursor-Konzept (früherer jedenfalls), sodass der JDBC-Treiber alle Daten auf die Client-Seite überträgt. Mit dieser Technik muss die Datenbank nicht gelockt werden und muss keine Transaktionen unterstützten. Das löst auf einfache Weise ein Problem wie: Der Abholer braucht 10 Stunden für das Lesen, die Tabelle wird aber beschrieben. Kopiert man alles, muss die Datenbank nur für die Übertragung gelockt werden. Schöne Optimierung-Parameter wie fetch-size oder so sind da völlig wertlos. Hier helfen

Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE );

// SENSITIVE ode INSENSITIVE gut überlegen

ResultSet uprs = stmt.executeQuery( "SELECT Bla FROM Blub" );

// Auf die passende Zeile steuern, dann etwa

uprs.updateFloat( "Groesse", 183f );
uprs.updateRow();

Warum bekomme ich bei Hibernate mit session.load(clazz, x) bei Sammlungen ein PersistentSet und kein normales Set?

Der Grund ist einfach: Hibernate verwaltet eine eigenes Set, um Lazy-Loading zu ermöglichen. Ist Lazy-Loading bei 1:n:-Assoziationen eingestellt (Standard), dann wird die Sammlung erst dann geladen, wenn es einen Zugriff auf die Sammlung gibt (Anfragen, add(), …). Der Punkt ist nun: Wie sollte ein Persistence-Provider mitbekommen, dass jmd. nun Daten aus der Sammlung lesen will? Daher fängt das PersistentSet (http://www.hibernate.org/hib\_docs/v3/api/org/hibernate/collection/PersistentSet.html) von Hibernate als Proxy die Anfragen ab (PersistentSet ist ein waschechtes java.util.Set) und kann so vor dem tatsächlichen Zugriff auf die Sammlung die Daten schnell laden.

Übrigens hat man in der JPA auch nur die Basis-Collection-Schnittstellen wie Set, List, … aber keine konkreten Klassen wie HashSet, TreeSet,… Die PersistentSet-Doku schreibt aber: "The underlying collection is a HashSet."

Mit Hilfe des Parameters -exclude kann man bei Javadoc komplette Pakete von der Dokumentation ausschließen. Nun möchte ich allerdings nur einzelne Klassen innerhalb eines Pakets ausschließen. Ist das irgendwie möglich?

Wenn du ant (http://ant.apache.org/manual/CoreTasks/javadoc.html) benutzt, schau dir doch mal das FileSet (http://ant.apache.org/manual/CoreTypes/fileset.html) an.

Damit sollte das gehen, etwa so:

Kategorien: Allgemein

← Alle Beiträge