風之力

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            19 Posts :: 2 Stories :: 18 Comments :: 0 Trackbacks

          做了個簡單的通告管理,在本機測試時數據量比較小。最開始用的時varchar2到2000,之后用hibernate中的text類型,對應數據庫中的Clob類型。當數據量小于4000時,可以直接使用setObject()插入數據庫。當數據量大于4000時。報錯:socket write error。
          查找了一些資料,說當數據量超過4000時,應該使用流方式操作??吹筋^昏昏,煩都煩死了......
          最后發現Spring封裝了對lob數據的操作,可以直接使用jdbcTemple操作lob數據。
          當使用MySql、MSSQL、Oracle 10g時,使用DefaultLobHandler;使用Oracle 9i時使用OracleLobHandler。
          示例代碼:【轉值javaWorld】

          ?1?????????final?File?binaryFile?=?new?File("c:\\workspace\\wish.jpg" );
          ?2?????????final?File?txtFile?=?new?File("c:\\workspace\\test.txt"
          );
          ?3?
          ???????
          ?4?????????final?InputStream?is?=?new
          ?FileInputStream(binaryFile);
          ?5?????????final?Reader?reader?=?new
          ?FileReader(txtFile);
          ?6?
          ???????
          ?7?????????JdbcTemplate?jdbcTemplate?=?new
          ?JdbcTemplate(dataSource);
          ?8?
          ???????
          ?9?????????final?LobHandler?lobHandler?=?new
          ?DefaultLobHandler();
          10?
          ???????
          11?????????jdbcTemplate.execute("INSERT?INTO?test?(txt,?image)?VALUES(?,??)"
          ,
          12??????????????????????new
          ?AbstractLobCreatingPreparedStatementCallback(lobHandler)?{
          13?????????????????????????protected?void
          ?setValues(PreparedStatement?pstmt,?LobCreator?lobCreator)
          14????????????????????????????????????????????????????????????throws
          ?SQLException,?DataAccessException?{
          15?????????????????????????????lobCreator.setClobAsCharacterStream(pstmt,?1,?reader,?(int
          )?txtFile.length());
          16?????????????????????????????lobCreator.setBlobAsBinaryStream(pstmt,?2,?is,?(int
          )?binaryFile.length());
          17?
          ????????????????????????}
          18?
          ?????????????????????});
          19?
          ???????
          20?
          ????????reader.close();
          21?
          ????????is.close();
          22?

          讀取代碼:

          ?1?????????final?Writer?writer?=?new?FileWriter("c:\\workspace\\test_bak.txt" );
          ?2?????????final?OutputStream?os?=?new?FileOutputStream(new?File("c:\\workspace\\wish_bak.jpg"
          ));
          ?3?
          ???????
          ?4?????????jdbcTemplate.query("SELECT?txt,image?FROM?test?WHERE?id?=??"
          ,
          ?5?????????????????new?Object[]?{new?Integer(1
          )},
          ?6?????????????????new
          ?AbstractLobStreamingResultSetExtractor()?{
          ?7?????????????????????protected?void?streamData(ResultSet?rs)?throws
          ?SQLException,?IOException,?DataAccessException?{
          ?8?????????????????????????FileCopyUtils.copy(lobHandler.getClobAsCharacterStream(rs,?1
          ),?writer);
          ?9?????????????????????????FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs,?2
          ),?os);
          10?
          ????????????????????}
          11?
          ?????????????????});
          12?
          ????????writer.close();
          13?
          ????????os.close();
          14?

          15?
          備注1:OracleLobHandler要求注入CommonsDbcpNativeJdbcExtractor,否則報錯:要求使用OracleConnection,不可以使用Dbcp連接池。
          1 ???? < bean?id = " lobHandler " ? class = " org.springframework.jdbc.support.lob.OracleLobHandler " >
          2 ???? < property?name = " nativeJdbcExtractor " >
          3 ??????? < bean? class = " org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor " />
          4 ??? </ property >
          5 ??? </ bean >
          備注2:Oracle驅動版本很多,要求使用正確的驅動。當驅動版本錯誤時,報錯:無法釋放LobHandler;無法關閉Writer;無法從套接字讀取更多的信息。執行插入操作,但是Clob類型數據為空。
          posted on 2006-11-08 16:20 風之力 閱讀(5577) 評論(4)  編輯  收藏 所屬分類: java

          Feedback

          # re: spring下lob數據處理【原創】 2008-08-01 15:29 gyhgc
          同時讀取多個圖片文件呢,如何處理呢?
          String name = rs.getString(2);
          final OutputStream os = new FileOutputStream(new File(path+name));
          FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 1), os);
          list.add(name);
          os.close();
          while(rs.next()){
          name = rs.getString(2);
          final OutputStream os1 = new FileOutputStream(new File(path+name));
          FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 1), os1);
          list.add(name);
          os1.close();

          }
          直接寫while(rs.next()) 第一個圖片取不到,如何寫才正確呢?  回復  更多評論
            

          # re: spring下lob數據處理【原創】 2008-08-04 10:14 風之力
          @gyhgc
          不是很明白你的意思,操作應該都是一樣的
          你是指不要上面那段,直接寫
          while(rs.next()){
          name = rs.getString(2);
          final OutputStream os1 = new FileOutputStream(new File(path+name));
          FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 1), os1);
          list.add(name);
          os1.close();
          }
          取不到第一張圖片?
            回復  更多評論
            

          # re: spring下lob數據處理【原創】 2008-08-04 11:10 gyhgc
          是的,就是rs的指針已經指向了第一行的位置。rs.next()只能從第二行開始讀取了。  回復  更多評論
            

          # re: spring下lob數據處理【原創】 2008-08-05 08:57 風之力
          @gyhgc
          AbstractLobStreamingResultSetExtractor的
          public final Object extractData(ResultSet rs) throws SQLException, DataAccessException {
          if (!rs.next()) {
          handleNoRowFound();
          }
          else {
          try {
          streamData(rs);
          if (rs.next()) {
          handleMultipleRowsFound();
          }
          }
          catch (IOException ex) {
          throw new LobRetrievalFailureException("Couldn't stream LOB content", ex);
          }
          }
          return null;
          }
          是先做了一次rs.next()的,所以rs的指針是指到第一行的
          你可以do{}while(rs.next())的嘛......
            回復  更多評論
            

          主站蜘蛛池模板: 滁州市| 福清市| 兴宁市| 龙门县| 大丰市| 巴彦县| 天峨县| 德州市| 文登市| 民县| 舒城县| 沂南县| 科技| 云阳县| 梅州市| 四平市| 民乐县| 洪江市| 合水县| 铁力市| 阿克苏市| 府谷县| 中超| 宜丰县| 宜君县| 望都县| 延吉市| 鱼台县| 民乐县| 新营市| 土默特左旗| 石柱| 嘉义县| 长春市| 阿尔山市| 霍山县| 舒兰市| 黎城县| 咸阳市| 兴安县| 漳平市|