DB2保存图片并读取动态显示图片

博文背景:

客户要求结构化图片信息,而不是文件文档话的管理,故要求将图片信息存储于DB2里,出于技术的角度,真不喜欢将文件存储于数据库,

但客户是上帝,木有办法,故有了如下的测试。

测试环境:DB2 V9.7  JDK7  spring3.x tomcat8

本机测试结果:在第一次访问的时候动态获取的速度是直接获取的1/20的样子,如果缓存的话就无法对比了。

时间检测使用了chrome和firfox的F12工具。

写测试代码的过程中参考了网上很多文章,发现大部分都是copy来copy去,估计都没去测试过十分能行的通。

这里记录一下测试过程中遇到的麻烦吧

1、DB2保存的时候数据库是Blob类型,java里设置成byte[]才能正常保存(BinaryStream和Blob均失败).

2、读取DB2的Blob的时候不知道为何使用PreparedStatement读取不出来,使用Statement才行。

3、IO的操作比较生疏了。

表结构:

1、保存图片

上传图片的页面:

<form action="bs/test/uploadImg.do" method="post" enctype="multipart/form-data" target="testFrame">
        ID:<input type="text" name="id"/><br />
        名字:<input name="name" type="text"/><br />
        文件:<input type="file" name="img"/><br />
        <input type="submit" value="提交"/>
</form>
<iframe src="" id="testFrame" name="testFrame" height="0" width="0" frameborder="0"></iframe>

后台action示例:

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.oreilly.servlet.multipart.FilePart;
import com.oreilly.servlet.multipart.MultipartParser;
import com.oreilly.servlet.multipart.ParamPart;
import com.oreilly.servlet.multipart.Part;
@Urls("uploadImg.do")
@Ajax
public void saveFile(HttpServletRequest request){
    int fileSize = 10;
    try {
        MultipartParser mp = new MultipartParser (request, fileSize * 1024 * 1024 );
        Part part;
        int fileCount = 0;
        byte[] bt = null;
        String name = null;
        String fileName = null;
        String id = "999";
        //遍历请求中的所有表单
            while((part=mp.readNextPart())!=null){
                 if(part.isFile()){//是文件
                     FilePart fp = (FilePart)part;
                     fileName = fp.getFileName();
                     if (fileName.endsWith("png") || fileName.endsWith("gif") || fileName.endsWith("jpg") || fileName.endsWith("jpeg")) {
                         //输出流的目的是将输入流转成byte数组
                         ByteArrayOutputStream out = new ByteArrayOutputStream();
                         InputStream in = fp.getInputStream();
                         int size = 0;
                         byte[] buffer = new byte[1024];
                         while((size=in.read(buffer))!=-1){
                             out.write(buffer, 0, size);
                         }
                         bt = out.toByteArray();
                         fileCount++;
                     }else {
                        throw new Exception("文件不是图片!");
                    }
                 }else{
                    ParamPart pp = (ParamPart)part;
                    String inputName = pp.getName();
                    if("name".equals(inputName)){
                        name = pp.getStringValue();
                    }else if("id".equals(inputName)){
                        id = pp.getStringValue();
                    }
                 }
            }
            if(fileCount==0){
                throw new Exception("请选择图片后再上传!");
            }
            this.testDao.saveFile(fileName, bt, name,Integer.parseInt(id));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

dao方法:

public void saveFile(final String fileName,final byte[] bt,final String name,final int id) throws SQLException{
        String sql = "insert into SDE.T_TEST_IMG(ID,FILE_NAME,IMG_FILE,NAME) VALUES(?,?,?,?)";

        this.getJdbcTemplate().update(sql, new PreparedStatementSetter() {
            public void setValues(PreparedStatement ps) throws SQLException {
                ps.setInt(1, id);
                ps.setString(2, fileName);
                //下面这2种都会报错,网上一大堆例子都是这么写的,很诧异..............
                //ps.setBinaryStream(3, fis, fileSize);
                //ps.setBlob(3, fis);
                ps.setBytes(3, bt);

                ps.setString(4, name);
            }
        });
    }

2、读取图片

前台:

<input type="button" onclick="setUrl()" value="加载图片"/>

<img src="" alt="动态生成" id="dImg"/>
<img src="" alt="直接获取" id="sImg"/>

js:

function setUrl(){
//动态生成同样的图片
document.getElementById("dImg").src="generationImg?id=3";
//直接访问图片
document.getElementById("sImg").src="mobileImage/17074_20130927160025.jpg";
}

处理生成图片的servlet:

/**
     * 从数据库里读取Blob类型的图片并显示给前台
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String id = request.getParameter("id");
        response.setContentType("image/jpeg");
        TestDao testDao = (TestDao)WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext()).getBean(TestDao.class);
        InputStream ins = null;
        try {
            ins = testDao.loadFile(id);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //从输入流构建图片
        BufferedImage image = null;
        image = ImageIO.read(ins);
        ServletOutputStream out = response.getOutputStream();
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(image);

        ins.close();
        out.flush();
        out.close();
    }

dao方法:

/**
     * 读取DB2的blob字段并转换成流
     * @param id
     * @return
     * @throws SQLException
     */
    public InputStream loadFile(String id) throws SQLException{
        String sql = "select IMG_FILE from SDE.T_TEST_IMG where ID="+id;
        InputStream ins = null;

        Connection con = this.getJdbcTemplate().getDataSource().getConnection();
        Statement ps = con.createStatement();
        ResultSet rs = ps.executeQuery(sql);
        while(rs.next()){
            Blob blob = rs.getBlob("IMG_FILE");
            ins = blob.getBinaryStream();
        }
        return ins;

        //下面这个写法会有问题,而且上面那个Statement改成PrepareStatement后也获取不到值,ResultSet是null
        /*
           InputStream ins = this.getJdbcTemplate().execute(sql, new PreparedStatementCallback() {

            public Object doInPreparedStatement(PreparedStatement ps)
                    throws SQLException, DataAccessException {
                ResultSet rs = ps.getResultSet();
                Blob blob = rs.getBlob(1);
                InputStream ins = blob.getBinaryStream();
                return ins;
            }
        });
        return ins;*/
    }

DB2保存图片并读取动态显示图片

时间: 2024-11-05 15:49:15

DB2保存图片并读取动态显示图片的相关文章

android 读取,写入图片到sd卡源码

<pre name="code" class="html"><!--<span style="font-family: Arial, Helvetica, sans-serif;">在AndroidMainfest.xml文件中添加</span><span style="font-family: Arial, Helvetica, sans-serif;">-->&l

【原创】Android 4.4前后版本读取图库图片方式的变化

Android 4.4前后版本读取图库图片方式的变化 本文讲述Android 4.4(KitKat)前后访问图库以及访问后通过图片路径读取图片的变化 Android 4.4(KitKat)以前: 访问图库(方法一): 1 /** 2 * Access the gallery to pick up an image. 3 */ 4 private void startPickPhotoActivity() { 5 Intent intent = new Intent(Intent. ACTION_

读取本地图片写到jsp页面

//读取本地图片写到jsp页面 File file = new File("D:/parking/A区12号.jpg"); ServletOutputStream out = null; InputStream in = null; try { in = new FileInputStream(file); response().setContentType("multipart/form-data"); int tempbyte; out = response()

C#从SQL server数据库中读取l图片和存入图片

原文:C#从SQL server数据库中读取l图片和存入图片 本实例主要介绍如何将图片存入数据库.将图片存入数据库,首先要在数据库中建立一张表,将存储图片的字段类型设为Image类型,用FileStream类.BinaryReader把图片读成字节的形式,赋给一个字节数组,然后用ADO.SqlCommand对象的ExecuteNonQuery()方法来把数据保存到数据库中.主要代码如下: private void button1_Click(object sender, EventArgs e)

OpenGL使用libPng读取png图片

#include<stdarg.h> #include<png.h> #include<glut.h> #include<math.h> #include<iostream> #pragma comment(lib,"libpng16.lib")//读取png图片 GLuint CreateTextureFromPng(const char* filename) { unsigned char header[8]; //8 i

利用CSS切割图片技术来动态显示图片

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Typ

数据库读取二进制图片显示到PictureBox中

1.已知路径,加载本地图片到Image中 Image img = Image.FromFile("路径"); 2.数据库中读取二进制图片 string strSql = "Select Top 1 ImageContent From TT_ImageFileSave)"; Byte[] byteImage = new Byte[0]; byteImage = (Byte[])(DbHelperSQL.GetSingle(strSql)); MemoryStream

Android 简单图片浏览器 读取sdcard图片+形成缩略图+Gallery

1.读取SD卡上面的图片信息 //想要的返回值所在的列 String[] projection = { MediaStore.Images.Thumbnails._ID}; //图片信息存储在 android.provider.MediaStore.Images.Thumbnails数据库 //快速查询数据库中的图片对应存放路劲 Cursor cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, pro

java读取jpg图片旋转按比例缩放

1 //入口 2 public static BufferedImage constructHeatWheelView(int pageWidth, int pageHeight, DoubleHolder scaleHolder) throws ValidateException{ 3 4 BufferedImage bi = new BufferedImage(pageWidth, pageHeight, BufferedImage.TYPE_INT_RGB); 5 Graphics2D g