往MySQL中存儲圖片

 
MySQL中存儲圖片
 
1 介紹
在設計到數據庫的開發中,難免要將圖片或音頻文件插入到數據庫中的情況。一般來說,我們可以同過插入圖片文件相應的存儲位置,而不是文件本身,來避免直接向數據庫裏插入的麻煩。但有些時候,向MySQL中插入圖片更加容易管理。那麼在MySQL中該怎麼存儲呢?
參考資料[1]中有個相當清晰的例子,不過是基於MySQL圖形界面的查詢工具Query Brower的,你的機子上沒有安裝的話,可能得不到很好的理解。我在這裏不在贅述,更詳細的資料請看給出的鏈接吧。
還有,[1]中的例子其實只是向我們說明了Query Brower的易用和強大,對我們在開發中實際應用不是很大。所以下面就讓我們用JAVA寫一個向MySQL中存儲的簡單實例。
2 建表
首先,先要在數據庫中建表。我在名爲test的數據庫下建立了一個叫pic的表。該表包括3列,idpic, caption和img。其中idpic是主鍵,caption是對圖片的表述,img是圖像文件本身。建表的SQL語句如下:
DROP TABLE IF EXISTS `test`.`pic`;
CREATE TABLE `test`.`pic` (
 `idpic` int(11) NOT NULL auto_increment,
 `caption` varchar(45) NOT NULL default '',
 `img` longblob NOT NULL,
 PRIMARY KEY (`idpic`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
將上面的語句輸入到命令行中(如果安裝了Query Brower, 你可以按照參考[1]中的指示來建表,那樣會更加方便。),執行,表建立成功。
3 實現圖像存儲類
表完成後,我們就開始寫個Java類,來完成向數據庫中插入圖片的操作。我們知道,Java與數據庫連接是通過JDBC driver來實現的。我用的是MySQL網站上提供的MySQL Connector/J,如果你用的是其他類型的driver, 在下面的實現過程中可能會有些許差別。
 
3.1 裝載JDBC驅動,建立連接
JDK中提供的DriverManager接口用來管理Java Application 和 JDBC Driver之間的連接。在使用這個接口之前, DriverManager需要知道要連接的JDBC 驅動。最簡單的方法就是用Class.forName()來向DriverManager註冊實現了java.sql.Driver 的接口類。對MySQL Connector/J來說,這個類的名字叫com.mysql.jdbc.Driver。
下面這個簡單的示例說明了怎樣來註冊Connector/J Driver。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
public class LoadDriver {
    public static void main(String[] args) {
        try {
            // The newInstance() call is a work around for some
            // broken Java implementations
 
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            
            // Connection con = DriverManager.getConnection(……)
            // ……
        } catch (Exception ex) {
            // handle the error
        }
}
向DriverManager註冊了驅動後,我們就可以通過調用 DriverManager.getConnection()方法來獲得和數據庫的連接。其實在上面的例子中就有這條語句,只不過被註釋掉了。在後面的實現中會有完整的例子。
3.2 PreparedStatement
完成上面的步驟後,我們就可以同過建立的連接創建Statement接口類,來執行一些SQL語句了。在下面的例子,我用的是PreparedStatement,還有CallableStatement,它可以執行一些存儲過程和函數,這裏不多講了。下面的代碼片斷是向pic表中插入一條記錄。其中(1)處Connection接口的對象con通過調用prepareStatement 方法得到預編譯的SQL 語句(precompiled SQL statement);(2)處是爲該insert語句的第一個問號賦值,(3)爲第二個賦值,(4)爲第三個,這步也是最該一提的,用的方法是setBinaryStream(),第一個參數3是指第三個問號,fis是一個二進制文件流,第三個參數是該文件流的長度。
 
PreparedStatement ps;
ps = con.prepareStatement("insert into PIC values (?,?,?)"); // (1)
ps.setInt(1, id); //(2)
ps.setString(2, file.getName()); (3)
ps.setBinaryStream(3, fis, (int)file.length()); (4)
ps.executeUpdate();
3.3 完整代碼
上面列出了完整的代碼。
package com.forrest.storepic;
 
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
/**
 * This class describes how to store picture file into MySQL.
 * @author Yanjiang Qian
 * @version 1.0 Jan-02-2006
 */
public class StorePictures {
   
    private String dbDriver;
    private String dbURL;
    private String dbUser;
    private String dbPassword;
    private Connection con;
    private PreparedStatement ps;  
 
    public StorePictures() {
        dbDriver = "com.mysql.jdbc.Driver";
        dbURL = "jdbc:mysql://localhost:3306/test";
        dbUser = "root";
        dbPassword = "admin";
        initDB();
    }
   
    public StorePictures(String strDriver, String strURL,
            String strUser, String strPwd) {
        dbDriver = strDriver;
        dbURL = strURL;
        dbUser = strUser;
        dbPassword = strPwd;
        initDB();
    }
 
    public void initDB() {
        try {
            // Load Driver
            Class.forName(dbDriver).newInstance();
            // Get connection
            con = DriverManager.getConnection(dbURL,
                    dbUser, dbPassword);           
        } catch(ClassNotFoundException e) {
            System.out.println(e.getMessage());
        } catch(SQLException ex) {
            // handle any errors
            System.out.println("SQLException: " + ex.getMessage());
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("VendorError: " + ex.getErrorCode());
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
 
    public boolean storeImg(String strFile) throws Exception {
        boolean written = false;
        if (con == null)
            written = false;
        else {
            int id = 0;
            File file = new File(strFile);
            FileInputStream fis = new FileInputStream(file);
           
            try {              
                ps = con.prepareStatement("SELECT MAX(idpic) FROM PIC");
                ResultSet rs = ps.executeQuery();
               
                if(rs != null) {
                    while(rs.next()) {
                        id = rs.getInt(1)+1;
                    }
                } else {       
                    return written;
                }
                
                ps = con.prepareStatement("insert "
                        + "into PIC values (?,?,?)");
                ps.setInt(1, id);
                ps.setString(2, file.getName());
                ps.setBinaryStream(3, fis, (int) file.length());
                ps.executeUpdate();
               
                written = true;
            } catch (SQLException e) {
                written = false;
                System.out.println("SQLException: "
                        + e.getMessage());
                System.out.println("SQLState: "
                        + e.getSQLState());
                System.out.println("VendorError: "
                        + e.getErrorCode());
                e.printStackTrace();
            } finally {             
                ps.close();
                fis.close();
                // close db con
                con.close();
            }
        }
        return written;
    }
   
    /**
     * Start point of the program
     * @param args CMD line
     */
    public static void main(String[] args) {
        if(args.length != 1) {
            System.err.println("java StorePictures filename");
            System.exit(1);
        }
        boolean flag = false;
        StorePictures sp = new StorePictures();
        try {
            flag = sp.storeImg(args[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(flag) {
            System.out.println("Picture uploading is successful.");
        } else {
            System.out.println("Picture uploading is failed.");
        }
    }
}
4 總結
到此,我們就介紹完了使用往MySQL保存圖片的全過程。這個例子是個最簡單的實例,讀者可以根據自己的實際需要加入其它的一些功能,比如讀取文件,刪除等,使整個程序更加完善。在寫這篇文章的時候主要參考了參考[2],在此謝過。參考[3]中是一個相當漂亮的例子,不僅有保存還有讀取,而且是有非常直觀的圖形界面,感興趣的可以深入研究。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章