[原]向MySQL数据库插入Blob数据的问题

[标题]:向MySQL数据库插入Blob数据的问题
[时间]:2009-6-3
[摘要]:在使用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、&
[环境]: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

[参考资料]:
Mysql 中的blob相关问题 : http://fenghuang.iteye.com/blog/363931
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中,可以使用 JDBC API 来将从 MySQL 数据库中检索到的 BLOB 数据转换为图片并显示出来。下面是具体的步骤: 1. 使用 JDBC API 连接到 MySQL 数据库,并执行 SELECT 语句以检索包含图片的 BLOB 列。 ```java Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password"); PreparedStatement stmt = conn.prepareStatement("SELECT data FROM images WHERE id = ?"); stmt.setInt(1, 1); ResultSet rs = stmt.executeQuery(); ``` 其中,1 是图片所在行的 ID。 2. 从 ResultSet 对象中提取 BLOB 列中的二进制数据。 ```java if (rs.next()) { Blob blob = rs.getBlob("data"); InputStream inputStream = blob.getBinaryStream(); } ``` 3. 将二进制数据转换为图片,并将其显示在 UI 上。 ```java Image image = ImageIO.read(inputStream); JLabel label = new JLabel(new ImageIcon(image)); JFrame frame = new JFrame(); frame.getContentPane().add(label, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); ``` 其中,ImageIO 类用于将二进制数据转换为 Image 对象,JLabel 用于显示 Image 对象,JFrame 用于创建 UI 窗口。 完整的代码示例如下: ```java import java.awt.BorderLayout; import java.awt.Image; import java.io.InputStream; import java.sql.Blob; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; public class App { public static void main(String[] args) { try { Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password"); PreparedStatement stmt = conn.prepareStatement("SELECT data FROM images WHERE id = ?"); stmt.setInt(1, 1); ResultSet rs = stmt.executeQuery(); if (rs.next()) { Blob blob = rs.getBlob("data"); InputStream inputStream = blob.getBinaryStream(); Image image = ImageIO.read(inputStream); JLabel label = new JLabel(new ImageIcon(image)); JFrame frame = new JFrame(); frame.getContentPane().add(label, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } } catch (Exception e) { e.printStackTrace(); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值