往MySQL中存儲(chǔ)圖片的方法
1 介紹
在設(shè)計(jì)到數(shù)據(jù)庫的開發(fā)中,難免要將圖片或音頻文件插入到數(shù)據(jù)庫中的情況。一般來說,我們可以同過插入圖片文件相應(yīng)的存儲(chǔ)位置,而不是文件本身,來避免直接向數(shù)據(jù)庫里插入的麻煩。但有些時(shí)候,向MySQL中插入圖片更加容易管理。那么在MySQL中該怎么存儲(chǔ)呢?
參考資料[1]中有個(gè)相當(dāng)清晰的例子,不過是基于MySQL圖形界面的查詢工具Query Brower的,你的機(jī)子上沒有安裝的話,可能得不到很好的理解。我在這里不在贅述,更詳細(xì)的資料請(qǐng)看給出的鏈接吧。
還有,[1]中的例子其實(shí)只是向我們說明了Query Brower的易用和強(qiáng)大,對(duì)我們?cè)陂_發(fā)中實(shí)際應(yīng)用不是很大。所以下面就讓我們用JAVA寫一個(gè)向MySQL中存儲(chǔ)的簡單實(shí)例。
2 建表
首先,先要在數(shù)據(jù)庫中建表。我在名為test的數(shù)據(jù)庫下建立了一個(gè)叫pic的表。該表包括3列,idpic, caption和img。其中idpic是主鍵,caption是對(duì)圖片的表述,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]中的指示來建表,那樣會(huì)更加方便。),執(zhí)行,表建立成功。
3 實(shí)現(xiàn)圖像存儲(chǔ)類
表完成后,我們就開始寫個(gè)Java類,來完成向數(shù)據(jù)庫中插入圖片的操作。我們知道,Java與數(shù)據(jù)庫連接是通過JDBC driver來實(shí)現(xiàn)的。我用的是MySQL網(wǎng)站上提供的MySQL Connector/J,如果你用的是其他類型的driver, 在下面的實(shí)現(xiàn)過程中可能會(huì)有些許差別。
3.1 裝載JDBC驅(qū)動(dòng),建立連接
JDK中提供的DriverManager接口用來管理Java Application 和 JDBC Driver之間的連接。在使用這個(gè)接口之前, DriverManager需要知道要連接的JDBC 驅(qū)動(dòng)。最簡單的方法就是用Class.forName()來向DriverManager注冊(cè)實(shí)現(xiàn)了java.sql.Driver 的接口類。對(duì)MySQL Connector/J來說,這個(gè)類的名字叫com.mysql.jdbc.Driver。
下面這個(gè)簡單的示例說明了怎樣來注冊(cè)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注冊(cè)了驅(qū)動(dòng)后,我們就可以通過調(diào)用 DriverManager.getConnection()方法來獲得和數(shù)據(jù)庫的連接。其實(shí)在上面的例子中就有這條語句,只不過被注釋掉了。在后面的實(shí)現(xiàn)中會(huì)有完整的例子。
3.2 PreparedStatement
完成上面的步驟后,我們就可以同過建立的連接創(chuàng)建Statement接口類,來執(zhí)行一些SQL語句了。在下面的例子,我用的是PreparedStatement,還有CallableStatement,它可以執(zhí)行一些存儲(chǔ)過程和函數(shù),這里不多講了。下面的代碼片斷是向pic表中插入一條記錄。其中(1)處Connection接口的對(duì)象con通過調(diào)用prepareStatement 方法得到預(yù)編譯的SQL 語句(precompiled SQL statement);(2)處是為該insert語句的第一個(gè)問號(hào)賦值,(3)為第二個(gè)賦值,(4)為第三個(gè),這步也是最該一提的,用的方法是setBinaryStream(),第一個(gè)參數(shù)3是指第三個(gè)問號(hào),fis是一個(gè)二進(jìn)制文件流,第三個(gè)參數(shù)是該文件流的長度。
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 總結(jié)
到此,我們就介紹完了使用往MySQL保存圖片的全過程。這個(gè)例子是個(gè)最簡單的實(shí)例,讀者可以根據(jù)自己的實(shí)際需要加入其它的一些功能,比如讀取文件,刪除等,使整個(gè)程序更加完善。在寫這篇文章的時(shí)候主要參考了參考[2],在此謝過。參考[3]中是一個(gè)相當(dāng)漂亮的例子,不僅有保存還有讀取,而且是有非常直觀的圖形界面,感興趣的可以深入研究。
以上所述是小編給大家介紹的往MySQL中存儲(chǔ)圖片的方法,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
mysql數(shù)據(jù)庫存儲(chǔ)過程之游標(biāo)(光標(biāo)cursor)詳解
這篇文章主要介紹了mysql數(shù)據(jù)庫存儲(chǔ)過程之游標(biāo)(光標(biāo)cursor)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
mysql中Table is read only的解決方法小結(jié)
本文章總結(jié)了關(guān)于在linux與windows中 mysql出現(xiàn)Table is read only解決辦法總結(jié),有需要的朋友可參考一下2013-01-01
mysql時(shí)間戳格式化函數(shù)from_unixtime使用的簡單說明
mysql中的FROM_UNIXTIME函數(shù)可以數(shù)據(jù)庫中整型類的時(shí)間戳格式化為字符串的日期時(shí)間格式,下面這篇文章主要給大家介紹了關(guān)于mysql時(shí)間戳格式化函數(shù)from_unixtime使用的簡單說明,需要的朋友可以參考下2022-08-08
MySQL對(duì)中文進(jìn)行排序詳解及實(shí)例
這篇文章主要介紹了MySQL對(duì)中文進(jìn)行排序詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05
Windows10下mysql 5.7.21 Installer版安裝圖文教程
這篇文章主要為大家詳細(xì)介紹了Windows10下mysql 5.7.21 Installer版安裝圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
MySQL無法重啟報(bào)錯(cuò)Warning: World-writable config file ‘/etc/my.cnf’
最近在維護(hù)公司服務(wù)器的時(shí)候,在關(guān)閉數(shù)據(jù)庫的命令發(fā)現(xiàn)mysql關(guān)不了了,提示錯(cuò)誤為Warning: World-writable config file '/etc/my.cnf' is ignored,通過查找網(wǎng)上的資料終于解決了,現(xiàn)在將解決的方法分享給大家,同樣遇到這個(gè)問題的朋友們可以參考借鑒。2016-12-12
詳解mysql索引總結(jié)----mysql索引類型以及創(chuàng)建
索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。這篇文章主要介紹了詳解mysql索引總結(jié)----mysql索引類型以及創(chuàng)建,有興趣的可以了解一下。2016-11-11
在MySQL中創(chuàng)建帶有IN和OUT參數(shù)的存儲(chǔ)過程的方法
這篇文章主要介紹了在MySQL中創(chuàng)建帶有IN和OUT參數(shù)的存儲(chǔ)過程的方法,在一定程度上簡化了操作,需要的朋友可以參考下2015-06-06

