When storing images in a database as BLOBs, there may come a time when you need to extract those images and save them to the file system—perhaps for migration, processing, or serving them more efficiently. In this tutorial, you’ll learn how to build a Spring Batch job to do exactly that.
Let’s break it down 👇
⚙️ Step 1: Add Maven Dependencies
In your pom.xml
, include the necessary dependencies:
xml
<dependencies>
<!-- Spring Batch -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
</dependency>
<!-- JPA + H2 (or your preferred database) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
🧱 Step 2: Define the Image Entity
Assuming your database table is called images
, you can map it like this:
java
import javax.persistence.*;
@Entity
public class ImageEntity {
@Id
private Long id;
private String filename;
@Lob
@Column(name = "image_data")
private byte[] imageData;
// Getters and setters
}
📡 Step 3: Create a JPA Repository
java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ImageRepository extends JpaRepository<ImageEntity, Long> {
}
🧩 Step 4: Configure the Spring Batch Job
Create your batch configuration class:
java
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.*;
import org.springframework.batch.item.*;
import org.springframework.batch.item.data.RepositoryItemReader;
import org.springframework.context.annotation.*;
import org.springframework.data.domain.Sort;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
@Configuration
@EnableBatchProcessing
public class ImageBatchConfig {
@Bean
public RepositoryItemReader<ImageEntity> reader(ImageRepository repo) {
RepositoryItemReader<ImageEntity> reader = new RepositoryItemReader<>();
reader.setRepository(repo);
reader.setMethodName("findAll");
reader.setSort(Collections.singletonMap("id", Sort.Direction.ASC));
return reader;
}
@Bean
public ItemProcessor<ImageEntity, ImageEntity> processor() {
return image -> {
// You can resize/convert here if needed
return image;
};
}
@Bean
public ItemWriter<ImageEntity> writer() {
return items -> {
String outputDir = "/path/to/your/folder/"; // ✅ change this
for (ImageEntity item : items) {
String filePath = outputDir + item.getFilename();
try (FileOutputStream fos = new FileOutputStream(filePath)) {
fos.write(item.getImageData());
}
}
};
}
@Bean
public Step exportStep(StepBuilderFactory stepBuilderFactory,
ItemReader<ImageEntity> reader,
ItemProcessor<ImageEntity, ImageEntity> processor,
ItemWriter<ImageEntity> writer) {
return stepBuilderFactory.get("exportImages")
.<ImageEntity, ImageEntity>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
@Bean
public Job imageExportJob(JobBuilderFactory jobBuilderFactory, Step exportStep) {
return jobBuilderFactory.get("imageExportJob")
.start(exportStep)
.build();
}
}
🚀 Step 5: Run the Job
When you run your application, Spring Batch will:
- Query images from your database,
- Optionally process them,
- And write them as files to your target folder.
Make sure the output directory exists and is writable.
✅ Extra Tips
- Error Handling: Wrap file output logic in
try-catch
to handle disk issues or invalid filenames. - File Formats: If needed, you can use libraries like
javax.imageio.ImageIO
to convert/validate formats. - Performance: Tune
chunk(10)
depending on your data size and memory limits.
📦 Summary
With Spring Batch, you can efficiently build a robust image extraction pipeline from a database using minimal configuration. This setup gives you a clean, scalable solution to export and persist BLOB images on disk.