使用Java以二进制格式在数据库中存储图像

使用Java以二进制格式在数据库中存储图像,java,image,swing,sql-server-2008-r2,binary-data,Java,Image,Swing,Sql Server 2008 R2,Binary Data,我正在处理我的项目,遇到了一些问题,我搜索了它,但找不到完整的学习资源,我需要的是使用Java程序将图像存储在SQL Server数据库中,并且需要返回以检索,图像的大小不是更大,它们的范围在30到50 K之间, 我可以使用toolKit中的getImage()方法从磁盘加载图像 Image imm = Toolkit.getDefaultToolkit().getImage("URl"); ,但我不知道如何将该图像转换为二进制格式并存储在数据库中,然后从数据库中检索回来。 我想将其存储在Va

我正在处理我的项目,遇到了一些问题,我搜索了它,但找不到完整的学习资源,我需要的是使用Java程序将图像存储在SQL Server数据库中,并且需要返回以检索,图像的大小不是更大,它们的范围在30到50 K之间, 我可以使用toolKit中的getImage()方法从磁盘加载图像

Image imm = Toolkit.getDefaultToolkit().getImage("URl");
,但我不知道如何将该图像转换为二进制格式并存储在数据库中,然后从数据库中检索回来。
我想将其存储在VarBinary中,通过查看几个站点,我发现SQL Server中的映像类型很快就要过时了。

通常,将像映像这样的大型资源放入数据库不是一个很好的主意,除非在使用它们时确实需要符合ACID。数据库转储和生成它们所需的时间急剧增长,您将需要使用更复杂、更脆弱的增量备份


通常,将映像存储在文件系统上可能会更有效,并且只有在确定映像资源已成功创建后,才能将映像路径放入数据库。

将像映像这样的大型资源放入数据库通常不是一个好主意,除非你在与他们合作时确实需要ACID合规性。数据库转储和生成它们所需的时间急剧增长,您将需要使用更复杂、更脆弱的增量备份


通常,将图像存储在文件系统上可能更有效,并且只有在您确定图像资源已成功创建后,才将图像路径放入数据库。

虽然在数据库中存储非常大的二进制对象不是一个好主意,但Microsoft研究论文“表示如果对象大小小于256K,这是一种有效的方法。因此,听起来您已经达到了30K图像数据库存储的最佳状态

您可以使用以下方法从URL将图像作为缓冲图像加载:

BufferedImage imm = ImageIO.read(url);
然后使用以下命令将其转换为字节数组:

byte[] immAsBytes = 
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//use another encoding if JPG is innappropriate for you
ImageIO.write(imm, "jpg", baos );
baos.flush();
byte[] immAsBytes = baos.toByteArray();
baos.close();
然后将字节数组作为VARBINARY存储在数据库中。在JDBC代码中,应将字节数组包装在ByteArrayInputStream中,并将PreparedStatement参数设置为BinaryStream:

PreparedStatement pstmt = commection.prepareStatement("INSERT INTO IMAGES (image) VALUES(?)");
ByteArrayInputStream bais = new ByteArrayInputStream(immAsBytes);
pstmt.setBinaryStream(1, bais, immAsBytes.length);
pstmt.executeUpdate();
pstmt.close();
要从数据库中获取图像,请使用ResultStatement.getBlob():

最后,将字节数组转换为BuffereImage并对其进行处理:

InputStream in = new ByteArrayInputStream(immAsBytes);
BufferedImage imgFromDb = ImageIO.read(in);

虽然在数据库中存储非常大的二进制对象不是一个好主意,但微软的研究论文“指出,如果对象大小小于256K,这是一种有效的方法。因此,听起来你已经达到了使用30K图像存储数据库的最佳状态。”

您可以使用以下方法从URL将图像作为缓冲图像加载:

BufferedImage imm = ImageIO.read(url);
然后使用以下命令将其转换为字节数组:

byte[] immAsBytes = 
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//use another encoding if JPG is innappropriate for you
ImageIO.write(imm, "jpg", baos );
baos.flush();
byte[] immAsBytes = baos.toByteArray();
baos.close();
然后将字节数组作为VARBINARY存储在数据库中。在JDBC代码中,应将字节数组包装在ByteArrayInputStream中,并将PreparedStatement参数设置为BinaryStream:

PreparedStatement pstmt = commection.prepareStatement("INSERT INTO IMAGES (image) VALUES(?)");
ByteArrayInputStream bais = new ByteArrayInputStream(immAsBytes);
pstmt.setBinaryStream(1, bais, immAsBytes.length);
pstmt.executeUpdate();
pstmt.close();
要从数据库中获取图像,请使用ResultStatement.getBlob():

最后,将字节数组转换为BuffereImage并对其进行处理:

InputStream in = new ByteArrayInputStream(immAsBytes);
BufferedImage imgFromDb = ImageIO.read(in);

为什么要将图像转换为VarBinary?只需将图像保存在磁盘中,并将路径保存在db中。这可能存在安全风险,假设我的图像名为image1.jpg,而其他人会删除该图像并放置另一个具有相同名称的图像。您可以使用一些约定,如使用imagename附加时间戳。这样re不会发生冲突。为什么要将图像转换为VarBinary?只需将图像保存在磁盘中,并将路径保存在db中。这可能存在安全风险,假设我的图像名为image1.jpg,而其他一些图像则会删除该图像并放置另一个同名图像?您可以使用一些约定,例如在im中附加时间戳这样就不会有冲突。那么做反向作业是什么意思?是指从数据库检索吗?做反向作业是指从数据库检索吗?