文档章节

Mysql 中的blob相关问题

文文1
 文文1
发布于 2015/09/08 19:14
字数 1087
阅读 43
收藏 0

一、MySQL BLOB 类型介绍
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。BLOB类型实际是个类型系列(TinyBlob、Blob、MediumBlob、LongBlob),除了在存储的最大信息量上不同外,他们是等同的。 


MySQL的四种BLOB类型 
 类型  大小(单位:字节) 
 TinyBlob  最大 255B
 Blob  最大 65K  //我的不是这个大小啊,也许设个是以前的吧
 MediumBlob  最大 16M 
 LongBlob  最大 4G 

实际使用中根据需要存入的数据大小定义不同的BLOB类型。 
需要注意的是:如果你存储的文件过大,数据库的性能会下降很多。  

 

二、mysql中的blob存取

表结构:

create table Dish {

     int id;

     blob photo;

};

下面是从数据库里写的方法:

String filepath = (String)session.getAttribute("file");//这里获得的是用jspsmartupload上传的文件的路径
File file = new File(filepath);
FileInputStream fin = new FileInputStream(file);
      
dataBS = new blobConn();    
con = dataBS.getConn();
String erpsql = "insert into Dish values(?,?)";
PreparedStatement stmt = con.prepareStatement(erpsql);
stmt.setString(2,String.valueOf(id));
          
//想数据库里插入是很简单的,就一行,但这种方法只有mysql可以用
stmt.setBinaryStream(3,fin,(int)file.length());
          
stmt.executeUpdate();
                            
fin.close();
stmt.close();
con.close();

下面是从数据库里读的方法:

1.BufferedInputStream inputimg = null;
try {
    Connection con = sqlDS.getConnection();//简写,获得数据库连接
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery("select from Dish where id = 11");
    if(rs.next()){
        java.sql.Blob blob = (java.sql.Blob)rs.getBlob("photo");
        input = new BufferedInputStream(blob.getBinaryStream);
    }
    BufferedImage image = null;
    image = javax.imageio.ImageIo.read(input);
    ServlerOutputStream sos = response.getOutputStream();
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(sos);
    encoder.encode(image);
    input.close();
}catch(Exception e) {
    e.printStackTrace();
}
 
2.
if(rs.next()){
    res.setContentType ("image/jpeg;charset=GB2312");//HttpServletResponse res
    ServletOutputStream out = res.getOutputStream ();
   
    BufferedInputStream jpgData = new BufferedInputStream (rs.getBinaryStream ("photo"));
    byte [] buf = new byte [4*1024];
    int len;
    if(jpgData.available () <= 0x0)//判断数据库里存放图片的字段是否有值,可以进行其他处理
    res.sendRedirect ("/images/nophoto.gif"); 
    
    while((len = jpgData.read (buf, 0, buf.length)) != -1)
    out.write (buf, 0, len);
}
3.
if(rs.next()){
    res.setContentType("image/jpeg");   
    ServletOutputStream   out=res.getOutputStream();   
    InputStream   in=rs.getBinaryStream("photo");   
    byte   buff[]=new   byte[1024];   
    int   i;   
    while((i=in.read(buff))!=-1){   
          out.write(buff);   
    }   
    in.close();   
    out.close();
}

三、charset设置对blog操作的影响

存储txt文件的时候没有问题;存储图片也没问题,但是再把图片图片从数据库中取出来,不能正常显示了;存储word格式的文件报错,如下:

Caused by: java.sql.BatchUpdateException: Syntax error or access violation message from server: "You have an error in your SQL syntax near ''D0CF11E0A1B11AE1000000000000000000000000000000003E000300FEFF0900060000000000000' at line 1"
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1540)

查了一下可能是charset编码的问题,于是将原来的连接字符串设置为:

Java代码 

url=url++"?useUnicode=true&characterEncoding=utf-8";

 问题解决了,不仅能支持各种格式的文件,图片也显示正常了。如果设置为其他的字符集就会出现前面的错误。

 

四、max_allowed_packet参数设置

往数据库中存储较大的文件是出现如下错误:

Java代码 

<strong>java.lang.IllegalArgumentException: Packet is larger than max_allowed_packet from server configuration of 1048576 bytes</strong>

这是因为存入的文件大于mysql默认的 max_allowed_packet值。

解决办法:在mysql安装目录下的my.ini文件中的最后一行添加

Java代码 

max_allowed_packet = 10M(也可以设置自己需要的大小)。

 五、效率问题

利用数据库存储大量文件时,查询效率就会变得很低。

在表的设计上,我们可以选择吧文件的相关信息存在一个表中fileInfo,而吧文件内容存在另一个表中fileContent,fileContent中有一个指向fileInfo的外键。这样,查询的时候只需要访问fileInfo,只有当要访问某个文件具体内容的时候才访问fileContent表。分表存储,能够显著提高查询速度。

 

-------------------------------------------------------------------------------------------------

 

  CLOB类型默认为1m 如果大于的话可能会出现

   Packet for query is too large (37748784 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable

 异常 这是可以在

[mysqld]下面添加 max_allowed_packet=10M来扩大限制

在 jdk 6。0 以前 向数据库插入clob 和blob数据的操作方法:

 void setBinaryStream(int parameterIndex, java.io.InputStream x, int length)方法

而在jdk 6.0以后就可以用

void setClob(int parameterIndex, Reader reader)

void setBlob(int parameterIndex, InputStream inputStream)方法来插入clob/blob

读取时候可以用读取流来处理或者用:

clob的时候可以

用 Clob.getSubString(pos, length)不过length是个int型的

或者用

Java代码 

Clob c = rs.getClob("clumn");  
StringBuffer a = new StringBuffer(1024);  
Reader r = c.getCharacterStream();  
char[] cc = new char[1];  
int i = -1;  
while((i =r.read(cc))!=-1){  
    a.append(cc);  
}

 读取blob可以用:

Blob b = rs.getBlob("clumn");
java.io.InputStream getBinaryStream ()或者getBytes(pos, length)

 


本文转载自:

文文1
粉丝 25
博文 454
码字总数 143313
作品 0
长沙
程序员
私信 提问
phpMyAdmin 3.4.5 发布

MySQL数据库管理工具 phpMyAdmin 3.4.5 发布,该版本改进:因为授权问题,本地Excel导出和导入模块被移除,BLOB 行的一个编辑相关的bug被修复,XSS修复。 phpMyAdmin是一个非常受欢迎的基于w...

小卒过河
2011/09/14
558
2
mysql怎么储存长字符-----MySQL text与blob字段类型的不同之处

字段类型选text型 或blog 区别见: 以下的文章主要介绍的是MySQL text与blob字段类型的不同之处的比较,同时本文也有对MySQL text与blob字段类型的实际应用的介绍,如果你对MySQL text与blo...

Airship
2015/07/03
4.4K
0
DJFocus 1.10.0319 免费版发布

DJFocus是J2EE体系下专注于Web数据展现与处理的组件。 DJFocus将Web数据处理封装为:模型、数据以及操作三个层面。 其中,“模型”定义了数据的来源和展现方式并以XML文档形式存放在服务器,...

红薯
2010/04/26
632
0
MySQL · 专家投稿 · MySQL5.7 的 JSON 实现

介绍 本文将介绍 MySQL 5.7 中如何实现非结构化(JSON)数据的存储,在介绍 MySQL 5.7 的非结构化数据存储之前,首先介绍在之前的 MySQL 的版本中,用户如何通过 BLOB 实现 JSON 对象的存储,...

阿里云RDS-数据库内核组
2016/01/04
0
0
Oracle数据库BLOB字段的存取

  最近几次碰到这个问题,需求是将一个文件或者文件流存储到Oracle数据库里,Oracle8提供了Blob和Clob用来存储二进制大对象数据,可是它和Java.sql.里面的Blob不兼容,经常导致Blob字段无法...

弱弱小男子
2013/09/09
460
0

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
6
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部