BLOB (binary large object),二進制大對象,是一個可以存儲二進制文件的容器。在計算機中,BLOB常常是數據庫中用來存儲二進制文件的字段類型,BLOB是一個大文件,典型的BLOB是一張圖片或一個聲音文件,由于它們的尺寸,必須使用特殊的方式來處理(例如:上傳、下載或者存放到一個數據庫)。
一、基本概念
在實際開發中,有時是需要用程序把大文本或二進制數據直接保存到數據庫中進行儲存的。
對MySQL而言只有blob,而沒有clob,mysql存儲大文本采用的是Text,Text和blob分別又分為:
TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT
TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB
二、搭建測試環境
2.1、搭建的測試項目架構
如圖:
2.2、編寫db.properties配置文件
1
2
3
4
|
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/jdbcStudy username=root password=XDP |
2.3、編寫JdbcUtils工具類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
package me.gacl.utils; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JdbcUtils { private static String driver = null ; private static String url = null ; private static String username = null ; private static String password = null ; static { try { //讀取db.properties文件中的數據庫連接信息 InputStream in = JdbcUtils. class .getClassLoader().getResourceAsStream( "db.properties" ); Properties prop = new Properties(); prop.load(in); //獲取數據庫連接驅動 driver = prop.getProperty( "driver" ); //獲取數據庫連接URL地址 url = prop.getProperty( "url" ); //獲取數據庫連接用戶名 username = prop.getProperty( "username" ); //獲取數據庫連接密碼 password = prop.getProperty( "password" ); //加載數據庫驅動 Class.forName(driver); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } /** * @Method: getConnection * @Description: 獲取數據庫連接對象 * @Anthor:孤傲蒼狼 * * @return Connection數據庫連接對象 * @throws SQLException */ public static Connection getConnection() throws SQLException{ return DriverManager.getConnection(url, username,password); } /** * @Method: release * @Description: 釋放資源, * 要釋放的資源包括Connection數據庫連接對象,負責執行SQL命令的Statement對象,存儲查詢結果的ResultSet對象 * @Anthor:孤傲蒼狼 * * @param conn * @param st * @param rs */ public static void release(Connection conn,Statement st,ResultSet rs){ if (rs!= null ){ try { //關閉存儲查詢結果的ResultSet對象 rs.close(); } catch (Exception e) { e.printStackTrace(); } rs = null ; } if (st!= null ){ try { //關閉負責執行SQL命令的Statement對象 st.close(); } catch (Exception e) { e.printStackTrace(); } } if (conn!= null ){ try { //關閉Connection數據庫連接對象 conn.close(); } catch (Exception e) { e.printStackTrace(); } } } } |
三、使用JDBC處理MySQL的大文本
對于MySQL中的Text類型,可調用如下方法設置
1
|
PreparedStatement.setCharacterStream(index, reader, length); //注意length長度須設置,并且設置為int型 |
對MySQL中的Text類型,可調用如下方法獲取
1
|
reader = resultSet. getCharacterStream(String columnLabel); 2 string s = resultSet.getString(String columnLabel); |
3.1、 測試范例
1、編寫SQL測試腳本
1
2
3
4
5
6
7
|
create database jdbcstudy; use jdbcstudy; create table testclob ( id int primary key auto_increment, resume text ); |
2、編寫測試代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
package me.gacl.demo; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.Reader; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import me.gacl.utils.JdbcUtils; import org.junit.Test; /** * @ClassName: JdbcOperaClob * @Description: 使用JDBC操作MySQL的大文本 * @author: 孤傲蒼狼 * @date: 2014-9-19 下午10:10:04 * */ public class JdbcOperaClob { /** * @Method: add * @Description:向數據庫中插入大文本數據 * @Anthor:孤傲蒼狼 * */ @Test public void add(){ Connection conn = null ; PreparedStatement st = null ; ResultSet rs = null ; Reader reader = null ; try { conn = JdbcUtils.getConnection(); String sql = "insert into testclob(resume) values(?)" ; st = conn.prepareStatement(sql); //這種方式獲取的路徑,其中的空格會被使用“%20”代替 String path = JdbcOperaClob. class .getClassLoader().getResource( "data.txt" ).getPath(); //將“%20”替換回空格 path = path.replaceAll( "%20" , " " ); File file = new File(path); reader = new FileReader(file); st.setCharacterStream( 1 , reader,( int ) file.length()); int num = st.executeUpdate(); if (num> 0 ){ System.out.println( "插入成功!!" ); } //關閉流 reader.close(); } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release(conn, st, rs); } } /** * @Method: read * @Description: 讀取數據庫中的大文本數據 * @Anthor:孤傲蒼狼 * */ @Test public void read(){ Connection conn = null ; PreparedStatement st = null ; ResultSet rs = null ; try { conn = JdbcUtils.getConnection(); String sql = "select resume from testclob where id=2" ; st = conn.prepareStatement(sql); rs = st.executeQuery(); String contentStr = "" ; String content = "" ; if (rs.next()){ //使用resultSet.getString("字段名")獲取大文本數據的內容 content = rs.getString( "resume" ); //使用resultSet.getCharacterStream("字段名")獲取大文本數據的內容 Reader reader = rs.getCharacterStream( "resume" ); char buffer[] = new char [ 1024 ]; int len = 0 ; FileWriter out = new FileWriter( "D:\\1.txt" ); while ((len=reader.read(buffer))> 0 ){ contentStr += new String(buffer); out.write(buffer, 0 , len); } out.close(); reader.close(); } System.out.println(content); System.out.println( "-----------------------------------------------" ); System.out.println(contentStr); } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release(conn, st, rs); } } } |
四、使用JDBC處理MySQL的二進制數據
對于MySQL中的BLOB類型,可調用如下方法設置:
1
|
PreparedStatement. setBinaryStream(i, inputStream, length); |
對MySQL中的BLOB類型,可調用如下方法獲取:
1
2
|
InputStream in = resultSet.getBinaryStream(String columnLabel); InputStream in = resultSet.getBlob(String columnLabel).getBinaryStream(); |
4.1、 測試范例
1、編寫SQL測試腳本
1
2
3
4
5
|
create table testblob ( id int primary key auto_increment, image longblob ); |
2、編寫測試代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
package me.gacl.demo; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import me.gacl.utils.JdbcUtils; import org.junit.Test; /** * @ClassName: JdbcOperaClob * @Description: 使用JDBC操作MySQL的二進制數據(例如圖像、聲音、二進制文) * @author: 孤傲蒼狼 * @date: 2014-9-19 下午10:10:04 * */ public class JdbcOperaBlob { /** * @Method: add * @Description:向數據庫中插入二進制數據 * @Anthor:孤傲蒼狼 * */ @Test public void add(){ Connection conn = null ; PreparedStatement st = null ; ResultSet rs = null ; try { conn = JdbcUtils.getConnection(); String sql = "insert into testblob(image) values(?)" ; st = conn.prepareStatement(sql); //這種方式獲取的路徑,其中的空格會被使用“%20”代替 String path = JdbcOperaBlob. class .getClassLoader().getResource( "01.jpg" ).getPath(); //將“%20”替換會空格 path = path.replaceAll( "%20" , " " ); File file = new File(path); FileInputStream fis = new FileInputStream(file); //生成的流 st.setBinaryStream( 1 , fis,( int ) file.length()); int num = st.executeUpdate(); if (num> 0 ){ System.out.println( "插入成功!!" ); } fis.close(); } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release(conn, st, rs); } } /** * @Method: read * @Description: 讀取數據庫中的二進制數據 * @Anthor:孤傲蒼狼 * */ @Test public void read() { Connection conn = null ; PreparedStatement st = null ; ResultSet rs = null ; try { conn = JdbcUtils.getConnection(); String sql = "select image from testblob where id=?" ; st = conn.prepareStatement(sql); st.setInt( 1 , 1 ); rs = st.executeQuery(); if (rs.next()) { //InputStream in = rs.getBlob("image").getBinaryStream();//這種方法也可以 InputStream in = rs.getBinaryStream( "image" ); int len = 0 ; byte buffer[] = new byte [ 1024 ]; FileOutputStream out = new FileOutputStream( "D:\\1.jpg" ); while ((len = in.read(buffer)) > 0 ) { out.write(buffer, 0 , len); } in.close(); out.close(); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release(conn, st, rs); } } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。