`

插入图片/文本(blob /clob)到oracle数据库

阅读更多
我们在写OA的时候经常遇到的问题就是员工图片档案的储存问题,解决这个问题有两个方法,<o:p></o:p>

1.JSPhtml页面里面读取web服务器上的图片,也就是把图片放到(上传)到web 服务器上,然后用html 语句读取:<o:p></o:p>

绝对或相对路径 " border="0" /><o:p></o:p>

2.就是上传到数据库里面(oracle).关于oracle 数据库,它支持blob, clob, 分别对应着图片和文本(长字符串)操作<o:p></o:p>

由于性能原因,我们还是要采用第二种方法,而且存到数据库里面比较容易管理,是吧?<o:p></o:p>

<o:p> </o:p>

首先,我们要解决上传问题,这里采用普遍使用的apache commons 组件里面的FileUpload class.<o:p></o:p>

具体步骤如:<o:p></o:p>

<o:p> </o:p>

DiskFileUpload dfu=new DiskFileUpload();<o:p></o:p>

  dfu.setSizeMax(100000000);<o:p></o:p>

  dfu.setSizeThreshold(100000);<o:p></o:p>

  dfu.setRepositoryPath("f:\\public");<o:p></o:p>

  <o:p></o:p>

  try{<o:p></o:p>

  List fileItems=dfu.parseRequest(request);<o:p></o:p>

  Iterator i=fileItems.iterator();<o:p></o:p>

  <o:p></o:p>

  while(i.hasNext()){<o:p></o:p>

  FileItem fi=(FileItem)i.next();<o:p></o:p>

  if(!fi.isFormField()){<o:p></o:p>

  name=fi.getName();                    <o:p></o:p>

  size=fi.getSize();                     <o:p></o:p>

  if((name==null||name.equals(""))&&size==0)<o:p></o:p>

  continue;<o:p></o:p>

                        }<o:p></o:p>

  name=fi.getName();<o:p></o:p>

  size=fi.getSize();<o:p></o:p>

  (InputStream)is=fi.getInputStream();<o:p></o:p>

  <o:p></o:p>

                    }<o:p></o:p>

                    <o:p></o:p>

上面的代码是web服务器接受上传的代码,参考文件已经在我上篇写的上传文本文件里给出,今天,终于想明白了:<o:p></o:p>

dfu.setRepositoryPath("f:\\public"); 的意思<o:p></o:p>

原来是转义字符也就是说\n\t等而要打印反斜杠要用\\,其实这个问题原先已经知道,可是由于经验没有写过图片上传处理什么的,觉得很高深,也很可怕,哈哈,心里有点畏惧.看来基础的东西,那怕一点点小细节也很重要,接着还有下面的java IO 问题.刚才读core java 的时候突然发现在讲io的时候特意提醒了这个问题,可是我没有注意!<o:p></o:p>

<o:p> </o:p>

通过上面的代码已经实现文件上传了.然后,我们要实现JDBC数据源链接,目的是要把数据插入到oracle.<o:p></o:p>

                   <o:p></o:p>

  Context ctx=new InitialContext();<o:p></o:p>

  DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");<o:p></o:p>

  conn=ds.getConnection();<o:p></o:p>

  conn.setAutoCommit(false);<o:p></o:p>

关于要import java.sql.* javax.sql.* java.naming.* 不再详细叙述了<o:p></o:p>

接着根据很有用的一篇文章的提示,插入blob类型一定要先1.插入一个空的<o:p></o:p>

  String insert=" insert into uploadpicture "+<o:p></o:p>

                " values(?, empty_blob()) "     ;<o:p></o:p>

2.然后找到这个bloboracle 里面的游标:<o:p></o:p>

String findCursor=" select content "+<o:p></o:p>

                    " from uploadpicture "+<o:p></o:p>

                    " where name=?  for update ";<o:p></o:p>

注意这个for update(注意!!!必须加for update,这将锁定该行,直至该行被修改完毕,保证不产生并发冲突。这里还是难以理解,先记下来吧)<o:p></o:p>

3.然后再修改<o:p></o:p>

String update=" update uploadpicture  "+<o:p></o:p>

                " set content=? "+<o:p></o:p>

                " where name=? ";<o:p></o:p>

这里的问号是为PreparedStatement参数处理而写的!<o:p></o:p>

<o:p> </o:p>

写这个程序用到了oracle.sql.BLOB class ,这个类是用来操作BLOB数据类型的<o:p></o:p>

当我们通过ResultSet 对象得到<o:p></o:p>

blob=(BLOB)rs.getBlob(1);<o:p></o:p>

的时候我不知道如何处理了,Blob 是什么?String, int ,long? 我现在也不明白!估计CSDN上的人也不明白,否则我发个帖子半天,也许是很烂,也许是太简单了,大家不屑一顾,看来我还要继续追赶!<o:p></o:p>

不发牢骚了,回到程序里(总觉得自己的发散思维很强,看来写程序的时候不能这样,多亏java 是纯面向对象语言,如果是过程就麻烦了)<o:p></o:p>

我们如何处理这个blob ?回答是,不管它是什么,直接写入  BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());<o:p></o:p>

这里是建立了缓冲写如blob 的流(注意getBinaryOutputStream()已经不被赞成使用了,一定有更优秀的方法替代!),说到流,我到现在还有点晕,类很多,不知道究竟用哪个好!<o:p></o:p>

基础的东西非常重要,这曾经是我的口头禅,这里用到了流的读入写和写入,有些流是从文件或其它位置上读取字节(, FileInputStream),有写流是把字节组合成有用的数据(, DataInputStream).我们读取数字的时候,需要首先建议一个FileInpuStream, 然后, 再把该类的对象传递给DataInputStream<o:p></o:p>

FileInputStream fin=new FileInputStream(“emp.dat”);<o:p></o:p>

DataInputStream din=new DataInputStream(fin);//fin传递给din<o:p></o:p>

double s=din.readDouble();<o:p></o:p>

默认情况下,流是没有缓冲的, 如果使用缓冲就是<o:p></o:p>

DataInputStream din=new DataInputStream(<o:p></o:p>

new BufferedInputStream(new FileINputStream(“emp.dat”)));<o:p></o:p>

<o:p> </o:p>

有了这点理解也很管用,<o:p></o:p>

  BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());<o:p></o:p>

就是建立一个缓冲写的对象到blob.注意这里的out1 不是out,否则程序运行的时候不能打印了temp 数据了!<o:p></o:p>

已经准备好如何写了, 可是如何读呢?<o:p></o:p>

BufferedInputStream in=new BufferedInputStream(is);<o:p></o:p>

在我们上传的时候  (InputStream)is=fi.getInputStream();<o:p></o:p>

读取图片为输入的流.保存为is 对象,然后就用到这里了,准备好了读和写了,我们开始干活:<o:p></o:p>

int c;<o:p></o:p>

  while((c=in.read())!=-1) {out1.write(c);}<o:p></o:p>

  in.close();<o:p></o:p>

  out1.close();<o:p></o:p>

通过缓冲一个个读数据,然后一个个写数据.-1 为文件的末尾,<o:p></o:p>

最后当读写完成后我们要关闭读写对象!<o:p></o:p>

程序分析就是这样,以后还要对此问题进行研究,最后还要注意,<o:p></o:p>

<%@ page contentType="image/jpeg;charset=GBK"%><o:p></o:p>

不是<o:p></o:p>

<%@ page contentType="text/html;charset=GBK"%><o:p></o:p>

否则是以文字显示图片---乱码.<o:p></o:p>

<o:p> </o:p>

这里研究了上传图片到oralce 里面的程序,关于显示还要麻烦一点,借助资料我实现了,明天再研究一下.<o:p></o:p>

<o:p> 
</o:p>

<o:p> //插入上传图片到数据库
<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.util.*"%>
<%@ page import="java.io.*"%>
<%@ page import="org.apache.commons.*"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<%@ page import="oracle.sql.*"%>
<html>
 
 
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    getPicture.jsp
  </head>
 
 
 
 
  <body>
 
  <%
  request.setCharacterEncoding("GBK");
   
 
  String name=null;
  long size=0;
 
  Connection conn=null;
  String insert=" insert into uploadpicture "+
                " values(?, empty_blob()) "     ;
 
  String findCursor=" select content "+
                    " from uploadpicture "+
                    " where name=?  for update ";
 
  String update=" update uploadpicture  "+
                " set content=? "+
                " where name=? ";
  BLOB blob=null;
    InputStream is=null;
 
  DiskFileUpload dfu=new DiskFileUpload();
  dfu.setSizeMax(100000000);
  dfu.setSizeThreshold(100000);
  dfu.setRepositoryPath("f:\\public");
 
  try{
  List fileItems=dfu.parseRequest(request);
  Iterator i=fileItems.iterator();
 
  while(i.hasNext()){
  FileItem fi=(FileItem)i.next();
  if(!fi.isFormField()){
  name=fi.getName();                   
  size=fi.getSize();                    
  if((name==null||name.equals(""))&&size==0)
  continue;
                        }
  name=fi.getName();
  size=fi.getSize();
  is=fi.getInputStream();
 
                    }
                   
  Context ctx=new InitialContext();
  DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");
  conn=ds.getConnection();
  conn.setAutoCommit(false);
 
  //step 1
  PreparedStatement ps=conn.prepareStatement(insert);
  ps.setString(1, name);
  int a=ps.executeUpdate();
  if(a>0)
  out.println("insert success!"+"
");
 
  //step 2
  ps=conn.prepareStatement(findCursor);
  ps.setString(1, name); 
  ResultSet rs=ps.executeQuery();
  while(rs.next())
  {
  blob=(BLOB)rs.getBlob(1);
 
 
   out.println("find cursor success!"+"
");
   out.println("cursor            :"+blob+"
");
  //step 3
  ps=conn.prepareStatement(update);
  ps.setBlob(1, blob);
  ps.setString(2, name);
  ps.executeUpdate();
  ps.close();
  BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());
  BufferedInputStream in=new BufferedInputStream(is);
  int c;
  while((c=in.read())!=-1) {out1.write(c);}
  in.close();
  out1.close();
  out.println("update success!"+"
");}
  conn.commit();
  }
 
  catch(SQLException se)
  {se.printStackTrace();}
  catch(FileUploadException fue)
  {fue.printStackTrace();}
  %>
 
 
  </body></o:p>

<o:p></html>


//显示数据库里面的图片

<%@ page contentType="image/jpeg;charset=GBK"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<%@ page import="java.io.*"%>
<%@ page import="com.sun.image.codec.jpeg.*"%>
<%@ page import="javax.imageio.*"%>
<%@ page import="java.util.*"%>
<%@ page import="java.awt.image.*"%></o:p>

<o:p> </o:p>


<html>
 
 
 
  <head>
    <meta http-equiv="Content-Type" content="image/jpeg; charset=GBK">
    showDBImage.jsp
  </head>
 
 
 
  <body>
  <%
  String showImage=" select * "+
                   " from uploadpicture "+
                   " where name='TXC with snow.JPG' " ;
  Connection conn=null;
  BufferedInputStream inputImage=null;
 
 
  try{
  Context ctx=new InitialContext();
  DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");
  conn=ds.getConnection();
  Statement st=conn.createStatement();
  ResultSet rs=st.executeQuery(showImage);
  while(rs.next())
  {
  oracle.sql.BLOB blob=(oracle.sql.BLOB)rs.getBlob("content");
  inputImage =new BufferedInputStream(blob.getBinaryStream());
  /*String name=rs.getString(1);
  String content=rs.getString(2);
  out.println(name+"
");*/}
 
  BufferedImage image=null;
  image=ImageIO.read(inputImage);
 
  ServletOutputStream sos=response.getOutputStream();
  JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(sos);
  encoder.encode(image);
  inputImage.close();
  conn.commit();
 
  }
  catch(SQLException se)
  {se.printStackTrace();
  conn.rollback();  }
  catch(IOException ie)
  {ie.printStackTrace();} 
  %>
 
  </body>


</html>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics