我這裏有一張表的列類型是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