如何通过JDBC写入BLOB文件_setBinaryStream上传图片与大文件至数据库
PreparedStatement.setBinaryStream写不进数据库的主因是流被提前关闭或未触发实际写入MySQL需配置useServerPrepStmtstrue并传精确长度PostgreSQL要求事务内操作且字段为byteaOracle不支持带长度参数的重载。PreparedStatement.setBinaryStream 为什么写不进数据库常见现象是执行完 executeupdate() 没报错但查数据库发现 blob 字段为 null 或空字节。根本原因不是 api 用错了而是流被提前关闭或未触发实际写入。必须确保传入的 InputStream 在 executeUpdate() 调用前仍处于可读状态比如文件没被 close网络流没超时MySQL 驱动默认把大对象当“客户端临时数据”处理如果连接配置没开 useServerPrepStmtstruesetBinaryStream 可能被降级成 setBytes悄悄把整个流加载进内存再转 byte[] —— 大文件直接 OOMPostgreSQL 的 setBinaryStream 要求字段类型明确是 bytea且不能在事务外调用否则抛 PGSQLException: Large Objects may not be used outside a transactionMySQL 和 PostgreSQL 的 setBinaryStream 参数差异两个主流驱动对第二个参数长度的处理逻辑完全不同填错就静默失败。MySQLConnector/J 8.0第二个参数是「精确字节数」必须传真实长度传 -1 会回退到 setBytes传 0 直接写空 blobPostgreSQLpgjdbc 42.6第二个参数是「最大预期长度」可以略大于实际值如传 10 * 1024 * 1024 写 5MB 图片但不能为 0 或负数传 -1 会抛异常Oracleojdbc8不支持 setBinaryStream(int, InputStream, long) 重载只能用 setBinaryStream(int, InputStream)无长度参数靠流 EOF 判断结束示例MySQL 安全写法File file new File(/tmp/photo.jpg);try (FileInputStream fis new FileInputStream(file)) { ps.setBinaryStream(1, fis, file.length()); // 必须是 file.length() ps.executeUpdate();}上传大文件时连接和事务怎么配才不崩BLOB 写入本质是长耗时 I/O不调优的话要么连不上要么事务超时要么驱动自己 abort。MySQL 连接串加 maxAllowedPacket256MconnectTimeout30000socketTimeout600000否则 16MB 以上文件直接被服务端拒收PostgreSQL 必须显式开启事务conn.setAutoCommit(false);ps conn.prepareStatement(INSERT INTO docs(name, content) VALUES (?, ?));ps.setBinaryStream(2, fis, fileSize);ps.executeUpdate();conn.commit(); // 不 commitLOB 资源不释放别在 Spring Transactional 方法里直接传 request.getInputStream() —— HTTP 请求流只读一次第二次调用 setBinaryStream 会读到空流为什么图片存进去了却打不开不是编码问题是内容被意外截断或污染。最常踩的三个坑 JoinMC智能客服 JoinMC智能客服帮您熬夜加班7X24小时全天候智能回复用户消息自动维护媒体主页全平台渠道集成管理电商物流平台一键绑定让您出海轻松无忧