spring,hibernate處理Lob型別資料
Lob代表大物件資料,包括BLOB和CLOB兩種型別資料,前者用於儲存大塊的二進位制資料,如圖片和視訊資料等,而後者用於儲存長文字資料,如論壇帖子內容,產品詳細描述等。在不同的資料庫中,大物件對應的欄位型別往往不一樣,如oracle對應的是BLOB/CLOB;Mysql對應的BLOB/LONGTEXT;SQLSERER對應IMAGE/TEXT,有些資料庫對大物件型別可以像簡單型別一樣訪問,如mysql的LONGTEXT的操作方式和VARCHAR型別一樣,在一半情況下,LOB型別資料的訪問不同於其他簡單型別的資料,使用者可能會以流的方式操作LOB型別的書。此外,LOB型別的資料訪問並不是執行緒安全的,需要分配相應的資料庫資源,並在操作後完成釋放。最後oracle非常有個性地採用非jdbc標準的api操作lob資料,spring為此在org.springframework.jdbc.support.lob包中提供幫助類
LobCreator
雖然jdbc定義了兩個操作LOB型別的介面:java.sql.BLOB,java.sql.CLOB,但是有些廠商的jdbc驅動程式並不支援這兩個介面。為此,spring定義了一個獨立於java.sql.blob/java.sql.clob介面,以統一的方式操作各種資料庫LOB型別的lobCreator介面,因為LobCreator本身執有Lob所對應的資料庫資源,所以它不是執行緒安全,一個LOBcREATOR只能操作一個Lob資料
LobCreator介面對應的方法
void close();關閉會話,並釋放Lob資源
void setBlobAsBinaryStream(PreparedStatement ps,int paramIndex,InputStream,int contentLength)通過流填充Blob資料
void setBlobAsBytes(PreparedStatement ps,int paramIndex,byte[] content);通過二進位制填充Blob資料
void setClobAsCharacterStream(PreparedStatement ps,int paramIndex,Reader characterStream,int contentLength);通過Unicode字元流填充clob資料
void setClobAsAsciiStream(PreparedStatement ps,int paramIndex,InputStream asciiStream,int contentLength);通過Ascii字元流填充clob資料
void setClobAsStream(PreparedStatement ps,int paramIndex,String content) 通過字串填充clob資料
LobHandler
lobhandler介面為操作大二進位制欄位和大文字欄位提供統一的訪問介面訪問,不管底層資料庫是以大物件的方式還是一般資料型別進行操作,lobhandler還充當了lobcreator的工廠類
InputStream getBlobAsBinaryStream(ResultSet rs,int columnIndex)從結果集中返回InputStream,通過InputStream讀取Blob資料
byte[] getBlobAsBytes(ResultSet rs,int columnIndex);以二進位制資料的方式讀取結果集中的Blobshuju
InputStream getClobAsAssciiStream(ResultSet rs,int columnIndex)從結果集中返回InputStream,通過InputStream 以Asscii字元流方式讀取Blob資料
Reader getClobAsCharacterStream(ResultSet rs,int columnIndex);從結果集中獲取Unicode字元流Reader,並通過Reader以Unicode字元流方式讀取Clob資料
getClobAsStream(ResultSet rs,int columnIndex)會從結果集中以字串的方式獲取clob資料
xml配置檔案
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true"/>
測試類
@Test
public void handle14() throws IOException{
File file = new File("F:\\e.png");
final byte[] mockImg = FileCopyUtils.copyToByteArray(file);
String sql = "insert into tb_content(image)values(?)";
jdbcTemplate.execute(sql, new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
@Override
protected void setValues(PreparedStatement ps, LobCreator lobCreator)
throws SQLException, DataAccessException {
lobCreator.setBlobAsBytes(ps, 1, mockImg);
}
});
}
@Test
public void handle15() throws IOException{
final File file = new File("F:\\d.png");
String sql = "select * from tb_content where id=3";
jdbcTemplate.query(sql, new RowMapper(){
@Override
public Object mapRow(ResultSet rs, int arg1) throws SQLException {
byte[] attach = lobHandler.getBlobAsBytes(rs, 1);
try {
FileOutputStream outputStream = new FileOutputStream(file);
try {
outputStream.write(attach, 0, attach.length);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
});
}
}
spring+hibernate處理Blob型別的資料
實體類
@Entity(name = "tb_news")
public class NewsContent {
private Integer id;
private byte[] photo;
public NewsContent(){}
public NewsContent(Integer id){
this.id = id;
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name ="photo",columnDefinition="longblob")
public byte[] getPhoto() {
return photo;
}
public void setPhoto(byte[] photo) {
this.photo = photo;
}
}
測試:
@Test
public void handle2() throws IOException{
NewsContent content = new NewsContent();
File file = new File("F:\\e.png");
byte[] bytes = FileUtils.readFileToByteArray(file);
content.setPhoto(bytes);
Session session = sessionFactory.openSession();
session.save(content);
}
@Test
public void handle3() throws IOException{
File file = new File("F:\\e.png");
FileOutputStream out = new FileOutputStream(file);
Session session = sessionFactory.openSession();
NewsContent content = (NewsContent)session.get(NewsContent.class, 1);
byte[] bytes = content.getPhoto();
out.write(bytes, 0, bytes.length);
}