PostgreSQL 的大对象(Large Object)操作
shell
-- 查看所有大对象的 OID 和创建时间
SELECT oid, lomowner, lomacl
FROM pg_largeobject_metadata;
-- 删除大对象
SELECT lo_unlink(oid);
-- 查看大对象元数据
SELECT * FROM pg_largeobject_metadata;
-- 查看大对象的实际数据块(通常很大,不建议全量查询)
SELECT * FROM pg_largeobject WHERE loid = 12345; -- 替换为实际的大对象OID
-- 查看单个表的大小(包含索引和相关对象)
SELECT pg_size_pretty(pg_total_relation_size('表名'));
springboot 整合 PostgreSQL 的大对象(Large Object)操作
java
package com.huayi.iepms.common.utils.pg;
import org.postgresql.largeobject.LargeObject;
import org.postgresql.largeobject.LargeObjectManager;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.SQLException;
/**
* PostgreSQL大对象工具类
* @author: zrf
* @date: 2025/08/25 16:09
*/
@Component
public class PostgresLargeObjectUtil {
private final JdbcTemplate jdbcTemplate;
public PostgresLargeObjectUtil(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* 从输入流创建大对象并返回OID
*/
@Transactional
public long createLargeObject(InputStream inputStream) throws SQLException {
// 获取数据库连接并关闭自动提交
Connection connection = jdbcTemplate.getDataSource().getConnection();
connection.setAutoCommit(false);
try {
// 获取PostgreSQL大对象管理器
LargeObjectManager lobjManager = connection.unwrap(org.postgresql.PGConnection.class)
.getLargeObjectAPI();
// 创建大对象,返回OID
long oid = lobjManager.createLO(LargeObjectManager.READ | LargeObjectManager.WRITE);
// 打开大对象并写入数据
try (LargeObject largeObject = lobjManager.open(oid, LargeObjectManager.WRITE)) {
OutputStream outputStream = largeObject.getOutputStream();
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
connection.commit();
return oid;
} catch (Exception e) {
connection.rollback();
throw new SQLException("创建大对象失败", e);
} finally {
connection.close();
}
}
/**
* 根据OID读取大对象内容到输出流
*/
@Transactional(readOnly = true)
public void readLargeObject(long oid, OutputStream outputStream) throws Exception {
Connection connection = jdbcTemplate.getDataSource().getConnection();
try {
LargeObjectManager lobjManager = connection.unwrap(org.postgresql.PGConnection.class)
.getLargeObjectAPI();
try (LargeObject largeObject = lobjManager.open(oid, LargeObjectManager.READ)) {
InputStream inputStream = largeObject.getInputStream();
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
} finally {
connection.close();
}
}
/**
* 删除大对象(释放磁盘空间)
*/
@Transactional
public void deleteLargeObject(long oid) throws SQLException {
Connection connection = jdbcTemplate.getDataSource().getConnection();
connection.setAutoCommit(false);
try {
LargeObjectManager lobjManager = connection.unwrap(org.postgresql.PGConnection.class)
.getLargeObjectAPI();
lobjManager.delete(oid);
connection.commit();
} catch (Exception e) {
connection.rollback();
throw new SQLException("删除大对象失败", e);
} finally {
connection.close();
}
}
}