我这里有一张表的列类型是bytea型,也就是文件的二进制数据,它属于大对象(Large Objects)。
(什么是大对象) 把二进制数据插入表中须要如下几个步骤。html
postgreSQL官方文档中,存储二进制是用Java的PreparedStatement#setBinaryStream方法。spring
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)");
ps.setString(1, file.getName());
ps.setBinaryStream(2, fis, file.length());
ps.executeUpdate();
ps.close();
fis.close();
复制代码
读取二进制则用ResultSet.getBytes()数据库
PreparedStatement ps = con.prepareStatement("SELECT img FROM images WHERE imgname = ?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
if (rs != null) {
while (rs.next()) {
byte[] imgBytes = rs.getBytes(1);
// 业务
}
rs.close();
}
ps.close();
复制代码
实体类的编码至关的简单。咱们只须要把相关的二进制字段声明为byte数组类型,Mybatis就会自动处理。这是由于在MyBatis 3.4中提供了TypeHandler处理BLOB/CLOB数据。数组
// 实体类字段
public class Entity {
......
private byte[] phototemplate;
.....
}
复制代码
像往常同样我把数据insert到表中时,出现了如下PSQLException。bash
大对象不能用于自动提交模式(Large Objects may not be used in auto-commit mode)
复制代码
因而改为了手动提交事务,终于成功插入了数据。 有时候咱们须要手动提交事务,好比说很大的数据分次提交,避免内存溢出。又或者插入二进数据到表中。
这里的关键是本身把DataSourceTransactionManager注入,并使用它进行事务处理。mybatis
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Service
public class IndicationmessagesServiceImpl {
@Autowired
MyMapper mapper;
@Autowired
private DataSourceTransactionManager transactionManager;
public void insert() throws Exception {
// 业务逻辑
// TODO
DefaultTransactionDefinition transDefinition = new DefaultTransactionDefinition();
// 开始新事物
transDefinition.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus transStatus = transactionManager.getTransaction(transDefinition);
try {
mapper.insert(entity);
// 提交事务
transactionManager.commit(transStatus);
} catch (Exception e) {
// 回滚事务
transactionManager.rollback(transStatus);
throw new Exception(e);
}
}
}
复制代码
我这里是读取图片文件的二进制数据,而后赋值给上面的phototemplate字段。app
private byte[] readAll(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
try (ByteArrayOutputStream bout = new ByteArrayOutputStream();) {
int len;
while (-1 != (len = inputStream.read(buffer))) {
bout.write(buffer, 0, len);
}
return bout.toByteArray();
}
}
复制代码
最后执行上述service的insert方法,插入到数据库。
select phototemplate结果 post