往MySQL中儲存圖片 longBlob型別
阿新 • • 發佈:2019-01-17
往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;
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:
"