當需要將大文本文件、日誌、XML/JSON 文檔等流式數據寫入數據庫 CLOB、TEXT、LONGVARCHAR 類型字段時,setAsciiStream 避免了將整個內容載入內存再轉為 String,實現流式傳輸、零拷貝、低內存佔用。
// PreparedStatement 方法簽名
void setAsciiStream(int parameterIndex, InputStream x, int length)
void setAsciiStream(int parameterIndex, InputStream x, long length) // JDBC 4.2+
void setAsciiStream(int parameterIndex, InputStream x) // JDBC 4.0+,無需指定長度
parameterIndex:佔位符位置(從 1 開始)x:ASCII 字符輸入流length:流長度(字節數),幫助數據庫優化存儲分配配套方法:setBinaryStream(二進制/BLOB)、setCharacterStream(字符/CLOB)、setUnicodeStream(已棄用)。
import java.io.*;
import java.sql.*;
public class ClobStreamInsertDemo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&characterEncoding=utf8";
String user = "root";
String password = "123456";
String sql = "INSERT INTO documents (title, content, created_at) VALUES (?, ?, NOW())";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement(sql);
FileInputStream fis = new FileInputStream("data/large_document.txt")) {
// 1. 設置普通參數
ps.setString(1, "大文檔導入測試");
// 2. 設置流參數(MySQL 支持無長度模式)
ps.setAsciiStream(2, fis); // 或 ps.setAsciiStream(2, fis, file.length());
// 3. 執行插入
int rows = ps.executeUpdate();
System.out.println("插入成功,影響行數: " + rows);
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
}
String query = "SELECT content FROM documents WHERE id = ?";
try (PreparedStatement ps = conn.prepareStatement(query)) {
ps.setInt(1, docId);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
// 方式一:字符流(推薦,自動處理編碼)
try (Reader reader = rs.getCharacterStream("content");
BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
// 方式二:ASCII 字節流
// try (InputStream is = rs.getAsciiStream("content")) { ... }
}
}
}
| 數據庫 | 字段類型 | setAsciiStream 支持 | 備註 |
|---|---|---|---|
| MySQL | TEXT / LONGTEXT | 優秀 | 無需指定長度,自動處理 |
| PostgreSQL | TEXT / BYTEA | 優秀 | 大對象 API 更高效 |
| Oracle | CLOB | 良好 | 需 oracle.jdbc.OraclePreparedStatement 或 setCharacterStream |
| SQL Server | VARCHAR(MAX) / TEXT | 良好 | JTDS/jdbc 驅動行為略有不同 |
new BufferedInputStream(fis, 64 * 1024) 減少系統調用addBatch() + executeBatch()conn.setAutoCommit(false),最後統一 commit()setAsciiStream 是處理大文本入庫的利器,配合流式讀寫、批量提交、連接池,可輕松應對 GB 級文本數據導入場景。