Java 中 Blob 和 String 之間的轉換
1. 概述
在 Java 中, Blob和String之間的轉換通常會先將資料轉換為位元組數組。 java.sql.Blob java.sql.Blob通常用於與關聯式資料庫互動。最關鍵的細節是在位元組數組和String之間轉換時指定字元編碼(例如 UTF-8),以防止資料損壞,尤其是在處理非 ASCII 字元時。
本教程涵蓋了將 Java String轉換為java.sql.Blob物件以及反向轉換的實用方法的實作和測試。當需要將文字資料(尤其是多位元組字串)持久化到旨在儲存二進位大型物件 (BLOB) 的資料庫列中時,這是一個常見的需求。我們使用 UTF-8 字元集以確保完全支援標準 ASCII 字元和特殊/國際字元。
2. Maven 安裝
要使用提供的 JUnit 5 測試類,我們需要在pom.xml中包含 JUnit Jupiter API 和引擎相依性。轉換工具本身僅依賴標準的 JDK 類別:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
</dependencies>
3. 將Blob轉換為String
要將Blob轉換為String ,我們從Blob物件讀取位元組內容,並使用 UTF-8 編碼將其轉換回 Java String 。
blobToString方法可以處理null的Blob對象,並且會檢查 Blob 物件是否過大(大於Integer.MAX_VALUE位元組),以防止轉換錯誤,因為Blob.getBytes()需要int長度。此方法傳回Blob資料的String表示形式:
public static String blobToString(Blob blob) throws SQLException {
if (blob == null) {
return null;
}
long length = blob.length();
if (length == 0) {
return "";
}
if (length > Integer.MAX_VALUE) {
throw new SQLException("Blob is too large for a single String conversion.");
}
byte[] bytes = blob.getBytes(1, (int) length);
return new String(bytes, StandardCharsets.UTF_8);
}
首先,我們檢查長度是否為零,以避免出現「 SerialException :參數無效」錯誤。據此,我們將整個Blob內容取得為一個位元組數組,起始位置從1開始。然後,我們使用 UTF-8 字元集將該位元組數組轉換為String 。如果發生資料庫存取錯誤,此方法將拋出SQLException 。
4. 將String轉換為Blob
要將String轉換為Blob ,我們首先使用 UTF-8 編碼將String轉換為位元組數組。然後,我們將位元組陣列包裝在SerialBlob物件中,SerialBlob 物件是Blob的一個具體、可序列化的實作。
stringToBlob方法將 Java String轉換為java.sql.Blob :
public static Blob stringToBlob(String text) throws SQLException {
if (text == null) {
return null;
}
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
return new SerialBlob(bytes);
}
請注意,即使輸入空字串(“”),此方法也是安全的,因為空字串會傳回長度為零的位元組數組。如果發生資料庫存取錯誤,此方法會拋出SQLException 。
5. 雙向轉換測試
接下來,我們針對各種輸入驗證雙向轉換( String -> Blob -> String ),以確保資料完整性和正確處理邊界情況。
5.1. 轉換標準 ASCII String
我們首先使用一個標準的 ASCII String ,將其轉換為Blob對象,然後再將Blob轉換回String物件。我們透過比較原始String和由Blob轉換回String來驗證String到Blob轉換是否正確:
@Test
void givenStandardAsciiString_whenPerformingConversion_thenConversionSuccessful()
throws SQLException {
String originalString = "Hello, world!";
Blob blob = BlobStringConverter.stringToBlob(originalString);
assertNotNull(blob);
String convertedString = BlobStringConverter.blobToString(blob);
assertEquals(originalString, convertedString);
}
請注意,我們也會驗證從String轉換而來的Blob是否不null 。
5.2. 轉換包含特殊字元的String
這次,我們從一個包含特殊字元(例如,國際字元、表情符號)的String開始。這項關鍵測試驗證了 UTF-8 編碼/解碼是否能正確處理多字節字符,避免資料遺失或損壞。我們首先來看一個包含非 ASCII 字元(例如,日語、德語變音符號)的範例String :
@Test
void givenStringWithSpecialCharacters_whenPerformingConversion_thenConversionSuccessful()
throws SQLException {
String originalString = "Test: こんにちは, äöü";
Blob blob = BlobStringConverter.stringToBlob(originalString);
String convertedString = BlobStringConverter.blobToString(blob);
assertEquals(originalString, convertedString);
}
請注意,我們再次做出相同的斷言,即原始String等於轉換後的String 。
5.3. 轉換空String
讓我們從一個空String開始,將其轉換為Blob ,然後再轉換回String :
@Test
void givenEmptyString_whenPerformingConversion_thenConversionSuccessful() throws SQLException {
String originalString = "";
Blob blob = BlobStringConverter.stringToBlob(originalString);
String convertedString = BlobStringConverter.blobToString(blob);
assertEquals(originalString, convertedString);
}
請注意,為了使assertEquals測試通過,空字串(“”)必須轉換為零長度的Blob ,然後再轉換回空String 。
5.4. 轉換null String
讓我們從一個null String開始,將其轉換為Blob ,然後再將Blob轉換回String :
@Test
void givenNullString_whenPerformingConversion_thenConversionSuccessful() throws SQLException {
assertNull(BlobStringConverter.stringToBlob(null),
"stringToBlob should return null for null input.");
assertNull(BlobStringConverter.blobToString(null),
"blobToString should return null for null input.");
}
此測試證實,對於任一轉換方法, null輸入都會導致null輸出,能夠正確處理資料庫中的null值。
6. 結論
本文探討如何將Blob轉換為String ,以及如何將String轉換為Blob 。透過始終使用 UTF-8 編碼,我們可以可靠地在 Java String物件和java.sql.Blob物件之間進行雙向轉換。此外,我們還測試了各種字元的轉換,並正確處理了諸如null和空輸入等特殊情況。
與往常一樣,範例的完整程式碼可在 GitHub 上找到。