程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JDBC讀寫MySQL的大字段數據

JDBC讀寫MySQL的大字段數據

編輯:關於JAVA

不管你是新手還是老手,大字段數據的操作常常令你感到很頭痛。因為大字段有些特 殊,不同數據庫處理的方式不一樣,大字段的操作常常是以流的方式來處理的。而非一般 的字段,一次即可讀出數據。本人以前用到Spring+iBatis架構來操作大字段,結果以慘 烈失敗而告終,在網上尋求解決方案,也沒找到答案。最終以JDBC來實現了大字段操作部 分。

本文以MySQL為例,通過最基本的JDBC技術來處理大字段的插入、讀取操作。

環境:

MySQL5.1

JDK1.5

一、認識MySQL的大字段類型

BLOB是一個二進制大對象,可以容納可變數量的數據。有4種BLOB類型:TINYBLOB、 BLOB、MEDIUMBLOB和LONGBLOB。它們只是可容納值的最大長度不同。

有4種TEXT類型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。這些對應4種BLOB類型, 有相同的最大長度和存儲需求。

BLOB 列被視為二進制字符串(字節字符串)。TEXT列被視為非二進制字符串(字符字符 串)。BLOB列沒有字符集,並且排序和比較基於列值字節的數值值。TEXT列有一個字符集 ,並且根據字符集的 校對規則對值進行排序和比較。

在TEXT或BLOB列的存儲或檢索過程中,不存在大小寫轉換。

當未運行在嚴格模式時,如果你為BLOB或TEXT列分配一個超過該列類型的最大長度的 值值,值被截取以保證適合。

幾種類型的大字段最大長度說明:

TINYBLOB最大長度為255(2^[8]–1)字節的BLOB列。

TINYTEXT最大長度為255(2^[8]–1)字符的TEXT列。

BLOB[(M)]最大長度為65,535(2^[16]–1)字節的BLOB列。可以給出該類型的可選長度M 。如果給出,則MySQL將列創建為最小的但足以容納M字節長的值的BLOB類型。

TEXT[(M)]最大長度為65,535(2^[16]–1)字符的TEXT列。可以給出可選長度M。則 MySQL將列創建為最小的但足以容納M字符長的值的TEXT類型。

MEDIUMBLOB最大長度為16,777,215(2^[24]–1)字節的BLOB列。

MEDIUMTEXT最大長度為16,777,215(2^[24]–1)字符的TEXT列。

LONGBLOB最大長度為4,294,967,295或4GB(2^[32]–1)字節的BLOB列。LONGBLOB列的最 大有效(允許的)長度取決於客戶端/服務器協議中配置最大包大小和可用的內存。

LONGTEXT最大長度為4,294,967,295或4GB(2^[32]–1)字符的TEXT列。LONGTEXT列的最 大有效(允許的)長度取決於客戶端/服務器協議中配置最大包大小和可用的內存。

二、創建測試環境

create table user (
     id int(11) not null auto_increment,
     name varchar(50) not null,
     pswd varchar(50) default null,
     pic longblob,
     remark longtext,
     primary key (id)
);

三、插入讀取blob

import lavasoft.common.DBToolkit;
import java.io.*;
import java.sql.*;
/**
* 操作MySQL5的blob字段
*
* @author leizhimin 2009-12-3 11:34:50 
*/
public class BlobTest {
         public static void main(String[] args) {
                 insertBlob();
                 queryBlob();
         }
         public static void insertBlob() {
                 Connection conn =  DBToolkit.getConnection();
                 PreparedStatement ps = null;
                 try {
                         String sql = "insert  into testdb.user (name, pswd, pic) values (?, ?, ?)";
                         ps =  conn.prepareStatement(sql);
                         ps.setString(1,  "zhangsan");
                         ps.setString(2,  "111");
                         //設置二進制參數
                         File file = new File ("D:\\new\\dbtools\\src\\res\\PIC.PNG");
                         InputStream in = new  BufferedInputStream(new FileInputStream(file));
                         ps.setBinaryStream(3, in,  (int) file.length());
                         ps.executeUpdate();
                         in.close();
                 } catch (IOException e) {
                         e.printStackTrace();
                 } catch (SQLException e) {
                         e.printStackTrace();
                 } finally {
                         DBToolkit.closeConnection (conn);
                 }
         }
         public static void queryBlob() {
                 Connection conn =  DBToolkit.getConnection();
                 PreparedStatement ps = null;
                 Statement stmt = null;
                 ResultSet rs = null;
                 try {
                         String sql = "select  pic from user where id = 24";
                         stmt =  conn.createStatement();
                         rs = stmt.executeQuery (sql);
                         if (rs.next()) {
                                 InputStream  in = rs.getBinaryStream(1);
                                 File file  = new File("D:\\new\\dbtools\\src\\res\\PIC_COPY.PNG");
                                 OutputStream out = new BufferedOutputStream(new FileOutputStream (file));
                                 byte[]  buff = new byte[1024];
                                 for (int  i = 0; (i = in.read(buff)) > 0;) {
                                          out.write(buff, 0, i);
                                 }
                                 out.flush ();
                                 out.close ();
                                 in.close ();
                         }
                         rs.close();
                         stmt.close();
                 } catch (IOException e) {
                         e.printStackTrace();
                 } catch (SQLException e) {
                         e.printStackTrace();
                 } finally {
                         DBToolkit.closeConnection (conn);
                 }
         }
}

注意,要確保二進制數據長度足夠大,否則可能導致數據寫入不完整的問題。

三、插入讀取clob字段

clob在MySQL5中對應的就是text字段,可以根據實際需要選擇合適的長度。

package lavasoft.jdbctest;
import lavasoft.common.DBToolkit;
import java.io.*;
import java.sql.*;
/**
* 操作MySQL5的Clob字段
*
* @author leizhimin 2009-12-3 13:56:16
*/
public class ClobTest {
         public static void main(String[] args) {
                 insertClob();
                 queryClob();
         }
         public static void insertClob() {
                 Connection conn =  DBToolkit.getConnection();
                 PreparedStatement ps = null;
                 try {
                         String sql = "insert  into testdb.user (name, pswd, remark) values (?, ?, ?)";
                         ps =  conn.prepareStatement(sql);
                         ps.setString(1,  "zhangsan");
                         ps.setString(2,  "111");
                         //設置二進制參數
                         File file = new File ("D:\\new\\dbtools\\src\\res\\PIC.PNG");
//                        InputStreamReader reader  = new InputStreamReader(new FileInputStream ("D:\\new\\dbtools\\src\\res\\TEXT.txt"),"GB18030");
                         InputStreamReader reader  = new InputStreamReader(new FileInputStream ("D:\\new\\dbtools\\src\\res\\TEXT.txt"));
                         ps.setCharacterStream(3,  reader, (int) file.length());
                         ps.executeUpdate();
                         reader.close();
                 } catch (IOException e) {
                         e.printStackTrace();
                 } catch (SQLException e) {
                         e.printStackTrace();
                 } finally {
                         DBToolkit.closeConnection (conn);
                 }
         }
         public static void queryClob() {
                 Connection conn =  DBToolkit.getConnection();
                 PreparedStatement ps = null;
                 Statement stmt = null;
                 ResultSet rs = null;
                 try {
                         String sql = "select  remark from user where id = 1";
                         stmt =  conn.createStatement();
                         rs = stmt.executeQuery (sql);
                         if (rs.next()) {
                                 Reader  reader = rs.getCharacterStream(1);
                                 File file  = new File("D:\\new\\dbtools\\src\\res\\TEXT_COPY.txt");
                                 OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream (file));
//                                 OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream (file),"ISO-8859-1");
//                                 OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream (file),"GB18030");
                                 char[]  buff = new char[1024];
                                 for (int  i = 0; (i = reader.read(buff)) > 0;) {
                                          writer.write(buff, 0, i);
                                 }
                                 writer.flush();
                                 writer.close();
                                 reader.close();
                         }
                         rs.close();
                         stmt.close();
                 } catch (IOException e) {
                         e.printStackTrace();
                 } catch (SQLException e) {
                         e.printStackTrace();
                 } finally {
                         DBToolkit.closeConnection (conn);
                 }
         }
}

在處理blob字段時候,由於直接處理的是二進制流,所以沒啥問題。在處理clob字段 的時候,由於數據庫對clob是以字符的形式進行存儲,這就有一個編碼問題。本文雖然成 功的插入讀取了clob字段,但是還沒有解決亂碼問題,因為JDBC在獲取到clob的時候,已 經對其進行了編碼,Reader reader = rs.getCharacterStream(1); 這就導致了編碼的混 亂,如果要徹底解決,還需要看看MySQL驅動的實現。通過非常規手段來解決。為了繞開 此問題,可以將clob的數據存儲為blog來操作,可以避免此問題。

出處:http://lavasoft.blog.51cto.com/62575/238222

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved