Of course! Working with BLOB (Binary Large Object) data in Java with an Oracle database is a common task for handling large binary files like images, videos, documents, etc.

Here’s a comprehensive guide covering the key concepts, methods, and a complete, runnable example.
What is a BLOB?
A BLOB is a database data type used to store large amounts of binary data. Unlike a CLOB (Character Large Object), which stores character data, a BLOB stores raw binary data (bytes). This makes it ideal for:
- Images (JPG, PNG, GIF)
- Videos (MP4, AVI)
- Audio files (MP3, WAV)
- Documents (PDF, DOCX, ZIP archives)
- Any other non-textual file.
Key Java Classes
java.sql.Blob: This is the JDBC interface that represents aBLOBvalue. It provides methods to manage the data, such as getting its length, retrieving a stream to read it, or getting a binary stream to write to it.oracle.sql.BLOB: This is Oracle's specific implementation of thejava.sql.Blobinterface. When you retrieve aBLOBfrom an Oracle database, the JDBC driver will typically give you an instance of this class, which has more powerful features than the standard interface.
Core Operations
There are three primary scenarios you'll encounter:
- Inserting a BLOB: Writing binary data from a file or an input stream into a new database record.
- Reading a BLOB: Retrieving binary data from a database record and saving it to a file or writing it to an output stream.
- Updating a BLOB: Modifying the content of an existing BLOB in the database.
Important Prerequisite: Oracle JDBC Driver
You must have the Oracle JDBC driver (JAR file) in your project's classpath. The modern driver is ojdbc8.jar (for Java 8) or ojdbc11.jar (for Java 11+).

If you're using Maven, add this dependency to your pom.xml:
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>21.5.0.0</version> <!-- Use the latest version available -->
</dependency>
Complete Example
Let's walk through a full example that includes:
- Creating a table.
- Inserting a BLOB.
- Reading a BLOB.
- Updating a BLOB.
Step 1: Setup Database Table
First, create a table in your Oracle database to store the BLOBs.
CREATE TABLE my_documents (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR2(255) NOT NULL,
document_content BLOB,
created_date TIMESTAMP DEFAULT SYSTIMESTAMP
);
Step 2: Java Code (BlobExample.java)
This class demonstrates all three operations. It uses try-with-resources to ensure that database connections and file streams are always closed properly.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BlobExample {
// --- Database Connection Details ---
// IMPORTANT: Replace with your actual database details
private static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:ORCLPDB1";
private static final String DB_USER = "your_username";
private static final String DB_PASSWORD = "your_password";
public static void main(String[] args) {
// The file we will use for the example
File sourceFile = new File("sample.pdf"); // Make sure this file exists
File outputFile = new File("output_from_db.pdf");
// 1. Insert a BLOB into the database
System.out.println("Inserting BLOB...");
long insertedId = insertBlob(sourceFile);
System.out.println("BLOB inserted with ID: " + insertedId);
// 2. Read the BLOB from the database and save it to a new file
System.out.println("\nReading BLOB with ID: " + insertedId);
readBlob(insertedId, outputFile);
System.out.println("BLOB read and saved to: " + outputFile.getAbsolutePath());
// 3. Update the BLOB in the database
File anotherFile = new File("another_document.docx"); // Make sure this file exists
System.out.println("\nUpdating BLOB with ID: " + insertedId);
updateBlob(insertedId, anotherFile);
System.out.println("BLOB updated.");
// 4. Read the updated BLOB to verify
System.out.println("\nReading updated BLOB with ID: " + insertedId);
readBlob(insertedId, new File("updated_output.docx"));
System.out.println("Updated BLOB read and saved.");
}
/**
* Inserts a BLOB into the database from a file.
*/
public static long insertBlob(File fileToInsert) {
final String sql = "INSERT INTO my_documents (name, document_content) VALUES (?, EMPTY_BLOB()) RETURNING id, document_content INTO ?, ?";
// Using try-with-resources for Connection and PreparedStatement
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, fileToInsert.getName());
// Register the OUT parameters for the RETURNING clause
// The first '?' is for the ID (LONG)
pstmt.registerOutParameter(2, java.sql.Types.NUMERIC);
// The second '?' is for the BLOB (oracle.sql.BLOB)
pstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.BLOB);
// Execute the insert. This does not yet write the BLOB data.
pstmt.executeUpdate();
// Now, get the BLOB locator from the OUT parameter
oracle.sql.BLOB blob = (oracle.sql.BLOB) pstmt.getObject(3);
long newId = pstmt.getLong(2);
// Write the file's content to the BLOB locator
try (InputStream inputStream = new FileInputStream(fileToInsert);
OutputStream outputStream = blob.getBinaryOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
return newId;
} catch (SQLException | IOException e) {
e.printStackTrace();
return -1;
}
}
/**
* Reads a BLOB from the database and saves it to a file.
*/
public static void readBlob(long id, File outputFile) {
final String sql = "SELECT document_content FROM my_documents WHERE id = ?";
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setLong(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
// Get the BLOB object from the result set
java.sql.Blob blob = rs.getBlob("document_content");
// Get an input stream from the BLOB
try (InputStream inputStream = blob.getBinaryStream();
OutputStream outputStream = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
} else {
System.out.println("No record found with ID: " + id);
}
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
/**
* Updates an existing BLOB in the database.
*/
public static void updateBlob(long id, File fileToUpdate) {
final String sql = "UPDATE my_documents SET document_content = EMPTY_BLOB() WHERE id = ? RETURNING document_content INTO ?";
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setLong(1, id);
// Register the OUT parameter for the BLOB locator
pstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.BLOB);
// Execute the update. This gets a new, empty BLOB locator.
pstmt.executeUpdate();
// Get the BLOB locator from the OUT parameter
oracle.sql.BLOB blob = (oracle.sql.BLOB) pstmt.getObject(2);
// Write the new file's content to the BLOB locator
try (InputStream inputStream = new FileInputStream(fileToUpdate);
OutputStream outputStream = blob.getBinaryOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
}
Best Practices and Important Considerations
-
Use
try-with-resources: Always wrap yourConnection,PreparedStatement,ResultSet,InputStream, andOutputStreamobjects intry-with-resourcesblocks. This guarantees they are closed automatically, preventing resource leaks. -
Use
PreparedStatementwithRETURNINGClause (for Oracle): This is the most efficient way to handle BLOBs. Instead of inserting an emptyBLOBand then doing a separateUPDATE, you can do it in one step:INSERT ... RETURNING document_content INTO ?- This gives you a "locator" to the
BLOBin the database immediately after the insert, which you can then write to directly. This avoids the overhead of a secondUPDATEstatement.
-
Memory Management: Loading a very large BLOB (e.g., a multi-gigabyte video) directly into memory using
blob.getBytes()is a very bad idea and will likely cause anOutOfMemoryError. Always use streams (getBinaryStream()andsetBinaryStream()) for large BLOBs. The example above correctly uses streams, which is the recommended approach. -
Transactions: BLOB operations can be slow. It's good practice to wrap them in a transaction to ensure data integrity.
conn.setAutoCommit(false); // Start transaction // ... perform your BLOB insert/update operations ... conn.commit(); // Commit the transaction // or conn.rollback(); if something goes wrong
-
BLOBvs.CLOB:- Use
BLOBfor any binary data (images, videos, PDFs, etc.). - Use
CLOBfor large text data (XML, JSON, long text articles). Character sets are handled correctly withCLOBs, which is not the case withBLOBs.
- Use
