`

MySQL 中的Blog杂谈

阅读更多
声明:本人完全copy来的
一、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));
          stmt.setBinaryStream(3,fin,(int)file.length());//想数据库里插入是很简单的,就一行,但这种方法只有mysql可以用
          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代码
1.url=url++"?useUnicode=true&characterEncoding=utf-8"; 
问题解决了,不仅能支持各种格式的文件,图片也显示正常了。如果设置为其他的字符集就会出现前面的错误。



四、max_allowed_packet参数设置

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



Java代码
1.java.lang.IllegalArgumentException: Packet is larger than max_allowed_packet from server configuration of 1048576 bytes 
这是因为存入的文件大于mysql默认的 max_allowed_packet值。

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

Java代码
1.max_allowed_packet = 10M(也可以设置自己需要的大小)。 
五、效率问题

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

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





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

向MySQL数据库插入Blob数据的问题

[摘要]:在使用Hibernate向数据库插入Blob二进制数据时,发生如下错误:SQL Error: 1064, SQLState: 42000 。You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '??^5b??08""199G?"0Px8=?ü??Y??ó??l%P?[
¨???ó`-??F????:???S?a?@??Zu??' at line 1
[关键字]:MySQL、Blob、图片、image、java、Hibernate、Clob、&amp;
[环境]:5.1.34-community MySQL Community Server (GPL),Hibernate 3.2.5
[作者]:Winty (wintys@gmail.com) http://www.blogjava.net/wintys

[错误]:
    使用Hibernate向数据库插入Blob二进制数据,程序如下:

    public void insert() {
        User user = new User();
        Transaction tc = null;
        try{
            Session session = HibernateUtil.getSession();
            tc = session.beginTransaction();
           
            user.setName("The Name");
           
            FileInputStream fin = new FileInputStream("rc/redheart.gif");
            Blob image = Hibernate.createBlob(fin);
            user.setImage(image);
           
            File file = new File("rc/news.txt");
            FileReader fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);
            Clob info = Hibernate.createClob(br , (int)file.length());
            user.setInfo(info);
           
            session.save(user);
           
            tc.commit();
        }catch(Exception e){
            if(tc != null){
                tc.rollback();
            }
            System.err.println(e.getMessage());           
        }finally{
            HibernateUtil.closeSession();
        }
    }

    发生如下错误:

Hibernate: insert into db.myblobclob (name, image, info, id) values (?, ?, ?, ?)
00:33:45,671  WARN JDBCExceptionReporter:77 - SQL Error: 1064, SQLState: 42000
00:33:45,671 ERROR JDBCExceptionReporter:78 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '??^5b??08""199G?"0Px8=?ü??Y??ó??l%P?[
¨???ó`-??F????:???S?a?@??Zu??' at line 1
00:33:45,687 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at wintys.hibernate.blobclob.UserDAOBean.insert(UserDAOBean.java:41)
    at wintys.hibernate.blobclob.UserTest.main(UserTest.java:18)
Caused by: java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '??^5b??08""199G?"0Px8=?ü??Y??ó??l%P?[
¨???ó`-??F????:???S?a?@??Zu??' at line 1
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1693)
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1108)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
    ... 9 more
Could not execute JDBC batch update
Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.image as image0_, user0_.info as info0_ from db.myblobclob user0_


[原因]:
    搜索了一下,错误原因可能为:"在定义字段时,不要和MYSQL的保留字段有相同的"。
    检查了一下表中的字段名,没有发现问题:

CREATE TABLE myblobclob(
    id          VARCHAR(100) NOT NULL,
    name    VARCHAR(100),
    image   BLOB,
    info       TEXT,
    PRIMARY KEY(id)
);


    如果把Blob相关的程序注释了,Clob数据能够正常写入。原因当然出在Blob数据的写入程序中。后来发现,把Blob写入的图片数据换成文本,却可以正常写入。可见,是二进制数据的编码问题。

[解决]:
    将原来的数据连接:

<property name="connection.url">
    jdbc:mysql://localhost:3306/db
</property>

    修改成:

<property name="connection.url">
    <![CDATA[jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf-8]]>
</property>

    注意,在将连接字符串放到CDATA中,因为&是XML中的转义字符。不然会提示错误:
    Error parsing XML: /hibernate.cfg.xml(12) The reference to entity "characterEncoding" must end with the ';' delimiter.

    也可以直接把&修改为&amp;
    即:
    jdbc:mysql://localhost:3306/db?useUnicode=true&amp;characterEncoding=utf-8


1
1
分享到:
评论

相关推荐

    MySQL中文参考手册CHM版

    MySQL数据库, MySQL中文帮助手册合集, MySQL中文文档, DOS命令大全, HTML5中文帮助手册, CHM版本, 数据库优化总结,

    MySQL 5.7 中文文档

    MySQL 5.7 中文文档 MySQL 5.7 中文文档 MySQL 5.7 中文文档

    MySQL中文参考手册.chm

    1.2 关于本手册 1.2.1 本手册中使用的约定 1.3 MySQL的历史 1.4 MySQL的主要特征 1.5 MySQL稳定性? 1.6 顺应2000年 1.7 SQL一般信息和教程 1.8 有用的MySQL相关链接 ...

    mysql中文使用手册

    主要内容:1 MySQL的一般的信息 2 MySQL 邮件列表及如何提问或报告错误 3 MySQL的许可证和技术支持 4 安装 MySQL 5 MySQL 与标准的兼容性 6 MySQL 存取权限系统 7 MySQL 语言参考 8 MySQL 教程 9 MySQL 服务器功能 ...

    php + mysql 个人博客系统

    php + mysql 个人博客系统 包括写博客,相片,音乐等各种功能

    MySQL8中文参考手册 MySQL DBA必备

    MySQL参考手册。它的文件通过8.0.14 MySQL 8。它可以包括MySQL版本尚未发布功能的文档。关于哪个版本的信息已被释放,看到MySQL 8版本说明 MySQL集群是目前不在MySQL 8的支持。关于MySQL集群的信息,请参阅7.5、...

    php+mysql 博客

    php+mysql 博客php+mysql 博客php+mysql 博客php+mysql 博客php+mysql 博客php+mysql 博客php+mysql 博客php+mysql 博客php+mysql 博客php+mysql 博客

    国家开放大学 MySQL数据库应用 实验训练1 在MySQL中创建数据库和表

    国家开放大学 MySQL数据库应用 实验训练1 在MySQL中创建数据库和表

    辛星杂谈之mysql中的数据碎片

    数据碎片很大程度上是由于删除数据库中的数据造成的,这篇小文章讨论的是我们删除MyISAM中的数据造成的数据碎片以及解决办法。

    mysql8中文参考手册.pdf

    mysql

    基于 Spring Boot + MySQL 开发的博客系统源码.zip

    基于 Spring Boot + MySQL 开发的博客系统源码 基于 Spring Boot + MySQL 开发的博客系统源码 基于 Spring Boot + MySQL 开发的博客系统源码 基于 Spring Boot + MySQL 开发的博客系统源码 基于 Spring ...

    MySQL8中文参考手册 .chm

    MySQL参考手册。它的文件通过8.0.14 MySQL 8。它可以包括MySQL版本尚未发布功能的文档。关于哪个版本的信息已被释放,看到MySQL 8版本说明 MySQL集群是目前不在MySQL 8的支持。关于MySQL集群的信息,请参阅7.5、...

    MySQL中文参考手册

    &lt;br&gt;由于本人水平有限,文中肯定有不准确的地方,敬请在阅读过程中不吝指出。文中不明之处,请参阅手册原文。 &lt;br&gt;本文的内容针对MySQL 3.23.7alpla,实际上很多内容是通用的。另外,参考手册的几个附录也是...

    利用MysqlODBC把Sqlserver数据库导入到Mysql中

    将mysql数据库转换为sql server的数据库,或者将sql server数据库转换为mysql的数据库,在nt环境下很多时候都会用到。使用mysql odbc后就比较好办,可以使用sql server的管理工具,也可以使用mysql的管理工具,更可以...

    node.js+mysql博客全栈系统源码.zip

    node.js+mysql博客全栈系统源码,全栈开发个人博客系统,前台展示和后台管理一体化。 node.js + express + mysql 包含前端博客展示、后台管理、node后端。整套博客系统开箱即用,对elemen-ui二次封装组件非常便利,...

    mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册

    mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册mysql手册...

    jsp+mysql实现的博客系统

    采用java技术和mysql数据库技术开发的比克系统,是比较完善的博客系统开发案例,包含博客的发布,博客管理,用户评论,账号管理等功能,是学习的非常好的案例。

    oracle中的BLOB(照片)转换到mysql中

    从oracle中的BLOB类型字段中取出照片,转存到mysql数据库中。思路是现将oracle中的照片存储在本地文件夹,在将本地图片上传到mysql中。

    mysql中文手册+mysql命令大全+mysql存储过程

    mysql中文手册.chm+mysql命令大全.chm+mysql存储过程.pdf

    mysql5.5、mysql5.6、mysql5.7、mysql8 各种版本最新下载合集

    MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提 高了灵活性。 MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL ...

Global site tag (gtag.js) - Google Analytics