`

如何通过java或jsp向数据库存取二进制图片

阅读更多
前几天突然看到学校音乐站上的图片原来是存储在数据库上的,是二进制而不是使用路径保存的,在网上招了找发现大多介绍的都是hph方式,在这里做个总结,首先要存储二进制文件在数据库中要搞清楚下面几个内容:
1 mysql存储大容量的二进制文件的格式是blob,其实除了图片还可以存别的
2 要向数据库存储二进制的文件一定要把要存储的数据转换成二进制流
废话就不多说了,大家看看代码很容易明白,先来看一个app程序,当然首先您要在数据库中先建立一个用于保存图片的表和相应的列,数据格式为blob
package com.lizhe;
import java.io.*;
import java.sql.*;
public class PutImg {
public void putimg() {
try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url = "jdbc:mysql://localhost/img?user=root&password=root&useUnicode=true&characterEncoding=gbk";
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
//stmt.execute("insert into imgt (id) values (5)");
stmt.close();
PreparedStatement pstmt = null;
String sql = "";
File file = new File("c:\blog.jpg");
InputStream photoStream = new FileInputStream(file);
//sql = " UPDATE imgt SET img = ? ";

sql = "INSERT INTO imgtable (img) VALUES (?)";

pstmt = conn.prepareStatement(sql);
pstmt.setBinaryStream(1, photoStream, (int) file.length());
pstmt.executeUpdate();
pstmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]){
PutImg pi=new PutImg();
pi.putimg();
}
}

InputStream photoStream = new FileInputStream(file);
可以很清楚的看到我们首先把一个图片文件(当然也可以是别的什么文件)转换成了一个二进制输入流
pstmt.setBinaryStream(1, photoStream, (int) file.length());
这个方法建议大家去查一下API文档,第一个参数是通配符位置没的说,第二个参数是流,这和以往的string类型的参数不太一样,我刚看到的时候也觉得豁然开朗了,但是到这里还没完,不同于以往的字符串参数,这里我们还需要第三个参数来设置这个流的长度,这里也就是这个文件的长度,导出数据库中的sql,一切都清楚了
INSERT INTO `m_diy` VALUES (2,? JFIF HH?? ExifMM* b j ( 1 r 2 ?i H H Adobe Photoshop CS Windows2007:03:18 23:08:15 ? ??? ? ........等等
其实就是将文件先转换成了二进制的流,然后插入到了sql语言中,向数据库写入了很长很长的一段sql语句



然后我们再来写一个app程序将这个文件读出来,存储成一个图片文件
package com.lizhe;
import java.io.*;
import java.sql.*;
class GetImg {

private static final String URL = "jdbc:mysql://localhost/img?user=root&password=root&useUnicode=true&characterEncoding=gbk";
private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
private File file = null;

public void blobRead(String outfile, int picID) throws Exception {
FileOutputStream fos = null;
InputStream is = null;
byte[] Buffer = new byte[4096];
try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
conn = DriverManager.getConnection(URL);
pstmt = conn.prepareStatement("select img from imgt where id=?");
pstmt.setInt(1, picID); // 传入要取的图片的ID
rs = pstmt.executeQuery();
rs.next();
file = new File(outfile);
if (!file.exists()) {
file.createNewFile(); // 如果文件不存在,则创建
}
fos = new FileOutputStream(file);
is = rs.getBinaryStream("img");
int size = 0;

while ((size = is.read(Buffer)) != -1) {
// System.out.println(size);
fos.write(Buffer, 0, size);
}
} catch (Exception e) {
System.out.println( e.getMessage());
} finally {
// 关闭用到的资源
fos.close();
rs.close();
pstmt.close();
conn.close();
}
}
public static void main(String[] args) {
try {
GetImg gi=new GetImg();
gi.blobRead("c:/getimgs/1.jpg", 5);
} catch (Exception e) {
System.out.println("[Main func error: ]" + e.getMessage());
}
}
}
这里需要注意的是
is = rs.getBinaryStream("img");
img是数据库中相应的列名,其实和rs.getString()方法差不多,只不过这个方法是读取二进制流的
最后在帖两个bs系统上用的文件给大家参考
通过struts的action向数据库写入二进制图片
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.lizhe.struts.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import com.lizhe.struts.form.UpimgForm;
/**
* MyEclipse Struts
* Creation date: 05-18-2007
*
* XDoclet definition:
* @struts.action path="/upimg" name="upimgForm" input="/userhomepage.jsp"
* @struts.action-forward name="userhome" path="/userhomepage.jsp" redirect="true" contextRelative="true"
*/
public class UpimgAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
* @throws IOException
* @throws FileNotFoundException
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException, IOException {
UpimgForm upimgForm = (UpimgForm) form;// TODO Auto-generated method stub

FormFile file=upimgForm.getFile();
InputStream is=file.getInputStream();

try {
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url = "jdbc:mysql://localhost/blog?user=root&password=root&useUnicode=true&characterEncoding=gb2312";
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
//stmt.execute("insert into img (id) values (5)");
stmt.close();
PreparedStatement pstmt = null;
String sql = "";
//File file = new File("c:\blog.jpg");
//InputStream photoStream = new FileInputStream(file);
//sql = " UPDATE imgt SET img = ? ";

sql = "INSERT INTO img (img) VALUES (?)";

pstmt = conn.prepareStatement(sql);
pstmt.setBinaryStream(1, is, (int) file.getFileSize());
pstmt.executeUpdate();
pstmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}

return mapping.findForward("userhomepage");
}
}
和app的方式几乎是一样的
第二个文件是通过jsp将数据库中的图片显示在页面上
这个有些不同
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.sql.*" %>
<%@ page import="java.util.*"%>
<%@ page import="java.text.*"%>
<%@ page import="java.io.*"%>
<%@ page import="java.awt.*"%>
<html>
<body>
<%
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url="jdbc:mysql://localhost/img?user=root&password=root";
Connection con = DriverManager.getConnection(url);
String sql = "select * from imgt where id=5";
Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery(sql);
if(rs.next()) {
InputStream in = rs.getBinaryStream("img");
ServletOutputStream op = response.getOutputStream();
int len;
byte[] buf=new byte[1024];
while((len= in.read(buf))!=-1) {
op.write(buf, 0, len);
}
op.close();
in.close();
}

rs.close();
stmt.close();
con.close();
%>
</body>
</html>


坏男孩 2007-06-01 08:38 发表评论
分享到:
评论
3 楼 ZYzhongyang 2011-02-20  
可能是mysql 的驱动版本低了
2 楼 kojh 2008-08-19  
我也遇到这样的问题啊,搞了好久都搞不好啊,苍天啊。。。谁能解决这个问题啊。。。。。。。。。。。。。。。。      
1 楼 kang36897 2008-05-02  
我想请教您一个问题,是关于MYSQL存入图片的,我用的是MYSQL5.0+jndi+jsp,下面是我的代码:
<%@ page language="java" contentType="text/html; charset=gb2312"
pageEncoding="gb2312"
import="java.io.*,java.sql.*,javax.sql.*,javax.naming.*,java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>插入图片</title>
</head>
<body>
<%
request.setCharacterEncoding("gb2312");
Connection con;
PreparedStatement preparedStmt;
String query = "insert into album(name,data,id) values(?,?,?)";
try {
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx
.lookup("java:comp/env/jdbc/mysqlpool");
con = ds.getConnection();
String location = request.getParameter("image");
File filename = new File(location);
out.println("1");
String name = request.getParameter("name");
InputStream fis = new FileInputStream(filename);
out.println("2");
preparedStmt = con.prepareStatement(query);
preparedStmt.setString(1, name);
preparedStmt.setInt(3, Integer.parseInt(request.getParameter("id")));
preparedStmt.setBinaryStream(2, fis, (int) filename.length());
preparedStmt.executeUpdate();
fis.close();
preparedStmt.close();
con.close();
out.println("操作成功!");
} catch (SQLException e) {
out.println(e.toString());
} catch (Exception e) {
out.println(e.getStackTrace());
}
%>

</body>
</html>

插入用页面是:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>将图片插入数据库</title>
</head>
<body>
<form method="post" action="insert.jsp">
<table border="0" cellspacing="0"cellpadding="0">

<tr>
<td>图片名称:</td>
<td><input type="text" name="name" size="20"></td>
</tr>
<tr>
<td>图片ID:</td>
<td><input type="text" name="id" size="20"></td>
</tr>
<tr>
<td align="top">文件:</td>
<td><input type="file" name="image"></td>
</tr>
<tr>
<td><input type="submit" value="上传"></td>
</tr>

</table>
</form>
</body>
</html>

但是就是插不进去,而且还报下面的错误:
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'm?QwV^b0N?,? B Gg>?j??j?C?S??I1???6…@Zè????S?Xéaü?IG?G???0u?ud}a??5\0? ?' at line 1

相关推荐

    JSP在数据库中存取图片

    然后,从请求中获取用户的输入信息,并将文件数据转换为二进制流,最终通过PreparedStatement执行SQL插入操作,将图片数据存储到数据库的`ImageData`字段中。 #### 五、总结 通过以上步骤,我们可以实现一个完整的...

    利用Java程序实现Oracle数据库中大对象的存取.pdf

    "利用Java程序实现Oracle数据库中大对象的存取" ...使用Java程序实现Oracle数据库中大对象的存取可以通过jdbc驱动程序连接Oracle数据库,并使用PreparedStatement对象执行SQL语句,实现对大对象的存储和读取。

    网页在Oracle中存取图片

    1. BLOB类型:Oracle数据库提供了BLOB(Binary Large Object)数据类型,用于存储大块二进制数据,如图片。在创建表时,我们需要定义一个BLOB字段来保存图片内容。 2. CLOB与NCLOB:对于文本格式的图片(如Base64...

    Struts2 Hibernate存取Oracle数据库中的BLOB数据.pdf

    - BLOB(二进制大对象):用于存储大型二进制数据,如影像、图片等,其长度可达4GB,支持随机存取。 - BFILE:虽然用于存储大型二进制数据,但数据实际存储在文件系统中,数据库中仅存储指向文件的指针,Oracle对...

    存取和显示

    为了显示数据库中的图片,我们可以创建一个新的JSP页面,通过查询数据库获取图片的二进制数据,然后将其写入响应流。这里不再展示具体的代码,但基本思路是:先根据图片ID查询数据库,获取到图片的二进制数据,然后...

    mysql-connector-java-3.1.11-bin

    MySQL Connector/J是MySQL数据库与Java应用程序之间的重要桥梁,它提供了Java Database Connectivity (JDBC) API,使得Java开发者能够方便地在应用中存取MySQL数据库。标题"mysql-connector-java-3.1.11-bin"指出这...

    jsp代码这是jsp百例的部分例子(92例的lib)(之二)

    6. **antlr-2.7.6rc1.jar**:ANTLR是一个强大的解析器生成器,可以用于读取、处理、执行或翻译结构化文本或二进制文件。在JSP中,可能用于解析和生成语法树。 7. **jboss-cache.jar**:这是JBoss的一个缓存解决方案...

    Java+JSP+SSH面试笔试题

    2. **提供Java存取数据库能力的包是。** - **答案解析:** 正确答案为A。Java中用于访问数据库的主要包是`java.sql`,它提供了与数据库交互的基本接口和类,如`Connection`、`Statement`、`ResultSet`等。 3. **...

    java必备知识点大全.pdf

    字节流与字符流的区别:字节流用于读写二进制数据,字符流用于读写文本数据。 final、finally、finalize三者区别:final用于声明常量,finally用在try-catch-finally语句中表示必须执行的代码块,finalize是Object...

    网页版聊天四个java实例

    实例中可能会展示如何创建WebSocket服务器端点以及客户端连接,以及如何通过WebSocket发送和接收文本或二进制数据。 3. **JSP与HTML/CSS/JavaScript** JSP(JavaServer Pages)是Java Web开发中的视图层技术,用于...

    JAVA程序员面试问题

    COM组件通过接口定义来实现功能的封装,支持二进制级别的互操作性。而CORBA(Common Object Request Broker Architecture)是一种跨平台的组件架构,由OMG(Object Management Group)制定,旨在解决分布式计算环境...

    2021-2022计算机二级等级考试试题及答案No.13085.docx

    20. 二进制扩展:在无符号二进制整数后面添加0,相当于左移一位,值翻倍。 21. 十进制转二进制:58转换成二进制是111010,这是正确的。 22. 完全二叉树的叶子节点计算:对于含有n个节点的完全二叉树,如果n是奇数...

    tomcate7+memcached所需jar包

    它通过网络进行通信,并使用二进制协议,提供高效的数据交换。 3. **Memcached客户端库**: 为了在Java应用中使用Memcached,我们需要一个Java客户端库。常见的有spymemcached、xmemcached等。这些库提供了与...

    2021-2022计算机二级等级考试试题及答案No.3410.docx

    10. 位移运算:`a&gt;&gt;1`表示将变量`a`的二进制表示右移一位,对于整型变量6(二进制110),右移一位后得到3(二进制011)。 11. Access退出快捷键:Alt+F+X是退出Access的快捷键。 12. 选择多个图标:在Windows中,...

    2021-2022计算机二级等级考试试题及答案No.9258.docx

    18. IP地址:IP地址由32位二进制数组成,而不是十进制。 19. Word段落标记:段落标记在打印时不被打印出来。 20. Visual FoxPro删除记录:SQL的DELETE命令可以直接删除记录,无需先用USE命令打开表,而传统的...

    2021-2022计算机二级等级考试试题及答案No.3512.docx

    9. 数制转换:八进制转换为二进制,每位八进制数对应三位二进制数。 10. RAM:随机存取存储器(RAM),是计算机中的一种临时存储数据的硬件,对数据可存可取。 11. 数组初始化:在Java中,执行`int[] x = new int...

    基于python图像的信息隐藏技术研究源码数据库.doc

    1. **像素值篡改**:通过修改图像的像素值来隐藏信息,比如使用LSB(Least Significant Bit)技术,将数据的二进制位替换图像像素的最低有效位。 2. **频域隐藏**:利用傅立叶变换,将秘密信息隐藏在图像的频率域中...

    javaWEB进阶详细整理

    GET请求常用于获取信息,而POST请求可以传递更复杂的数据,包括二进制数据。在HTML表单中,可以通过method属性设置提交方法,默认为GET。 开发JavaWeb项目时,需要按照特定的目录结构组织源代码。创建Web项目后,...

    2021-2022计算机二级等级考试试题及答案No.13684.docx

    14. JSP页面可以通过表单或超链接访问Servlet,这是Web应用的基本交互方式。 15. HTTP的GET请求可以获取各种类型的数据,包括HTML、图片、视频等。 16. SqlCommand对象的方法中没有ExecuteRead(),应该是...

Global site tag (gtag.js) - Google Analytics