雖然說現(xiàn)在大部分公司都把文件存放在一個單獨的文件服務(wù)器上吃靠,在數(shù)據(jù)庫中存的是圖片的地址剥懒,但是還有一些比較落后的公司直接把圖片放在數(shù)據(jù)庫中,這種方式比較占用數(shù)據(jù)庫容量捺萌,而且不方便檢索鹿寨,前臺也不好處理新博,但是我就遇到了這樣一個需求薪夕,將本地文件導(dǎo)入到Oracle數(shù)據(jù)庫中脚草。
1、添加依賴
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.2.0</version>
</dependency>
</dependencies>
我創(chuàng)建的是一個普通的maven項目原献。由于只需要和數(shù)據(jù)庫交互馏慨,所以只用添加數(shù)據(jù)庫驅(qū)動就可以了,我們開發(fā)用的是Oracle數(shù)據(jù)庫姑隅,所以用的是Oracle驅(qū)動写隶,如果是MySQL數(shù)據(jù)庫就需要使用MYSQL驅(qū)動。我還添加了druid的依賴讲仰,其實是沒有必要的慕趴。
2、配置文件
jdbc.properties
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@192.168.6.222:1521:sid
userName=test
password=test
這個配置文件保存jdbc連接的配置信息鄙陡,放在resources目錄下冕房。
3、工具類
import com.alibaba.druid.pool.DruidDataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static DruidDataSource dataSource = new DruidDataSource();
static{
try {
//從本地文件中讀取配置信息
Properties properties = new Properties();
//獲取當(dāng)前類的根路徑 , 讀取配置文件
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
properties.load(is);
dataSource.setDriverClassName(properties.getProperty("driver"));
dataSource.setUrl(properties.getProperty("url"));
dataSource.setUsername(properties.getProperty("userName"));
dataSource.setPassword(properties.getProperty("password"));
dataSource.setMaxActive(150);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
Connection cn = null;
try {
cn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return cn;
}
public static void close(Statement st, Connection cn){
close(null,st,cn);
}
public static void close(ResultSet rs, Statement st, Connection cn){
//關(guān)閉連接
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(cn!=null){
try {
cn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBCUtils工具類用于讀取配置文件趁矾、獲取連接耙册、關(guān)閉連接。
4毫捣、主類
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.sql.*;
/**
* @author huwen
*/
public class ImportImage {
private Connection conn;
/**
* 向表中插入圖片
*
* @param path 圖片所在的路徑
* @return 整形 判斷成功或失敗
*/
public int insertImage(File path) throws Exception {
int i = 0;
Statement st = null;
ResultSet rs = null;
conn=JDBCUtils.getConnection();
//設(shè)置數(shù)據(jù)庫為不自動提交详拙,必須的一步
conn.setAutoCommit(false);
//先插入一個空對象,這里我調(diào)用了Empty_BLOB()函數(shù)
st = conn.createStatement();
//先插入一個空對象蔓同,這里我調(diào)用了Empty_BLOB()函數(shù)
String paperNo = path.getName().split("\\.")[0];
String insertSql = "insert into TF_F_CARDPARKPHOTO_SZ_TMP (parpno,picture,operatetime) values ('"+paperNo+"',Empty_BLOB(),sysdate)";
i = st.executeUpdate(insertSql);
//以行的方式鎖定
String selectSql = "select picture from TF_F_CARDPARKPHOTO_SZ_TMP where parpno= '"+paperNo+"' for update";
rs = st
.executeQuery(selectSql);
if (rs.next()) {
//得到流
oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(1);
//從得到的低級流構(gòu)造一個高級流
if(blob==null){
System.out.println(paperNo);
}
PrintStream ps = new PrintStream(blob.getBinaryOutputStream());
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(path));
byte[] buff = new byte[1024];
int n = 0;
//從輸入到輸出
while ((n = bis.read(buff)) != -1) {
ps.write(buff, 0, n);
}
//清空流的緩存
ps.flush();
//關(guān)閉流饶辙,注意一定要關(guān)
ps.close();
bis.close();
}
conn.commit();
JDBCUtils.close(rs,st,conn);
return i;
}
public static void main(String[] args) throws Exception {
ImportImage test=new ImportImage();
File file = new File("C:\\Users\\huwen\\Documents\\1109");
for (File f : file.listFiles()) {
test.insertImage(f);
}
System.out.println("OK");
}
}
首先要保證表中沒有數(shù)據(jù),并且有一個字段數(shù)據(jù)類型為BLOB斑粱。這種做法的原理是先向表中插入一個Empty_Blob()函數(shù)創(chuàng)建的數(shù)據(jù)弃揽,然后以行的方式鎖定讀取該字段信息,從磁盤中讀取文件寫入。中間一定要注意關(guān)閉自動提交
蹋宦,執(zhí)行完后進(jìn)行手動提交
披粟。