JavaFX应用读写JPEG图片至数据库的示例需求
JavaFX 读写JPEG图片到H2数据库极简示例
1. H2数据库表准备
先创建存储图片的表,用BLOB类型存储图片字节数据:
CREATE TABLE IF NOT EXISTS image_store ( id INT AUTO_INCREMENT PRIMARY KEY, image_name VARCHAR(100) NOT NULL, image_data BLOB NOT NULL );
2. 核心转换逻辑
JavaFX的Image对象无法直接存入数据库,需要转成字节数组;从数据库读取的字节数组也需要转回Image:
import javafx.scene.image.Image; import javafx.embed.swing.SwingFXUtils; import javax.imageio.ImageIO; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.awt.image.BufferedImage; // JavaFX Image 转字节数组(JPEG格式) public static byte[] imageToBytes(Image image) throws IOException { BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", outputStream); return outputStream.toByteArray(); } // 字节数组转JavaFX Image public static Image bytesToImage(byte[] imageBytes) { ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); return new Image(inputStream); }
注意:如果是从本地文件直接读取图片存入数据库,也可以直接读取文件字节流,无需转成JavaFX Image,效率更高。
3. JDBC读写数据库代码
插入图片到H2
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public static void saveImageToDB(String imageName, byte[] imageBytes) throws SQLException { // H2数据库连接URL(嵌入式模式) String url = "jdbc:h2:~/test"; String user = "sa"; String password = ""; String sql = "INSERT INTO image_store (image_name, image_data) VALUES (?, ?)"; try (Connection conn = DriverManager.getConnection(url, user, password); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, imageName); pstmt.setBytes(2, imageBytes); pstmt.executeUpdate(); } }
从H2读取图片
import java.sql.ResultSet; public static byte[] getImageBytesFromDB(int imageId) throws SQLException { String url = "jdbc:h2:~/test"; String user = "sa"; String password = ""; String sql = "SELECT image_data FROM image_store WHERE id = ?"; try (Connection conn = DriverManager.getConnection(url, user, password); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setInt(1, imageId); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { return rs.getBytes("image_data"); } return null; } }
4. JavaFX界面示例
一个简单的窗口,实现选择本地JPEG、保存到数据库、加载并显示的功能:
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.VBox; import javafx.scene.image.ImageView; import javafx.stage.FileChooser; import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Files; public class ImageDBApp extends Application { private ImageView imageView = new ImageView(); @Override public void start(Stage stage) { // 选择图片按钮 Button selectBtn = new Button("选择JPEG图片"); selectBtn.setOnAction(e -> { FileChooser fileChooser = new FileChooser(); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JPEG图片", "*.jpg", "*.jpeg")); File selectedFile = fileChooser.showOpenDialog(stage); if (selectedFile != null) { try { // 直接读取文件字节(比转成Image再转字节更高效) byte[] imageBytes = Files.readAllBytes(selectedFile.toPath()); saveImageToDB(selectedFile.getName(), imageBytes); // 显示选择的图片 imageView.setImage(new Image(selectedFile.toURI().toString())); } catch (IOException | SQLException ex) { ex.printStackTrace(); } } }); // 加载图片按钮 Button loadBtn = new Button("从数据库加载图片(ID=1)"); loadBtn.setOnAction(e -> { try { byte[] imageBytes = getImageBytesFromDB(1); if (imageBytes != null) { imageView.setImage(bytesToImage(imageBytes)); } } catch (SQLException ex) { ex.printStackTrace(); } }); VBox root = new VBox(10, selectBtn, loadBtn, imageView); root.setPrefSize(600, 400); Scene scene = new Scene(root); stage.setTitle("JavaFX图片数据库示例"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } // 这里把前面的imageToBytes、bytesToImage、saveImageToDB、getImageBytesFromDB方法复制过来 }
注意事项
- 确保项目中引入H2数据库驱动和JavaFX依赖
- 大图片建议分块读取/写入,避免内存溢出
- 实际项目中建议用连接池代替直接创建Connection
内容的提问来源于stack exchange,提问作者Basil Bourque
相关产品推荐
相关产品推荐

