1. 程式人生 > >Java向Mysql資料庫中儲存圖片等二進位制檔案的實現,以及常見報錯的解決!

Java向Mysql資料庫中儲存圖片等二進位制檔案的實現,以及常見報錯的解決!

Mysql資料庫的功能很強大,除了能儲存字元等常見資料以外,它同樣可以儲存圖片等二進位制檔案,本文以儲存照片為例。

一、Mysql儲存二進位制檔案常見報錯有:

1.com.mysql.jdbc.PacketTooBigException: Packet for query is too large問題。

這個問題是由於mysql資料庫查詢和接收包的資料大小有限制,預設是1M,當你存取的二進位制檔案比較大的時候你需要修改Mysql的配置,具體命令如下:

在mysql命令列中執行命令:

(1)首先檢視當前配置。

show VARIABLES like '%max_allowed_packet%';

(2)修改最大可接收包大小為20M。 

set global max_allowed_packet = 2*1024*1024*10;

2.data too long for column 'xxx' at row 1問題 

這個問題是由於所儲存的檔案大於你所選擇的二進位制檔案型別的最大長度,以圖片儲存為例一般選擇BLOB型別,但是不同的blob型別有他的長度大小區分,具體如下:

BLOB是個型別系列,包括:TinyBlob、Blob、MediumBlob、LongBlob,這幾個型別之間的唯一區別是在儲存檔案的最大大小上不同。 

BLOB型別

大小(單位:位元組)

TinyBlob

最大255 byte

Blob

最大65 kb

MediumBlob

最大16 M

LongBlob

最大4 G


 二、下面貼上我寫的資料庫連線,二進位制流的獲取,圖片存入和取出資料庫的工具類,水平有限,有錯誤的地方請大家指正,共同學習。

我的mysql資料庫表photo的設計如下 :

CREATE TABLE photo
(
  id    INT AUTO_INCREMENT
    PRIMARY KEY,
  name  VARCHAR(20) NOT NULL
  COMMENT '姓名',
  photo LONGBLOB    NOT NULL
  COMMENT '照片'
);

1.MysqlUtils工具類,用於資料庫的連線和關閉。

package mydatabase;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @date on 14:48 2018/8/16
 * @author yuyong
 * @describe 用於連線mysql資料庫的工具類
 */
public class MysqlUtils {

    enum Constants{
        /**
         *定義列舉型別放入資料庫連線的常量
         * Constants_Driver 驅動
         * Constants_Url 資料庫路徑
         * Constants_user 使用者名稱
         * Constants_password 密碼
         */
        Constants_Driver("com.mysql.jdbc.Driver"),
        Constants_Url("jdbc:mysql://localhost:3307/test"),
        Constants_user("root"),
        Constants_password("root");

        private String description;
        Constants (String description){
            this.description = description;
        }
        public String getDescription(){
            return description;
        }
    }

    static {
        try {
            Class.forName(Constants.Constants_Driver.getDescription());
            System.out.println("資料庫驅動註冊成功...");
        } catch (ClassNotFoundException e) {
            System.out.println("驅動註冊失敗");
            e.printStackTrace();
        }
    }

    /**
     * 獲取資料庫的連線
     * @return Connection
     */
    public static Connection getConnection(){
        try {
            Connection connection = DriverManager.getConnection(Constants.Constants_Url.getDescription(),
                    Constants.Constants_user.getDescription(),Constants.Constants_password.getDescription());
            System.out.println("資料庫連線成功...");
            return connection;
        } catch (SQLException e) {
            System.out.println("獲取連線失敗");
            e.printStackTrace();
        }
        return null;
    }

    public static boolean closeConnection(Connection connection){
        if (null != connection){
            try {
                connection.close();
                System.out.println("資料庫關閉成功...");
                return true;
            } catch (SQLException e) {
                System.out.println("關閉連線失敗!!");
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * Junit測試
     */
    @Test
    public void mysqlUtilsTest(){
        Connection connection = MysqlUtils.getConnection();
        MysqlUtils.closeConnection(connection);
    }

}

2. ReadImageUtils工具類,封裝用於讀取圖片的工具流,用於資料庫儲存圖片。

package mydatabase;

/**
 * @date on 15:15 2018/8/16
 * @author yuyong
 * @describe 封裝用於讀取圖片的工具流,用於資料庫儲存圖片
 */
import java.io.*;

public class ReadImageUtils {

    /**
     * 讀取本地圖片的輸入流
     * @return FileInputStream
     */
    public static FileInputStream getIns(String imagePath){
        try {
            return new FileInputStream(new File(imagePath));
        } catch (FileNotFoundException e) {
            System.out.println("請檢查檔案路徑是否正確");
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 讀取資料庫表中圖片的輸出流
     * @param targetPath 圖片儲存到本地的路徑
     * @return FileOutputStream
     */
    public static FileOutputStream getOuts(String targetPath){
        File file = new File(targetPath);
        String path = targetPath.substring(0,targetPath.lastIndexOf("/"));
        //如果檔案不存在則建立目錄
        if (!file.exists()){
            new File(path).mkdir();
        }

        FileOutputStream fos ;
        try {
             fos = new FileOutputStream(file);
             return fos;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 讀取資料庫中的圖片二進位制資料寫出目標地址
     * @param in 輸入流
     * @param out 輸出流
     * @return boolean
     */
    public static boolean readBinaryImage(InputStream in, OutputStream out){
        try {
            int len;
            byte[] b = new byte[1000];
            while ((len=in.read(b)) != -1){
                out.write(b,0,len);
            }
            out.flush();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != out){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != in){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
}

3. ImageSaveAndOut工具類,實現圖片的本地與資料庫傳輸。

package mydatabase;

/**
 * @date on 15:52 2018/8/16
 * @author yuyong
 * @describe 實現圖片的本地與資料庫傳輸!
 */
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ImageSaveAndOut {


    /**
     * 存入和取出的sql語句
     */
    enum SQL{
        /**
         * SQL_IN 將圖片存入資料庫的sql語句
         * SQL_OUT 將圖片從資料庫取出的sql語句
         */
        SQL_IN("insert into photo (name,photo) values (?,?)"),
        SQL_OUT("select * from photo where id = ?");
        private String sql;
        SQL(String sql){
            this.sql = sql;
        }
        public String getSql(){
            return sql;
        }
    }
    private static PreparedStatement preparedStatement;
    private static ResultSet resultSet;
    private static Connection connection;
    private static InputStream in;
    private static OutputStream out;

    /**
     * 將圖片資源存入資料庫
     * @param imagePath 本地圖片路徑
     * @param name 名稱
     * @return boolean
     */
    public static boolean imageToDatabase(String imagePath,String name){
        try {
            if (null == out){
                in = ReadImageUtils.getIns(imagePath);
            }
            connection = MysqlUtils.getConnection();
            if (null != connection) {
                preparedStatement = connection.prepareStatement(SQL.SQL_IN.getSql());
                //設定sql語句中的佔位符?
                preparedStatement.setString(1,name);
                preparedStatement.setBlob(2,in,in.available());
                int count = preparedStatement.executeUpdate();
                if (count > 0){
                    System.out.println("儲存圖片成功...");
                    return true;
                }else {
                    System.out.println("儲存圖片失敗...");
                    return false;
                }
            }
        }catch (SQLException | IOException e) {
            e.printStackTrace();
        } finally {
            MysqlUtils.closeConnection(connection);
            try {
                if (null != in ){
                    in.close();
                }
                if (null != preparedStatement){
                    preparedStatement.close();
                }
            }catch (IOException e) {
                System.out.println("輸入流關閉失敗...");
                e.printStackTrace();
            } catch (SQLException e) {
                System.out.println("預處理命令關閉失敗...");
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * 將資料庫中的圖片讀出儲存到本地
     * @param localPath 本地儲存該圖片的路徑
     * @param id 資料庫中該圖片的id
     * @return boolean
     */
    public static boolean databaseToImage(String localPath, int id){
        try {

            connection = MysqlUtils.getConnection();
            if (null == out){
                out = ReadImageUtils.getOuts(localPath);
            }
            if (null != connection){
                preparedStatement = connection.prepareStatement(SQL.SQL_OUT.getSql());
            }
            preparedStatement.setInt(1,id);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                in = resultSet.getBinaryStream("photo");
                ReadImageUtils.readBinaryImage(in,out);
                System.out.println("圖片取出成功...");
            }
            return true;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            MysqlUtils.closeConnection(connection);
            if (null != resultSet){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    /**
     * Junit 測試
     */
    @Test
    public void imageSaveAndOutTest(){
        //存入
        //ImageSaveAndOut.imageToDatabase("./src/mydatabase/1111.jpg","yuyong");
        //取出
        ImageSaveAndOut.databaseToImage("./1.jpg",3);
    }
}

相關推薦

JavaMysql資料庫儲存圖片二進位制檔案實現以及見報解決

Mysql資料庫的功能很強大,除了能儲存字元等常見資料以外,它同樣可以儲存圖片等二進位制檔案,本文以儲存照片為例。 一、Mysql儲存二進位制檔案常見報錯有: 1.com.mysql.jdbc.PacketTooBigException: Packet for query

javaMySql資料庫插入資料

package test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLExc

Java程式MySql資料庫插入的資料變成了問號

其實,當我們看到這個問題的時候都會很快的想到是編碼格式的問題。但是當我檢視MyEclipse中的編碼格式的時候發現,編碼方式是沒有問題的,而且自己寫的JSP頁面中的編碼格式也是沒有問題的。那麼這會嘛原因的? 後來在檢視Mysql的資料時候發現: 1、MySQL的預設編碼是La

java 使用jdbcmysql資料庫插入1億條資料

<span style="font-size:14px;"><span style="font-size:14px;">package com.ddx.zhang; import java.sql.SQLException; import java

c#SQL Server儲存圖片並且再從資料庫讀取圖片

前言 資料庫課程設計答辯時,老師提出瞭如果資料是圖片或者其他檔案型別的時候,頓時覺得自己做的管理系統用到的較多的就是Char型別。於是,答辯結束後,就蒐集資料學習,在查詢資料的時候發現,有的一開始並不能看懂,找到一篇文件,自己做了一個測試,然後發現出現了一點小

『PHP學習筆記』系列八:MySQL資料庫新增資料

資料表結構: 資料表原有資料: 向MySQL資料庫寫入資料:  INSERT INTO 語句通常用於向 MySQL 表新增新的記錄: INSERT INTO table_name (column1, column2, column3,...) VALUES

MySQL資料庫插入帶emoji表情符的資料時報

問題:向MySQL資料庫中插入帶emoji表情符的資料時報錯 原因:utf8字符集不支援emoji表情符,需要改為utf8mb4字符集(utf8mb4是MySQL在5.5.3之後增加的,實際開發中建議使用該字符集) 解決: 1. 設定MySQL伺服器及資料庫表的字符集    

mysql資料庫插入資料時顯示“Duplicate entry '1′ for key ‘PRIMARY' ”錯誤

錯誤情況如題,出現這個錯誤的原因十分簡單: 很明顯,這是主鍵的問題。 在一張資料表中是不能同時出現多個相同主鍵的資料的 這就是錯誤的原因,解決的方法: 1.可以將這張表設定成無主鍵(mysql支

1、用WorkbenchMySQL資料庫匯入SQL檔案

一、點選workbench登入資料庫二、新建schema,自己命名三、可以看到新建的schema中table等均為空四、左上角選單欄file-Open SQL Script-選中要匯入的SQL檔案五、在開啟的SQL檔案中,找到除註釋外的第一行程式碼,在其前面加一句“use [

MySQL資料庫批量讀取資料

這是在一次作業的時候用到的,將一個csv檔案中的資料讀取到MySQL建好的一個表中去。話不多說,上程式碼。#coding=utf-8 import MySQLdb conn = MySQLdb.co

MySQL資料庫匯入SQL檔案出錯,innodb

在MySQL資料庫中匯入SQL檔案,出現“Unsuccessful”的錯誤,執行效果如下圖所示: 將錯誤提示面板翻至頂端,可以看到資料庫給出的錯誤提示,如下圖: 根據錯誤提示可

MySQL資料庫存入json型別資料

0.說明    因為出於個人專案的需要,獲取到的資料都是json型別的,並且都要存入MySQL資料庫中,因為json型別資料不像一般的文字資料,所以在存入MySQL時需要注意的問題很多。    在網上找了很多方法,整理了一下比較實用可靠的,總結下來就是下面的過程:MySQL表

使用c++和AdoOracle資料庫插入圖片

    最近因為專案需要,需要將圖片插入至Oracle,現簡單總結如下:     1.引入ado #import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename(

mysql資料庫插入大文字

@Testpublic void demo5() throws SQLException, FileNotFoundException{System.setProperty("jdbc:drivers", "com.mysql.jdbc.Driver");Propertie

使用JavaMysql資料庫寫入當前時間

     最近做專案需要採集某些資料然後儲存在資料庫中,儲存時要求帶上採集時間,但是本人是初學Mysql和Java沒多久,坦白點說是不知怎麼寫,搜尋一下發現沒啥資源,後來硬下頭皮把Mysql的API文件看了一下,終於找到了思路,以下給出詳細思路及程式碼。      首先,面

利用jmetermysql資料庫插入資料

準備工作:1.已安裝好的jmeter2.mysql-connector-java.jar包:https://download.csdn.net/download/qq_41919825/103155693.mysql資料庫4.資料庫名稱test,表名稱tmptable,欄位i

Javamysql資料庫插入datatime時間資料

//將時間字串轉Timestamp型別 public static Timestamp string2Time(String dateString) throws ParseException {

Android儲存圖片到本地功能實現

文章轉載自http://blog.csdn.net/ccpat/article/details/45314175  感謝原作者~ 本文描述將一個Bitmap物件儲存為一個圖片檔案的主要步驟。儲存的圖片檔案能夠立刻在系統相簿和相簿中找到。 我使用的是一張drawabl

Android儲存圖片到本地功能實現 .

初學Android時轉載的文章,沒想到還有很多人看,但是今天我才發現我這排版排的什麼玩意啊,根本沒法看!估計也耽誤了很多人的時間!真的很對不住,寫部落格也是個細心的活,不能摻進偷懶的想法。 文章轉載自http://blog.csdn.net/ccpat/article/d

tensorboard使用過程見報解決方案

在使用tensorboard將神經網路視覺化的過程中,常見遇見的一些報錯及其修正方案: AttributeError: 'module' object has no attribute 'SummaryWriter' tf.train.SummaryWriter 改