Java中将图片保存到数据库中

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

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

在此我借助于一个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简单的进行体现,大家可以根据自己的需要进行改进。

时间: 2024-12-16 03:24:33

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

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

PageOffice产品和数据库是两个独立的概念,严格来说两者之间没有任何本质关系.PageOffice不依赖数据库而存在,但是数据库和PageOffice可以结合使用来完成某些复杂的业务逻辑.例如:PageOffice可以打开数据库中的二进制流文件,也可以将Word或者Excel整个文档或者文档中的一部分数据保存到数据库中,这里的数据库可以是任意数据库,如:Sqlite,Access,SQL Server,Oracle,MySQL,DB2,Sybase等.下面我们就此问题展开详细论述. 1)打

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

图片保存到数据库的方法: public void imgToDB(string sql)        {   //参数sql中要求保存的imge变量名称为@images            //调用方法如:imgToDB("update UserPhoto set [email protected] where UserNo='" + temp + "'");            FileStream fs = File.OpenRead(t_photo.Te

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

java.sql.Date,java.sql.Time和java.sql.Timestamp三个都是java.util.Date的子类(包装类). java.sql.Date是java.util.Date的子类,是一个包装了毫秒值的瘦包装器,允许 JDBC 将毫秒值标识为 SQL DATE 值.毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以来经过的毫秒数. 为了与 SQL DATE 的定义一致,由 java.sql.Date 实例包装的毫秒值必须通过将时间.分钟.秒和毫

FMDB使用的一点心得:数据库创建、制表、查询等以及image转换成二进制nsdata保存到数据库中

<span style="font-size:18px;">//首先,获取数据库的路径,(如果不存在,就是我们想要存储的路径),不用担心每次都创建数据库会重复,不会的,如果没有则创建,有了就不会再重复创建: //接下来,我们要制表,首先我们先查看我们的表是否已经存在,方法在下面代码中:如果存在则跳过,不存在则创建</span> -(void)DataBaseInit { //获取Document文件夹下的数据库文件,没有则创建 NSString *dbPath

二进制数据将图片保存到数据库,并读取数据库二进制数据显示图片

一. 浏览图片 OpenFileDialog ofd = new OpenFileDialog();            ofd.InitialDirectory = @"E:\";            ofd.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files(*.*)|*.*";            ofd.RestoreDirectory = true; if (ofd

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

图片保存到数据库,如果是sqlserver就是Image类型,如果保存到Oracle就是blob类型,在c#中相对应的就是byte[]类型,同时只需要对读出的数据强制转换就行(byte[])object. 1. 将图片保存为byte数组 //参数是图片路径,返回Byte[]类型 public byte[] GetPictureData(string imagepath) { FileStream file = new FileStream(imagepath, FileMode.Open); b

Python爬虫项目,获取所有网站上的新闻,并保存到数据库中,解析html网页等

1.需求说明 需求: 爬取虎嗅网站的所有新闻,并保存到数据库中. http://www.huxiu.com 技术: 1.爬虫 获取服务器的资源(urllib) 解析html网页(BeautifulSoup) 2.数据库技术 数据库 MySQLdb 业务逻辑的分析: (1).虎嗅网站的新闻,包括首页和分页信息(下一页) (2).需要从首页的资源和分页的资源中获取每个新闻的url连接 如何获取url: 解析网站html文件,如果A标签的href属性包含 article字段,就表示这是一个新闻 (3)

将配置保存在数据库中

将配置保存在数据库中 我们在<聊聊默认支持的各种配置源>和<深入了解三种针对文件(JSON.XML与INI)的配置源>对配置模型中默认提供的各种ConfigurationSource进行了深入详尽的介绍,如果它们依然不能满足项目中的配置需求,我们可以还可以通过自定义ConfigurationProvider来支持我们希望的配置来源.就配置数据的持久化方式来说,将培植存储在数据库中应该是一种非常常见的方式,接下来我们就是创建一个针对数据库的ConfigurationSource,它采

Java代码实现向Oracle数据库中导入已备份的数据库文件

今天将很早就实现的一个Oracle数据库备份功能粘贴出来,这个功能是在大学做阶段设计时写的: import java.io.IOException; /** * Java代码实现向Oracle数据库中导入已备份的数据库文件 * * @author:Gaohuanjie */ public class OracleImportDatabase { /** * 向Oracle数据库中导入已备份的数据库文件 * * @author:Gaohuanjie * @param userName 进入数据库所