這次項目,我可以被oralce氣傷了。Oracle 9i怎麼會有那麼多問題,驅動怎麼會有那麼多問題。
好了,說問題吧。
這次的問題集中讀寫Oracle的blob、clob字段上。
1,讀寫blob需要一個lobhander,雖然defaultlobhander可以用於大多數數據庫和大多數oracle的版本,卻不能用過oracle 9i。我需要一個Oraclelobhander。
以下是spring中的配置。
以下是dao中的片段
/** * 更新指定的blob * @param key * @param contentStream * @param contentLength */ public void updateBlog(final String key, final InputStream contentStream, final int contentLength) { logger.debug("update content"); try { getJdbcTemplate().execute( "update table set content = ? where id = ?", new AbstractLobCreatingPreparedStatementCallback( this.lobHandler) { protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException { lobCreator.setBlobAsBinaryStream(ps, 1, contentStream, contentLength); ps.setString(2, key); } }); } catch (RuntimeException re) { logger.warn("update content fail"); throw re; } } /** * 取得指定的blob * @param name * @param contentStream * @throws DataAccessException */ public void getBlobContent(final String id, final OutputStream contentStream) throws DataAccessException { getJdbcTemplate().query( "SELECT content FROM table WHERE id=?", new String[] {id}, new AbstractLobStreamingResultSetExtractor() { protected void handleNoRowFound() throws LobRetrIEvalFailureException { throw new IncorrectResultSizeDataAccessException( "Image with id '" + id + "' not found in database", 1, 0); } public void streamData(ResultSet rs) throws SQLException, IOException { InputStream is = lobHandler.getBlobAsBinaryStream(rs, 1); if (is != null) { FileCopyUtils.copy(is, contentStream); } } } ); }
前一個方法是寫blob,後一個讀blob。後面一個在業務方法中,這樣用。
public void getBlobContent(HttpServletRequest request, HttpServletResponse response) { try { serviceDisplayDAO.getBlobContent(request.getParameter("id"),response.getOutputStream()); } catch (DataAccessException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
在頁面中只需要做個鏈接:href="/blob.do?action=getBlogContent&id='"+id+"'"
2,讀寫clob
這個要簡單一些,不過要需要oracle的驅動不能用class12.zip那個,要從Oracle下一個新的版本,具體多少不記得了。
/** * 基於主鍵的查詢方法 根據給出的主鍵查詢一個業務並返回 * * @param key * @return */ public List findByPrimaryKey(String key) { logger.debug("finding service by primary key"); try { return getJdbcTemplate().query( "SELECT serviceid,contenttype,templatetext FROM table where serviceid='"+key+"'", new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { String serviceid = rs.getString(1); String contenttype = rs.getString(2); String templatetext = lobHandler.getClobAsString(rs, 3); return new ServConTempBean(serviceid, contenttype, templatetext); } }); } catch (RuntimeException re) { logger.warn("finding service by primary key failed", re); throw re; } } /** * 根據業務主鍵更新信息 * @param key * @param params * @param types * @return */ public void updateContentByPrimaryKey(final String key,final String templatetext) { logger.debug("update service content by content template primary key"); try { getJdbcTemplate().execute( "update table set templatetext=? where serviceid=?", new AbstractLobCreatingPreparedStatementCallback(this.lobHandler) {protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException { lobCreator.setClobAsString(ps, 1, templatetext); ps.setString(2, key); } } ); } catch (RuntimeException re) { logger.warn("update service by service primary key failed", re); throw re; } }