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