1、MySQL BLOB 类型介绍
MySQL中,BLOB是一个二进制大型对象,是一个能够存储大量数据的容器,它能容纳不一样大小的数据。BLOB类型实际是个类型系列(TinyBlob、Blob、MediumBlob、LongBlob),除了在存储的最大信息量上不一样外,他们是等同的。 java
MySQL的四种BLOB类型
类型 大小(单位:字节)
TinyBlob 最大 255B
Blob 最大 65K //个人不是这个大小啊,也许设个是之前的吧
MediumBlob 最大 16M
LongBlob 最大 4G
实际使用中根据须要存入的数据大小定义不一样的BLOB类型。
须要注意的是:若是你存储的文件过大,数据库的性能会降低不少。 mysql
2、mysql中的blob存取sql
表结构:数据库
create table Dish {session
int id;app
blob photo;jsp
};性能
下面是从数据库里写的方法:this
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(); }
3、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";
问题解决了,不只能支持各类格式的文件,图片也显示正常了。若是设置为其余的字符集就会出现前面的错误。
4、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(也能够设置本身须要的大小)。
5、效率问题
利用数据库存储大量文件时,查询效率就会变得很低。
在表的设计上,咱们能够选择吧文件的相关信息存在一个表中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)