首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

JSP + MySQL 處理 BLOB/LongBlob 圖片存取實戰:PreparedStatement 二進位流寫入與輸出

     編輯:MySQL 綜合教學

資料型別選擇

  • BLOB:64 KB
  • MEDIUMBLOB:16 MB
  • LONGBLOB:4 GB(現代數位相片建議使用)
CREATE TABLE images (
    id CHAR(36) PRIMARY KEY,
    pic LONGBLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

上傳頁面 postblob.html

<form action="testblob.jsp" method="post" enctype="multipart/form-data">
  ID: <input name="id" type="text"/><br/>
  File: <input name="file" type="file"/><br/>
  <input type="submit" value="上傳"/>
</form>

寫入邏輯 testblob.jsp(核心:PreparedStatement + setBinaryStream)

<%@ page import="java.sql.*,java.io.*" %>
<%
String id = request.getParameter("id");
Part filePart = request.getPart("file");  // Servlet 3.0+ 標準 API
InputStream is = filePart.getInputStream();

Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");

String sql = "INSERT INTO images (id, pic) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
pstmt.setBinaryStream(2, is, (int) filePart.getSize());  // 傳入長度讓驅動優化
pstmt.executeUpdate();

pstmt.close();
conn.close();
out.println("上傳成功!");
%>

優勢:無需先插入空值再更新,單次 executeUpdate 完成寫入,效能最佳。

讀取顯示 readblob.jsp

<%@ page import="java.sql.*,java.io.*" %>
<%
String id = request.getParameter("id");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT pic FROM images WHERE id='" + id + "'");

if (rs.next()) {
    Blob blob = rs.getBlob("pic");
    int len = (int) blob.length();
    InputStream in = blob.getBinaryStream();
    byte[] buf = new byte[4096];
    int read;
    response.setContentType("image/jpeg");  // 或根據實際格式動態判斷
    ServletOutputStream out = response.getOutputStream();
    while ((read = in.read(buf)) != -1) {
        out.write(buf, 0, read);
    }
    in.close();
    out.flush();
}
rs.close();
stmt.close();
conn.close();
%>

關鍵注意事項

項目說明
連線池生產環境必須使用 DataSource (JNDI/連線池),避免頻繁建立連線
大檔案> 10MB 建議存檔案系統/物件存儲,資料庫只存路徑
SQL 注入讀取頁面示範用拼接 SQL 僅為教學,**實務必須用 PreparedStatement**
Content-Type建議表中額外存 mime_type 欄位,動態設定回應類型
緩衝區大小4KB-8KB 平衡記憶體與系統呼叫次數

常見問題

  • Packet too large:調大 max_allowed_packet(如 32M)
  • 圖片顯示破損:確認 response.setContentType 與實際格式一致,避免 JSP 頁面輸出空白字元混入二進位流
  • 記憶體溢位:禁止 blob.getBytes(1, (int)blob.length()) 一次性讀入大 Blob,必須流式讀寫

掌握 PreparedStatement.setBinaryStream 與 Blob.getBinaryStream 流式處理模式,是 JSP/MySQL 高效、安全處理二進位資料的標準作法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved