【问题标题】:Updating JLabel via SetIcon from bytea data type in postgres通过 SetIcon 从 postgres 中的 bytea 数据类型更新 JLabel
【发布时间】:2015-09-17 05:31:18
【问题描述】:

我正在从 Wolfram|Alpha 检索 gif 图像。为了尽量减少查询,我想存储这些图像并且只在数据更改时查询 W|A,所以我将图像作为 bytea 数据类型存储在我的 postgres 数据库中。 “保存”部分似乎正在工作,因为有数据。 System.out.println(rs.getString("fnPlotImg")) 产生这个:\x4275666665726564496d6167654035356437373834323a2074797065203d203120446972656374436f6c6f724d6f64656c3a20726d61736b3d66663030303020676d61736b3d6666303020626d61736b3d666620616d61736b3d3020496e7465676572496e7465726c65617665645261737465723a207769647468203d2032303020686569676874203d20313335202342616e6473203d203320784f6666203d203020794f6666203d203020646174614f66667365745b305d2030

我已经能够使用这段代码成功地从 W|A 更新图像:

String path = ((WAImage) element).getURL();
URL url = new URL(path);
BufferedImage image = ImageIO.read(url);
picLabel.setIcon(new ImageIcon(image));

我想用数据库中的图像更新我的应用程序并尝试了以下代码:

byte[] ba = rs.getBytes("fnPlotImg");
try{
    picLabel.setIcon(new ImageIcon(ba));
} catch (NullPointerException e) {
    e.printStackTrace();
}

我的理由是 bytea 是一个字节数组,getBytes() 应该检索一个字节数组,而 ImageIcon() 应该处理一个字节数组。但是,如果我不构建空指针异常它错误出来。我认为这是因为我没有将图像正确保存到数据库,或者我没有正确检索它。

欢迎所有想法,我已经很累了,所以我会在早上用新鲜的眼睛检查。

【问题讨论】:

  • 你是如何将图像存储在数据库中的?
  • 通过 SQL 将其与相关数据作为 BufferedImage 插入...我突然想到我没有检查这是否是正确的做法。
  • 我认为您想写入文件图像数据,而不是 BufferedImage,例如 this。这样您只需阅读byteaInputStreamImageIO
  • 我会在早上试试你的建议,谢谢你的意见。

标签: java postgresql


【解决方案1】:

我没有可用的 PostgreSQL 安装,但我认为您应该写入/读取图像格式而不是 BufferedImage 数据。

例如,写作可能看起来像......

Connection con = ...;
BufferedImage img = ...;
try (PreparedStatement stmt = con.prepareStatement("insert into tableofimages (image) values (?)")) {
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        ImageIO.write(img, "png", baos);
        try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {
            stmt.setBinaryStream(1, bais);
            int rows = stmt.executeUpdate();
            System.out.println(rows + " rows updated");
        }
    }
} catch (SQLException | IOException exp) {
    exp.printStackTrace();
}

阅读可能看起来像......

Connection con = ...;
try (PreparedStatement stmt = con.prepareStatement("select image from tableofimages")) {
    try (ResultSet rs = stmt.executeQuery()) {
        while (rs.next()) {
            try (InputStream is = rs.getBinaryStream(1)) {
                BufferedImage img = ImageIO.read(is);
            }
        }
    }
} catch (SQLException | IOException exp) {
    exp.printStackTrace();
}

【讨论】:

  • 我终于明白了。这个解决方案的“写入”部分,以及我发现的许多类似的部分,正在将图像本身写入没有任何并发​​数据的表中。我假设 setBinaryStream 将只写入图像,如果我想插入的不仅仅是图像列,我必须插入所有初始数据,然后更新 BLOB 列,反之亦然。这听起来对吗,或者我可以以某种方式一次编写所有内容吗?
  • 您可以将插入扩展为具有多个值,并将每个标记 (?) 设置为您要插入的值,因此应该可以一步完成。您也可以正常更新表格
  • 好的,我不明白 PreparedStatement 是如何工作的。说得通。但是现在当我写入然后从数据库中读取时,它又全黑了。我可能需要逐步分解它才能找到问题,这需要一些时间。
  • 你真的应该学习,看看Using Prepared Statements
  • 我通过 H2(针对 BINARY 类型,应该与 BYTEA 相同)运行(更新的)代码,它似乎对我有用。原始代码在读取二进制流时使用列0,而它本应读取1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
  • 2022-09-22
  • 1970-01-01
相关资源
最近更新 更多