`
woshixushigang
  • 浏览: 578054 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

SQLSERVER2005读取图片类型字段

阅读更多

下午向数据库SQL SERVER中遇到添加图片类型数据的问题,本以为在界面管理器中可以直接(通过指定路径把图片的数据保存起来)添加图片却不然。网上搜了下找到了相关的较专业的资料,整合解读一下:

两种方法:

      第一就是在数据库中存储图片的路径,然后在程序中根据读取的路径读取图片;这种方法简单、容易使用,但是在图片过多时不好管理。
      第二种就是将图片转换成二进制存储于数据库中,sql server 2005有个image数据类型,专门用于存储图片,Image数据类型存储的是长度不确定的二进制数据,最大长度是2GB。

第二种方法(详情请参阅:详述的过程)

简述过程:

当然首先得有存储图片字段的数据库、表。

如何插入图片:

大致流程:其他图片格式--》image类型的转化--》到MemoryStream流的转换--》到二进制的转换--》插入到数据库。

如何得到图片:

大致流程:选取数据库中的image类型字段--》转化为二进制流--》转化为MemoryStream流--》转化为Image图片格式类型。

其它:如何插入读取一个文件、如何保存数据库中的image字段到一个文件。。
 

 

Connection conn ;
  conn= ConnectionFactory.getConn();
  PreparedStatement ps;
  //建立Statement对象
String name=request.getParameter("picname");
String img=request.getParameter("pic");
//获得所要显示图片的标题、存储路径、内容,并进行中文编码
FileInputStream str=new FileInputStream(img);
//String sql="insert into p(picname,pic) values(?,?)";

String sql="INSERT INTO test_Img(name,img) VALUES(?,?)";
ps=conn.prepareStatement(sql);
ps.setString(1,name);

ps.setBinaryStream(2,str,str.available());
ps.execute();
//将数据存入数据库
out.println("Success,You Have Insert an Image Successfully");

 

/**   
  * Created by IntelliJ IDEA.   
  * User: ljt   
  * Date: 2003-3-31   
  * Time: 18:51:38   
  * To change this template use Options | File Templates.   
  */   
  import oracle.jdbc.driver.OraclePreparedStatement;   
  import oracle.jdbc.driver.OracleResultSet;   
    
  import java.sql.Connection;   
  import java.sql.DriverManager;   
  import java.sql.Statement;   
  import java.sql.Clob;   
    
    
    
  public class TestOpenDoc {   
  public OracleResultSet ors = null; //**这里rs一定要用Oracle提供的   
  public OraclePreparedStatement opst = null; //**PreparedStatement用   
  public Connection conn = null;   
  public Statement stmt = null;   
    
  public TestOpenDoc() {   
  }   
    
  public boolean getConnect() {   
  //这是我的数据库所在   
  String serverName = "prosrv";   
  try {   
  Class.forName("oracle.jdbc.driver.OracleDriver");   
  String url = "jdbc:oracle:thin:@" + serverName + ":1521:BOHDATA";   
  conn = DriverManager.getConnection(url, "appuser", "appuser");   
  }   
  catch (Exception e) {   
  System.out.println(e);   
  return false;   
  }   
  return true;   
  }   
    
  public static void main(String[] args) {   
  TestOpenDoc test = new TestOpenDoc();   
  if (!test.getConnect()) {   
  System.out.println("数据库连结错误");   
  return ;   
  }   
  try{   
    
  test.conn.setAutoCommit(false);   
  byte a[] = null; //**将测试文件test.doc读入此字节数组   
  java.io.FileInputStream fin = null;   
  java.io.FileOutputStream fout = null;   
    
  //Oracle提供的   
  try {   
  java.io.File f1 = new java.io.File("c:/test.doc");   
  java.io.File f2 = new java.io.File("d:/testout.doc"); //**从BLOB读出的信息写   
    
  //入该文 件,和源文件对比测试用   
  fin = new java.io.FileInputStream(f1);   
  fout = new java.io.FileOutputStream(f2);   
    
  int flength = (int) f1.length(); //**读入文件的字节长度   
  System.out.println("file length::" + flength);   
  a = new byte[flength];   
    
  int i = 0;   
  int itotal = 0;   
  //* 将文件读入字节数组   
  for (; itotal < flength; itotal = i + itotal) {   
  i = fin.read(a, itotal, flength - itotal);   
  }   
  fin.close();   
    
  System.out.println("read itotal::" + itotal);   
  //**注意Oracle的 BLOB一定要用EMPTY_BLOB()初始化   
  String mysql =   
  "insert into filelist (FileName,FileSize,FileBody) values (?,?,EMPTY_BLOB())";   
  OraclePreparedStatement opst = (OraclePreparedStatement) test.conn.   
  prepareStatement(mysql);   
  opst.setString(1, "wordtemplate2");   
  opst.setInt(2, flength);   
  opst.executeUpdate();   
  opst.clearParameters();   
  // /**插入其它数据后,定位BLOB字段   
  mysql = "select filebody from filelist where filename=?";   
  opst = (OraclePreparedStatement) test.conn.prepareStatement(mysql);   
  opst.setString(1, "wordtemplate2");   
  OracleResultSet ors = (OracleResultSet) opst.executeQuery();   
    
  if (ors.next()) {   
  oracle.sql.BLOB blob = ors.getBLOB(1); //**得到BLOB字段   
  int j = blob.putBytes(1, a); //**将字节数组写入BLOB字段   
  System.out.println("j:" + j);   
  test.conn.commit();   
  ors.close();   
  Clob clob;   
  clob = ors.getClob("");   
  String str;   
  str = clob.toString();   
  str = clob.getSubString(0L,(int)clob.length());   
  System.out.println(str);   
  }   
    
  System.out.println("insert into ok");   
    
  byte b[] = null; //**保存从BLOB读出的字节   
  opst.clearParameters();   
  mysql = "select filebody from filelist where filename=?";   
  opst = (OraclePreparedStatement) test.conn.   
  prepareStatement(mysql);   
  opst.setString(1, "wordtemplate2");   
  ors = (OracleResultSet) opst.executeQuery();   
  if (ors.next()) {   
  oracle.sql.BLOB blob2 = ors.getBLOB(1);   
    
  System.out.println("blob2 length:" + blob2.length());   
  b = blob2.getBytes(1, flength); //**从BLOB取出字节流数据   
  System.out.println("b length::" + b.length);   
  test.conn.commit();   
  }   
  ors.close();   
  // 将从BLOB读出的字节写入文件   
  fout.write(b, 0, b.length);   
  fout.close();   
    
  System.out.println("write itotal::" + b.length);   
    
  }   
  catch (Exception e) {   
  System.out.println("errror :" + e.toString());   
  e.printStackTrace();   
    
  }   
  finally { //**关闭所有数据联接   
  test.conn.commit();   
  }   
  }   
  catch(Exception e){   
  System.out.println(e);   
    
  }   
  }   
    
  }

方式二: 
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,?\0 JFIF\0     \0H\0H\0\0?? Exif\0\0MM\0*\0\0\0 \0    \0 \0\0\0 \0 \0\0    \0 \0\0\0 \0\0\0b 
\0 \0\0\0 \0\0\0j (\0 \0\0\0 \0 \0\0 1\0 \0\0\0 \0\0\0r 2\0 \0\0\0 \0\0\0?i\0 \0\0\0 \0\0\0\0\0\0\0\0\0H\0\0\0 
\0\0\0H\0\0\0 Adobe Photoshop CS Windows\02007:03:18 23:08:15\0\0\0\0\0 ?\0 \0\0\0 ??\0\0?\0 \0\0\0 \0\0\0? \0 
........等等
其实就是将文件先转换成了二进制的流,然后插入到了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>  
 

 

 

分享到:
评论

相关推荐

    SQL Server Text型字段读取(delphi)

    一直在用ADOQuery读取数据库字段,当遇到SQL Server数据库Text型字段时,一直读取不全,在网上搜索很多遍未解决。试探将asstring 换为 CurValue。成功!

    java读取sqlserver image字段.docx

    本文将详细介绍如何使用Java语言读取SQL Server中的`IMAGE`字段,并将其转换为图片文件。 #### 二、关键技术点 ##### 1. JDBC连接SQL Server 在Java中,通过JDBC (Java Database Connectivity) 连接SQL Server是...

    C# 对SqlServer中Image字段的读写(例子)

    在SQL Server数据库中,`Image`数据类型用于存储大量的二进制数据,如图片、文档等。在C#编程环境中,我们经常需要处理这类数据,包括从数据库读取`Image`字段并显示为图片,或者将图片数据写入数据库。本篇文章将...

    sql server中的image类型的数据导出到oracle的clob字段中

    SQL Server 中 Image 类型数据导出到 Oracle 的 CLOB 字段中 在进行数据库迁移或数据交换时,需要将不同数据库管理系统之间的数据类型进行转换。在本文中,我们将讨论如何将 SQL Server 中的 Image 类型数据导出到 ...

    sql server替换textntext类型字段的值

    在这一背景下,本文将探讨如何在SQL Server中替换text/ntext类型字段的值,并详细解释相关操作和注意事项。 首先,需要理解text和ntext数据类型的特性。text数据类型用于存储最多2GB的非Unicode文本数据,而ntext...

    sqlserver 导出表及字段说明脚本.rar

    这个压缩包"sqlserver 导出表及字段说明脚本.rar"包含了一个名为"sqlserver 导出表及字段说明脚本.sql"的文件,这通常是一个用于生成SQL语句的脚本,用于描述数据库中的表结构以及各字段的详细信息。以下是对这个...

    ORACLE中BLOB字段导入到SQL SERVER中的IMAGE字段

    而在SQL SERVER中,IMAGE字段同样用于存储大块的二进制数据,但在SQL SERVER 2005及以后的版本中已被废弃,取而代之的是VARBINARY(MAX)。 要完成这种迁移,我们需要遵循以下步骤: 1. **数据准备**:确保ORACLE...

    python 读写sqlserver image字段

    python 通过adodbapi读写sqlserver image字段类型。

    sqlserver 2005 express X64

    - 下载安装文件:首先,从微软官方网站获取SQL Server 2005 Express X64的安装包。 - 运行安装向导:双击下载的.msi文件启动安装程序,按照向导提示进行操作。 - 选择组件:可以选择安装数据库引擎、Management ...

    C# 存取SqlServer中的Image类型.txt

    当我们在C#应用程序中处理图像数据时,有时需要将这些图像存储到SQL Server数据库的特定字段,例如Image类型字段。Image类型字段在SQL Server中用于存储大对象(LOB)数据,如图像、二进制文件等。下面我们将详细...

    sqlserver字段类型介绍

    sqlserver字段类型介绍 数据库中,英文字符只需要一个字节存储就足够了,但汉字和其他众多非英文字符,则需要两个字节存储。如果英文与汉字同时存在,由于占用空间数不同,容易造成混乱,导致读取出来的字符串是乱码...

    delphi读写sqlserver二进制字段image

    在使用Delphi进行数据库开发时,经常会遇到与SQL Server中的二进制字段类型"image"交互的情况。"image"字段通常用于存储大容量的二进制数据,如图片、文档或任何其他非文本数据。本篇文章将深入探讨如何在Delphi中...

    sql server字段保存文件,blob操作

    在SQL Server 2000及之前版本中,用于存储BLOB数据的字段类型是`image`,而在2005及以上版本中,这个角色由`varbinary(MAX)`接替。 `image`字段类型在SQL Server 2000中用于存储任何长度的二进制数据,最大可达2^31...

    导出SQL server2005表字段信息说明

    ### 导出SQL Server 2005表字段信息说明 在进行数据库管理与维护时,经常需要了解数据库中各个表的字段详细信息,包括字段名称、数据类型、是否为主键、长度、精度等属性。本文将通过一个SQL查询语句来详细解析如何...

    sqlserver-oracle 数据类型对照

    本文将详细比较SQL Server和Oracle数据库之间的数据类型对应以及常用函数的转换。 首先,我们来看SQL Server和Oracle的数据类型对照: 1. **数值类型**: - `bigint`在SQL Server中对应Oracle的`NUMBER(19)`,...

    C#更新SQLServer中TimeStamp字段(时间戳)的方法

    在C#编程中,SQL Server的时间戳(TimeStamp)字段是一个特殊的数据类型,它与我们通常理解的日期时间无关,而是用来记录数据行的版本或更改信息。本文将深入探讨如何在C#中读取和更新SQL Server中的Timestamp字段。...

    SQL Server 2005报表服务的配置与开发

    SQL Server 2005报表服务是微软提供的一款强大的商业智能工具,用于创建、管理和部署各种类型的报表。在本文中,我们将深入探讨SQL Server 2005报表服务的配置与开发过程,以便帮助读者更好地理解和应用这项技术。 ...

    SQL Server中读取XML文件的简单做法

    在SQL Server中,读取XML文件并对其进行处理是数据库...在SQL Server的后续版本中,如SQL Server 2005及更高版本,处理XML的功能得到了显著增强,例如引入了XML数据类型和更强大的XML方法,使得XML操作更加简便高效。

    sqlserver中日期型字段设默认值

    在SQL Server中,日期型字段设默认值是一个重要的功能,它允许数据库管理员或开发者为特定的日期字段设定一个默认的时间点,通常是当前时间或者基于当前时间的某个偏移量。这在创建新记录时非常有用,可以自动填充...

    Sql server 获取表字段属性信息,注释信息

    从Sql server 2008获取表字段属性信息,注释信息 。注意,字段说明除非有备注才显示,如果没有的的情况下显示空白是正常的。

Global site tag (gtag.js) - Google Analytics