JDBC读写MySQL的大字段数据
 
不管你是新手还是老手,大字段数据的操作常常令你感到很头痛。因为大字段有些特殊,不同数据库处理的方式不一样,大字段的操作常常是以流的方式 来处理的。而非一般的字段,一次即可读出数据。本人以前用到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列的最大有效(允许的)长度取决于客户端/服务器协议中配置最大包大小和可用的内存。
 
二、创建测试环境
 
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 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字段,可以根据实际需要选择合适的长度。
 
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/

JDBC读写MySQL的大字段数据的更多相关文章

  1. 移动商城第八篇【添加商品之基本属性和大字段数据(FCK文本编辑器)】

    添加商品 修改对应的超链接url,controller转发到对应的JSP页面 <a href="${path}/item/toAddItem.do" class=" ...

  2. SparkSQL-通过JDBC读写mysql数据库

    object JdbcDatasourceTest { def main(args: Array[String]): Unit = { val spark = SparkSession .builde ...

  3. SparkSQL读写外部数据源-通过jdbc读写mysql数据库

    object JdbcDatasourceTest { def main(args: Array[String]): Unit = { val spark = SparkSession .builde ...

  4. JDBC连接mysql数据库,添加数据

    如下:其中添加/删除/修改只是sql字符串不同 //3.要执行的字符串 String sql="INSERT INTO t_student(NAME,age,email) VALUES('x ...

  5. JDBC读写mysql总结

    一.下载驱动(主要是jar包) mysql-connection-java-5.1.31-bin.jar 二.添加jar包,配置环境变量 把驱动jar包添加到以下两个目录,并设置classpath环境 ...

  6. 使用JDBC处理MySQL大数据

    一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时 ...

  7. 利用JDBC处理mysql大数据--大文本和二进制文件等

    转载自http://www.cnblogs.com/xdp-gacl/p/3982581.html 一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob, ...

  8. JavaWeb学习总结(十)--JDBC之MySQL大数据

    一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 但是,在mysql ...

  9. javaweb学习总结(三十四)——使用JDBC处理MySQL大数据

    一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时 ...

随机推荐

  1. HDU1166 敌兵布阵 线段树详解

    题解: 更新是线段树的单点更新,简单一点. 有50000个阵营,40000查询,用普通数组肯定超时.区间求和和区间查询问题用线段树最好不过了. 先说说什么是线段树. 区间[1,10]用树的方法存起来, ...

  2. ubantu上搭建hive环境

    上次我们在ubantu上安装了hadoop,那我们现在再进一步,开始我们的学习之旅--hive板块吧! 第一步:准备! 软件: I.一个搭建好的hadoop环境 II.hive的bin文件(前往apa ...

  3. 洛谷 p2618 数字工程 记忆化搜索_ 线性筛

    我们在线筛的同时处理出每个数的所有质因子,记忆化搜索的时候直接枚举质因子即可. 时间复杂度为 O(nlogn)O(nlogn)O(nlogn) Code: #include<cstdio> ...

  4. 路飞学城Python-Day31

    19-生产者消费者模型 生产者:生成数据的任务 消费者:处理数据的任务 在并发编程的过程中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理,才能继续生产数据:同样的,如果 ...

  5. php字符处理

    1.strstr 截取某个字符后的字符: echo strstr("123456789","5");//输出:6789

  6. FZU 1692 Key problem( 循环矩阵优化 + 矩阵快速幂)

    链接:传送门 题意: n个小朋友围成一个环( 2 <= n <= 100 )然后进行m次的游戏. 一开始,第 i 个小朋友有 Ai 个苹果. 定义游戏的规则为:每一次游戏处于 i 位置的小 ...

  7. js追加元素

    直接运行 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  8. Python学习笔记(6)元组

    2019-03-02 元组(tuple): (1)元组是不可变的,无法进行任意修改.插入.删除一个元素. (2)创建元组大部分时候用小括号,如果创建的元组中只有一个元素,需要在它的后面加上一个逗号. ...

  9. mysql_5.6.24_winx64 安装

    1.将zip压缩文件放在一个文件夹中 2.将路劲加入path环境变量 3.注册系统服务 在C:\windows下建立一个ini文件 1 2 3 4 5 6 7 8 9 10 11 12 [client ...

  10. poj2528 Mayor&#39;s posters(线段树,离散化)

    离散化的思想: 对于这样的数据 (3,10000). (9,1000000). (5.100000), (1,1000). (7,1000000) 我们能够将其处理为 (2,7). (5,9). (3 ...