Sergio:
Powinieneś użyć BLOBa . Z JDBC jest to całkiem proste.
Problem z drugim opublikowanym kodem dotyczy kodowania. Powinieneś dodatkowo zakodować bajty, aby upewnić się, że żaden z nich nie zawiedzie.
Jeśli nadal chcesz zapisać go w łańcuchu, możesz zakodować bajty za pomocą java.util.Base64 .
Nadal powinieneś używać CLOB jako typu danych, ponieważ nie wiesz, jak długo będą zserializowane dane.
Oto przykład, jak go używać.
import java.util.*;
import java.io.*;
/**
* Usage sample serializing SomeClass instance
*/
public class ToStringSample {
public static void main( String [] args ) throws IOException,
ClassNotFoundException {
String string = toString( new SomeClass() );
System.out.println(" Encoded serialized version " );
System.out.println( string );
SomeClass some = ( SomeClass ) fromString( string );
System.out.println( "\n\nReconstituted object");
System.out.println( some );
}
/** Read the object from Base64 string. */
private static Object fromString( String s ) throws IOException ,
ClassNotFoundException {
byte [] data = Base64.getDecoder().decode( s );
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream( data ) );
Object o = ois.readObject();
ois.close();
return o;
}
/** Write the object to a Base64 string. */
private static String toString( Serializable o ) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream( baos );
oos.writeObject( o );
oos.close();
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
}
/** Test subject. A very simple class. */
class SomeClass implements Serializable {
private final static long serialVersionUID = 1; // See Nick's comment below
int i = Integer.MAX_VALUE;
String s = "ABCDEFGHIJKLMNOP";
Double d = new Double( -1.0 );
public String toString(){
return "SomeClass instance says: Don't worry, "
+ "I'm healthy. Look, my data is i = " + i
+ ", s = " + s + ", d = " + d;
}
}
Wynik:
C:\samples>javac *.java
C:\samples>java ToStringSample
Encoded serialized version
rO0ABXNyAAlTb21lQ2xhc3MAAAAAAAAAAQIAA0kAAWlMAAFkdAASTGphdmEvbGFuZy9Eb3VibGU7T
AABc3QAEkxqYXZhL2xhbmcvU3RyaW5nO3hwf////3NyABBqYXZhLmxhbmcuRG91YmxlgLPCSilr+w
QCAAFEAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cL/wAAAAAAAAdAAQQUJ
DREVGR0hJSktMTU5PUA==
Reconstituted object
SomeClass instance says: Don't worry, I'm healthy. Look, my data is i = 2147483647, s = ABCDEFGHIJKLMNOP, d = -1.0
UWAGA : w przypadku Java 7 i wcześniejszych oryginalną odpowiedź można znaleźć tutaj
serialVersionUID
doSomeClass
ochroni przed dodawaniem nowych pól, ale jeśli pola zostaną usunięte, będziesz miał wkręty. Warto przeczytać, co na ten temat ma do powiedzenia Joshua Bloch w Effective Java - books.google.co.uk/…Co powiesz na zapisanie danych do ByteArrayOutputStream zamiast do FileOutputStream?
W przeciwnym razie możesz serializować obiekt za pomocą XMLEncoder, utrwalić XML, a następnie deserializować za pomocą XMLDecoder.
źródło
Dzięki za świetne i szybkie odpowiedzi. Natychmiast zrezygnuję z niektórych głosów, aby podziękować za pomoc. Zakodowałem najlepsze moim zdaniem rozwiązanie na podstawie Twoich odpowiedzi.
Uwaga: nie rozważałem używania JSON, ponieważ jest mniej wydajny.
Uwaga: Rozważę twoją radę, aby nie przechowywać zserializowanego obiektu jako ciągów w bazie danych, ale zamiast tego jako bajt [].
źródło
Podejście Java8, konwertowanie Object z / na String, zainspirowane odpowiedzią z OscarRyz . Do dekodowania / kodowania wymagany jest i używany plik java.util.Base64 .
źródło
XStream zapewnia proste narzędzie do serializacji / deserializacji do / z XML i jest bardzo szybkie. Przechowywanie XML CLOB zamiast binarnych BLOBS będzie mniej kruche, nie wspominając o bardziej czytelnym.
źródło
Co powiesz na utrwalanie obiektu jako obiektu blob
źródło
Jeśli przechowujesz obiekt jako dane binarne w bazie danych, to naprawdę powinieneś użyć
BLOB
typu danych. Baza danych jest w stanie przechowywać ją wydajniej i nie musisz martwić się o kodowanie i tym podobne. JDBC udostępnia metody tworzenia i pobierania obiektów blob w postaci strumieni. Jeśli możesz, korzystaj z języka Java 6, ponieważ wprowadził on pewne dodatki do interfejsu API JDBC, które znacznie ułatwiają obsługę obiektów blob.Jeśli absolutnie potrzebujesz przechowywać dane jako String, poleciłbym XStream do przechowywania opartego na XML (znacznie łatwiejsze niż
XMLEncoder
), ale alternatywne reprezentacje obiektów mogą być równie przydatne (np. JSON). Twoje podejście zależy od tego, dlaczego faktycznie musisz przechowywać obiekt w ten sposób.źródło
Przyjrzyj się klasie java.sql.PreparedStatement, a konkretnie funkcji
http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html#setBinaryStream(int,%20java.io.InputStream)
Następnie przyjrzyj się klasie java.sql.ResultSet, a konkretnie funkcji
http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html#getBinaryStream(int)
Pamiętaj, że jeśli serializujesz obiekt do bazy danych, a następnie zmienisz obiekt w kodzie w nowej wersji, proces deserializacji może łatwo zakończyć się niepowodzeniem, ponieważ zmieniła się sygnatura obiektu. Kiedyś popełniłem ten błąd, przechowując niestandardowe serializowane preferencje, a następnie wprowadzając zmiany w definicji preferencji. Nagle nie mogłem odczytać żadnej z wcześniej zserializowanych informacji.
Lepszym rozwiązaniem może być pisanie niezgrabnych kolumn właściwości w tabeli oraz komponowanie i dekomponowanie obiektu w ten sposób, aby uniknąć tego problemu z wersjami obiektów i deserializacją. Lub zapisanie właściwości w jakiejś tablicy hashmapy, takiej jak obiekt java.util.Properties, a następnie serializacja obiektu properties, co jest bardzo mało prawdopodobne, aby się zmienił.
źródło
Zserializowany strumień to po prostu sekwencja bajtów (oktetów). Zatem pytanie brzmi, jak przekonwertować sekwencję bajtów na łańcuch i z powrotem. Ponadto musi użyć ograniczonego zestawu kodów znaków, jeśli ma być przechowywany w bazie danych.
Oczywistym rozwiązaniem problemu jest zmiana pola na binarny LOB. Jeśli chcesz trzymać się znaku LOB, musisz zakodować w jakimś schemacie, takim jak base64, hex lub uu.
źródło
Możesz użyć kompilacji w klasach sun.misc.Base64Decoder i sun.misc.Base64Encoder, aby przekonwertować dane binarne serializacji na ciąg. Nie potrzebujesz dodatkowych klas, ponieważ są wbudowane.
źródło
możesz użyć UUEncoding
źródło
Proste rozwiązanie, zadziałało dla mnie
źródło
Użyj struktury O / R, takiej jak hibernacja
źródło