继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

JDBC读写MySQL的大字段数据

largeQ
关注TA
已关注
手记 977
粉丝 92
获赞 585


 

不管你是新手还是老手,大字段数据的操作常常令你感到很头痛。因为大字段有些特殊,不同数据库处理的方式不一样,大字段的操作常常是以流的方式来处理的。而非一般的字段,一次即可读出数据。本人以前用到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来操作,可以避免此问题。

 

©著作权归作者所有:来自51CTO博客作者leizhimin的原创作品,如需转载,请注明出处,否则将追究法律责任

MySQL数据库休闲J2SE


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP