在实际的开发中,我们可能需要将图片、影音等文件直接保存到数据库中,然后通过编程方式将数据读出进行使用。例如将读出的图片数据显示出来,将读出的电影文件播放出来。

二进制数据直接保存到文件和从文件中读出非常的简单。和普通的数据库操作差别不大。只是用到部分流操作。例如各种输入输出流操作。所以深刻理解流操是非常重要的。

在此我借助于一个JSP的简单实例进行讲解。此实例保存职员数据,其中职员数据包含一个图片列。此列保存每名员工的照片。在此将照片直接保存到数据库中。首先建立职员信息表EmployeeInfo,表列非常的简单

employeeId:职员编号(自动增长);employeeName:职员姓名;age:职员年龄;pic:职员图片(image类型)

首先讲解信息的保存。先建立一个录入界面index.jsp,其中包含一个<input type="file"/>元素,用于让用户选择图片文件。

页面代码如下(不做过多讲解):

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
  
  <body>
    <form action="addServlet" method="POST">
     <table border="15" width="60%" align="center">
      <tr>
       <td width="30%" align="right">EmployeeName:</td>
       <td width="70%" align="left"><input type="text" name="employeeName"/></td>
      </tr>
      <tr>
       <td width="30%" align="right">Age:</td>
       <td width="70%" align="left"><input type="text" name="age"/></td>
      </tr>
      <tr>
       <td width="30%" align="right">Image:</td>
       <td width="70%" align="left"><input type="file" name="pic"/></td>
      </tr>
      <tr>
       <td colspan="2" align="center"><input type="submit" value="add"/></td>
      </tr>      
     </table>
    </form>
  </body>
</html>

页面请求addServlet,获取录入信息,并调用JavaBean实现数据保存。Servlet代码如下:

package com.frank.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.frank.rule.*;
public class AddServlet extends HttpServlet {

/**
  * Constructor of the object.
  */
 public AddServlet() {
  super();
 }

/**
  * Destruction of the servlet. <br>
  */
 public void destroy() {
  super.destroy(); // Just puts "destroy" string in log
  // Put your code here
 }

/**
  * The doGet method of the servlet. <br>
  *
  * This method is called when a form has its tag value method equals to get.
  * 
  * @param request the request send by the client to the server
  * @param response the response send by the server to the client
  * @throws ServletException if an error occurred
  * @throws IOException if an error occurred
  */
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

String employeeName=request.getParameter("employeeName");
  int age=Integer.parseInt(request.getParameter("age"));
  String pic=request.getParameter("pic");
  EmployeeDAO employeeDAO=new EmployeeDAO();
  if(employeeDAO.employeeAdd(employeeName, age, pic))
   response.sendRedirect("success.jsp");
  else
   response.sendRedirect("index.jsp");
  
 }

/**
  * The doPost method of the servlet. <br>
  *
  * This method is called when a form has its tag value method equals to post.
  * 
  * @param request the request send by the client to the server
  * @param response the response send by the server to the client
  * @throws ServletException if an error occurred
  * @throws IOException if an error occurred
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

doGet(request,response);
 }

/**
  * Initialization of the servlet. <br>
  *
  * @throws ServletException if an error occurs
  */
 public void init() throws ServletException {
  // Put your code here
 }

}

此Servlet只是简单的获取页面输入的数据,其中获取的Pic为用户选择的图片路径。严格讲,获取文件需要经过验证,防止非法图片的选择,这个可以根据自己的需要改善。然后Servlet调用业务类,将获取的数据通过参数传入,进行数据的增加。其中employeeAdd方法实现数据的保存,代码如下:

public boolean employeeAdd(String employeeName,int age,String pic){
  Connection conn=null;
  PreparedStatement pstmt=null;
  FileInputStream fis=null;
  try{
   Class.forName("net.sourceforge.jtds.jdbc.Driver");
   conn=DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/SampleDB","sa","");
   fis=new FileInputStream(pic);
   
   String strSQL="INSERT INTO employeeInfo VALUES(?,?,?)";
   pstmt=conn.prepareStatement(strSQL);
   pstmt.setString(1, employeeName);
   pstmt.setInt(2, age);
   pstmt.setBinaryStream(3, fis, fis.available());
   if(pstmt.executeUpdate()>0)
    return true;
   else
    return false;
  }catch(ClassNotFoundException ex){
   ex.printStackTrace();
   return false;
  }catch(SQLException ex){
   ex.printStackTrace();
   return false;
  }catch(IOException ex){
   ex.printStackTrace();
   return false;
  }finally{
   try{
    fis.close();
    pstmt.close();
    conn.close();
   }catch(Exception ex){
    
   }
  }
 }

注意粗体部分,用获取的pic信息(文件路径)创建文件输入流对象,增加pic字段的内容通过流对象增加。

pstmt.setBinaryStream(3, fis, fis.available());
三个参数分别为:参数索引,流对象,流对象大小

当增加成功时,重定向到success.jsp

运行结果如下:

增加后,显示如下代表成功:

那么如何验证图片数据是否保存到了数据库中呢?我们通过再次检索增加的数据,读出增加的图片数据并在页面中显示出来进行验证。

首先建立一个非常简单的页面search.jsp,此页面通过文本框使用户输入要检索的人员的姓名,检索人员的基本信息(不检索图片数据),将检索的人员数据形成JOPO对象,保存到session中,以便页面使用。

POJO类(EmployeeObj)

package com.frank.obj;

public class EmployeeObj {
 private int employeeId;
 private String employeeName;
 private int age;
 public int getEmployeeId() {
  return employeeId;
 }
 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }
 public String getEmployeeName() {
  return employeeName;
 }
 public void setEmployeeName(String employeeName) {
  this.employeeName = employeeName;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 
}

search.jsp页面代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'search.jsp' starting page</title>
    
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->

</head>
  
  <body>
    <form action="searchServlet" method="POST">
     employeeName:<input type="text" name="employeeName"/>
     <input type="submit" value="search"/>
    </form>

  </body>
</html>

通过searchServlet实现基本信息的检索

package com.frank.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.frank.obj.EmployeeObj;
import com.frank.rule.EmployeeDAO;

public class SearchServlet extends HttpServlet {

/**
  * Constructor of the object.
  */
 public SearchServlet() {
  super();
 }

/**
  * Destruction of the servlet. <br>
  */
 public void destroy() {
  super.destroy(); // Just puts "destroy" string in log
  // Put your code here
 }

/**
  * The doGet method of the servlet. <br>
  *
  * This method is called when a form has its tag value method equals to get.
  * 
  * @param request the request send by the client to the server
  * @param response the response send by the server to the client
  * @throws ServletException if an error occurred
  * @throws IOException if an error occurred
  */
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

String employeeName=request.getParameter("employeeName");
  EmployeeDAO employeeDAO=new EmployeeDAO();
  EmployeeObj employeeObj=employeeDAO.getEmployeeByName(employeeName);
  HttpSession session=request.getSession();
  session.setAttribute("employee", employeeObj);
  response.sendRedirect("display.jsp");
 }

/**
  * The doPost method of the servlet. <br>
  *
  * This method is called when a form has its tag value method equals to post.
  * 
  * @param request the request send by the client to the server
  * @param response the response send by the server to the client
  * @throws ServletException if an error occurred
  * @throws IOException if an error occurred
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

doGet(request,response);
 }

/**
  * Initialization of the servlet. <br>
  *
  * @throws ServletException if an error occurs
  */
 public void init() throws ServletException {
  // Put your code here
 }

}

此Servlet调用业务类的getEmployeeByName方法检索人员基本信息,返回EmployeeObj对象,并放入session中,当然也可以放入request中,根据自己的需要改进。页面检索成功后重定向到display.jsp进行信息的显示(稍后讲解)

getEmployeeByName方法代码如下:

public EmployeeObj getEmployeeByName(String employeeName){
  Connection conn=null;
  PreparedStatement pstmt=null;
  ResultSet rst=null;
  EmployeeObj employeeObj=new EmployeeObj();
  try{
   Class.forName("net.sourceforge.jtds.jdbc.Driver");
   conn=DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/SampleDB","sa","");
   
   String strSQL="SELECT employeeId,employeeName,age FROM EmployeeInfo WHERE employeeName=?";
   pstmt=conn.prepareStatement(strSQL);
   pstmt.setString(1, employeeName);
   rst=pstmt.executeQuery();
   if(rst.next()){
    employeeObj.setEmployeeId(rst.getInt("employeeId"));
    employeeObj.setEmployeeName(rst.getString("employeeName"));
    employeeObj.setAge(rst.getInt("age"));
    return employeeObj;
   }
   return null;
  }catch(ClassNotFoundException ex){
   ex.printStackTrace();
   return null;
  }catch(SQLException ex){
   ex.printStackTrace();
   return null;
  }finally{
   try{
    pstmt.close();
    conn.close();
   }catch(Exception ex){
    
   }
  }
 }

display.jsp负责显示查询出的结果信息,代码如下:

<%@ page language="java" import="java.util.*,com.frank.obj.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'display.jsp' starting page</title>
    
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
 <%
  EmployeeObj employeeObj=(EmployeeObj)session.getAttribute("employee");
  %>
  </head>
  
  <body>
    <table width="80" border="15">
     <tr>
      <td width="30%" align="right">EmployeeId</td>
      <td width="70%" align="left"><%=employeeObj.getEmployeeId() %></td>
     </tr>
     <tr>
      <td width="30%" align="right">EmployeeName</td>
      <td width="70%" align="left"><%=employeeObj.getEmployeeName() %></td>
     </tr>
     <tr>
      <td width="30%" align="right">Age</td>
      <td width="70%" align="left"><%=employeeObj.getAge() %></td>
     </tr>
     <tr>
      <td width="30%" align="right">Pic</td>
      <td width="70%" align="left"><img src="displayServlet?employeeId=<%=employeeObj.getEmployeeId() %>"/></td>
     </tr>     
    </table>
  </body>
</html>

代码非常的简单,只是简单的从session中获取保存的EmployeeObj对象,然后利用jsp表达式将数据成员信息显示到页面上。但是注意粗体部分,因为我们需要将保存的图片数据读出,然后显示成图片。所以在此我们利用Img元素显示图片,而Src利用displayServlet的运行结果输出到客户端,作为图片的显示源。displayServlet包含参数employeeId,用来决定具体显示哪一员工的图片。

displayServlet通过Servlet输出流,将读取的图片数据发送到客户端,代码如下:

package com.frank.action;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.frank.rule.EmployeeDAO;

public class DisplayServlet extends HttpServlet {

/**
  * Constructor of the object.
  */
 public DisplayServlet() {
  super();
 }

/**
  * Destruction of the servlet. <br>
  */
 public void destroy() {
  super.destroy(); // Just puts "destroy" string in log
  // Put your code here
 }

/**
  * The doGet method of the servlet. <br>
  *
  * This method is called when a form has its tag value method equals to get.
  * 
  * @param request the request send by the client to the server
  * @param response the response send by the server to the client
  * @throws ServletException if an error occurred
  * @throws IOException if an error occurred
  */
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  
  response.setContentType("image/gif");
  int employeeId=Integer.parseInt(request.getParameter("employeeId"));
  EmployeeDAO employeeDAO=new EmployeeDAO();
  InputStream is=employeeDAO.getPicById(employeeId);
  int size=is.available();
  byte[] image=new byte[size];
  is.read(image);
  ServletOutputStream out=response.getOutputStream();
  out.write(image);

  
 }

/**
  * Initialization of the servlet. <br>
  *
  * @throws ServletException if an error occurs
  */
 public void init() throws ServletException {
  // Put your code here
 }

}
在此,调用业务类的getPicById方法得到图片数据的输入流。然后获取的输入流写到ServletOutputStream,这样可以在Servlet的输出端使用,即img的src中使用

getPicById代码如下:

public InputStream getPicById(int employeeId){
  Connection conn=null;
  PreparedStatement pstmt=null;
  ResultSet rst=null;
  InputStream is=null;
  try{
   Class.forName("net.sourceforge.jtds.jdbc.Driver");
   conn=DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/SampleDB","sa","");
   
   String strSQL="SELECT pic FROM EmployeeInfo WHERE employeeId=?";
   pstmt=conn.prepareStatement(strSQL);
   pstmt.setInt(1, employeeId);
   rst=pstmt.executeQuery();
   if(rst.next()){
    is=rst.getBinaryStream("pic");
    return is;
   }
   return null;
  }catch(ClassNotFoundException ex){
   ex.printStackTrace();
   return null;
  }catch(SQLException ex){
   ex.printStackTrace();
   return null;
  }finally{
   try{
    pstmt.close();
    conn.close();
   }catch(Exception ex){
    
   }
  }
 }

注意粗体部分

好了,我们可以通过运行结果来进行验证,假设我们搜索名称为Mike的人员数据,那么这样:

点search按钮,运行结果如下:

好了,显示出了检索结果,不但包括人员的基本数据,保存到数据库中的图片数据也被读出并显示成图片。

代码只是利用jsp简单的进行体现,大家可以根据自己的需要进行改进。

Java中将图片保存到数据库中的更多相关文章

  1. iOS9中将图片保存到照片中的某个相册的方法说明

    iOS9中将图片保存到照片中的某个相册的方法说明 在App中很经常遇到的就是用户点击某张图片后将图片保存到本地,下面介绍下iOS中保存图片的一些东西 1.首先,在iOS中把图片保存到系统照片是比较简单 ...

  2. [原创]Java调用PageOffice在线打开数据库中保存的Word文件

    PageOffice产品和数据库是两个独立的概念,严格来说两者之间没有任何本质关系.PageOffice不依赖数据库而存在,但是数据库和PageOffice可以结合使用来完成某些复杂的业务逻辑.例如: ...

  3. C# 图片保存到数据库和从数据库读取图片并显示

    图片保存到数据库的方法: public void imgToDB(string sql)        {   //参数sql中要求保存的imge变量名称为@images            //调 ...

  4. java.sql.date与java.util.date区别以及数据库中插入带时分秒的时间

    java.sql.Date,java.sql.Time和java.sql.Timestamp三个都是java.util.Date的子类(包装类). java.sql.Date是java.util.Da ...

  5. 把MP3保存到数据库中

    使用JdbcUtils得到连接con java.sql包下的Interface Blob----其实现类SerialBlob Blob是一个可以存储二进制文件的容器. BLOB常常是数据库中用来存储二 ...

  6. 图片保存到数据库以及C#读取图片

    图片保存到数据库,如果是sqlserver就是Image类型,如果保存到Oracle就是blob类型,在c#中相对应的就是byte[]类型,同时只需要对读出的数据强制转换就行(byte[])objec ...

  7. 把Dev的excel表格用clientdataset保存到数据库中。

    网上很多,如何把图片.word.excel等保存到数据库中.可是自己就是死活出现异常,百思不得其解.原因找到了,为什么没有去弄明白: 在sql server字段类型中,我把存储字段设成binary,结 ...

  8. PHP把图片保存到数据库,将图片本身保存在数据库,而非保存路径

    备注 百度开发者的云代码空间为了保证高可用,不允许用户将图片保存到代码空间中,使用CDN或者对象存储不仅收费而且使用比较复杂,于是考虑能否将img存储在数据库中,虽然很多人说会造成性能问题,权当一试 ...

  9. XAF:如何让用户在运行时个性化界面并将个性化信息保存到数据库中 win/web/entityframework/xpo

    本主题介绍如何启用管理模型差异(XAFML),并将设置存储在数据库中.   名词解释: 1.模型:XAF中把所有应用程序的结构都用模型来定义,比如列表,有哪些列,名称是什么,对应的字段名是什么,业务对 ...

随机推荐

  1. 新手C#参数类型ref、out、params的学习2018.08.04

    ref用于传递参数时,将实参传递到函数中,是引用参数,在使用前必须被赋值.string类型也同样适用. static void Main(string[] args) { string a1,a2; ...

  2. [leetcode]621. Task Scheduler任务调度

    Given a char array representing tasks CPU need to do. It contains capital letters A to Z where diffe ...

  3. sort_contours_xld算子的几种排序方式研究

    算子sort_contours_xld算子有5种排序方式,即: 'upper_left': The position is determined by the upper left corner of ...

  4. 使用MySQLMTOP监控MySQL性能

    一.服务器角色 服务器角色 172.18.35.29 10.160.22.14 (MySQL Master) 10.160.22.47 (MySQL Slave) 监控点 YES NO NO 被监控点 ...

  5. 20155317 2016-2017-2 《Java程序设计》第7周学习总结

    20155317 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 1.在只有Lambda表达式的情况下,参数的类型必须写出来. 2.Lambda表达式本身是中 ...

  6. 深入浅出谈数据挖掘zz

    编者的话:本文对数据挖掘概念的产生,数据挖掘与常规数据分析的主要区别,所能解决的几大类问题和所应用的领域都有着非常清晰的论述.作者在此篇文章中认为数据挖掘最重要的要素是分析人员的相关业务知识和思维模式 ...

  7. 借用服务器百度BAE

    3一.简介 对于普通的开发者,不必要买服务器和买域名,这时要将自己的项目传到服务器上,就用到了百度BAE这样的,可以直接传项目的服务器. 二.申请 登录百度开放平台上 三.登录网址,选择要使用的项目 ...

  8. 一文读懂 超简单的spark structured stream 源码解读

    为了让大家理解structured stream的运行流程,我将根据一个代码例子,讲述structured stream的基本运行流程和原理. 下面是一段简单的代码: val spark = Spar ...

  9. jQuery框架-3.jQuery自定义封装插件和第三方插件

    一.jQuery的封装扩展 1.jQuery中extend方法使用 (挂在到jQuery和jQuery.fn两对象身上的使用) 1.1.官方文档定义: jQuery.extend   Merge th ...

  10. Android各国语言Values文件夹命名规则

    android多国语言文件夹文件汇总如下: 中文(中国):values-zh-rCN 中文(台湾):values-zh-rTW 中文(香港):values-zh-rHK 英语(美国):values-e ...