-- 建表
CREATE TABLE TEST (ID NUMBER, CONTENT CLOB);
-- JSP 插入
String sql = "INSERT INTO TEST (ID, CONTENT) VALUES (?, EMPTY_CLOB())";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 1);
pstmt.executeUpdate();
// 必須 SELECT FOR UPDATE 取得 Locator
ResultSet rs = stmt.executeQuery("SELECT CONTENT FROM TEST WHERE ID=1 FOR UPDATE");
rs.next();
Clob clob = rs.getClob(1);
// 寫入內容
Writer writer = clob.setCharacterStream(1);
writer.write("中文內容...");
writer.flush();
writer.close();
conn.commit();
關鍵點:
EMPTY_CLOB() 配置 Locator,再 SELECT FOR UPDATE 鎖定列。conn.setAutoCommit(false),寫完 commit()。getCharacterStream() (Unicode) 而非 getAsciiStream()。public class ECov {
// ISO-8859-1 → GB2312 (讀取 DB 後轉中文)
public static String isoToGb(String iso) {
if (iso == null) return null;
try { return new String(iso.getBytes("ISO-8859-1"), "GB2312"); }
catch (UnsupportedEncodingException e) { return iso; }
}
// GB2312 → ISO-8859-1 (寫入 DB 前轉編碼)
public static String gbToIso(String gb) {
if (gb == null) return null;
try { return new String(gb.getBytes("GB2312"), "ISO-8859-1"); }
catch (UnsupportedEncodingException e) { return gb; }
}
}
// 使用
String param = ECov.gbToIso(request.getParameter("name")); // 寫入
String display = ECov.isoToGb(rs.getString("NAME")); // 讀出
Oracle JDBC (thin) 內部以 ISO-8859-1 傳輸,故需雙向轉換。JDK 1.4+ 建議直接設定 oracle.jdbc.defaultNChar=true 或連線屬性 useUnicode=true&characterEncoding=UTF-8 (需資料庫字符集支援)。
// 寫入:用 setTimestamp 配合 java.sql.Timestamp
pstmt.setTimestamp(1, new Timestamp(java.util.Date().getTime()));
// 讀取:getTimestamp → java.util.Date
Date utilDate = rs.getTimestamp("CREATE_DATE");
避免用 setDate/getDate(僅精確到天),時區問題請在 JVM 或連線層面統一設定。
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/OracleDS");
Connection conn = ds.getConnection();
優勢:連線重用、洩漏防護、驗證機制、JNDI 解耦。
EMPTY_LOB() 再 FOR UPDATE 寫入。Timestamp 保留毫秒。DriverManager.getConnection。try-with-resources (JDK 7+)。