You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java通过REST API从MySQL读取图片报Blob容器构建器不存在错误

问题原因

你的报错是JDBI 2.x版本未内置java.sql.Blob类型的容器构造器导致的,当你定义DAO方法直接返回Blob类型时,JDBI无法将数据库返回的大字段结果封装为Blob实例。
另外还有一个隐藏问题:java.sql.Blob是和数据库连接生命周期绑定的,一旦数据库连接关闭,即使你拿到Blob实例也无法读取其中的内容,后续调用handleBlob方法同样会报错。

解决方案

推荐优先采用第一种方案,实现成本最低且稳定性更高:

方案1:修改DAO方法返回值为byte[]

JDBI默认支持将MySQL的BLOB类型列直接映射为字节数组,你只需要调整retrieveImage对应的DAO方法、Factory方法的返回值类型从Blob改为byte[]即可,不需要修改SQL逻辑,也不需要额外配置映射器。
调整后你的业务代码可以简化为:

// 不需要再调用handleBlob处理Blob,直接拿到图片字节数组
byte[] image = BooksFactory.retrieveImage(b.getBookId());

方案2:自定义注册Blob容器工厂(不推荐)

如果业务必须使用Blob类型,你可以手动为JDBI注册Blob类型的容器构造器,示例代码如下:

// 初始化JDBI的时候注册
jdbi.registerContainerFactory(new ContainerFactory<Blob>() {
    @Override
    public boolean accepts(Class<?> type) {
        return Blob.class.isAssignableFrom(type);
    }

    @Override
    public ContainerBuilder<Blob> newContainerBuilderFor(Class<?> type) {
        return new ContainerBuilder<Blob>() {
            private Blob blob;
            @Override
            public ContainerBuilder<Blob> add(Object it) {
                this.blob = (Blob) it;
                return this;
            }

            @Override
            public Blob build() {
                return blob;
            }
        };
    }
});

注意该方案需要额外处理数据库连接生命周期,确保读取Blob内容时连接未关闭,维护成本更高。

额外优化建议

  • 你当前的逻辑是先查全量书籍列表,再循环调用接口查每本书的图片和库存,属于典型的N+1查询问题,数据量大的时候性能会非常差,建议修改listAllBooks的SQL语句,关联查询库存和图片字段,一次查询返回所有需要的内容。
  • 你当前将图片存储在本地E盘并返回本地路径给前端,前端无法直接访问该路径,建议将图片存储在静态资源服务目录,返回对应的HTTP访问路径,或者将图片转为Base64字符串放在返回结果中。

内容的提问来源于stack exchange,提问作者Pallavi Prasad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 22:57:01