javaGrowing

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            92 隨筆 :: 33 文章 :: 49 評論 :: 0 Trackbacks
          JDBC高級應用(二)
          本來想繼續談JDBC的高級連結方式,事務模式.但發現關于大對象存儲有很多人在問,所以
          先來插入一節關于大對象存儲的內容,然后再接著原來的思路寫下去.

          JDBC的大對象存儲聽起來復雜,其實如果你明白了原理以后,就非常簡單,網上有關這方面的
          教材很少,而SUN的文檔中,我從1.2開始看到一在仍然是錯誤的,不知道寫文檔的人長腦子沒
          有,就那幾行代碼你試試不就知道了,這么多次重抄下來還是錯誤的.


          大對象分類:一般來說,大對象分為:大的文本對象,比如一個很長的文本(請你要注意什么是
          文本文件,什么是二進制文件)文件,或者是你定義的一個長字符串,比如你定義了:
          String s = "我們要去吃飯了......................然后睡覺!";
          從吃飯到睡覺中間省略了實際的10000000000000字,雖然你不會真的定義這么稱的String,但
          有時會從什么地方得到這樣的String,要寫到數據庫中.
          另一種就是大的二進制對象,象執行文件,圖象文件等,注意,word,excel,ppt這些"帶格式"的文
          檔都應該以二進制對象存儲.

          一般來說,數據庫如果支持大對象存儲,會有這幾種類型的SQL數據類型:
          BLOB,CLOCB,NLOB,也有的數據數只有一種BLOB,基本上是這樣的:BLOB用來存放二進制文件,而
          CLOB用來存放文本文件,NLOB是對多字節文本文件支持.假如你的文本文件是純英文的,放在
          BLOB中當然可以,也就是說它是以byte格式存儲的,而多字節是以CHAR格式存儲的.

          同樣對于這幾種類型的文檔,有幾種相對應的存取方式:
          setter:
          利用PreparedStatement的setXXX方法,
          setAsciiStream()方法用于寫入一般的文本流.setBinaryStream()方法用于寫入二進制流
          而setUnicodeStream()用于寫好UNICODE編碼的文本,與此相對應的ResultSet中三個getter方法
          用于取回:getAsciiStream(),getBinaryStream(),getBinaryStream().
          對于文件本身,要把它作為一個流,只要new InputStream(new FileInputStream("文件路徑"))
          就可以了,但對于大的String對象,你不會寫入文件再轉換成輸入流吧?
          new StringBufferInputStream(String s),記住了.
          JDBC2以后提供了java.sql.BLOB對象,我不建議大家使用它,一是很麻類,二是容易出錯,要先插
          入一個空的BLOB對象,然后再填充它,實在沒有必要,直接setXXX就行了,我試過,至少mysql,
          oracle,sql server是可以直接set的.
          好了,我們先看一個例子如何寫入文件到數據庫:
          數據結構:
          create table test(
            name varchar(200),
            content BLOB
          );
          File f = new File("a.exe");//先生成File對象是為了取得流的長度.FileInputStram可以直接
                                     //傳入文件路徑
          InputStream in = new InputStream(new FileInputStream(f));
          PreparedStatement ps = conn.prepareStatement("insert into test (?,?)");
          ps.setString(1,"a.exe");
          ps.setBinaryStream(2,in,(int)f.length());
          ps.executeUpdate();
          f的長度一定要做從long到int的轉換,SUN的文檔中好幾版都沒有改過來.就這么簡單,當然,不同的
          數據庫存本身要設置它允許的最大長度,MYSQL默認只能傳1M的文件,要修改參數原能存更大的文件.
          如果要從數庫中取得文件:
          PreparedStatement ps = conn.prepareStatement("select * from test where name=?");
          ps.setString(1,"a.exe");
          ResultSet rs = ps.executeQuery();
          if(rs.next()){
           InputStream in = rs.getBinaryStream("content");
          }
          得到in對象后,你可以進行任何處理,寫向文件和寫向頁面只是out對象不同而已:
          寫向文件:
          DateOutputStream out = new DateOutputStream(new FileOutputStream("b.exe"));
          寫向頁面:
          response.reset();
          response.setContType("類型");
          ServletOutputSreamt out = response.getOutputSream();
          得到out對象后,就可以輸出了:
          byte[] buf = new byte[1024];
          int len = 0;
          while((len = in.read(buf)) >0)
            out.write(buf,0,len);
          in.close();
          out.close();
          對于向頁面輸入,要設置什么樣的ContType,要看你想如何輸出,如果你想讓對方下載,就設為
          "application/octet-stream",這樣即使是文本,圖象都會下載而不會在瀏覽器中打開.如果你要想
          在瀏覽器中打開,就要設置相應的類型,還要在容器的配置文件中設置支持這種文檔類型的輸出,但
          對于很多格式的文件,到底要輸出什么類型,其實就是HTTP的MIME集,比如圖片:image/gif,當然你如
          果你的文件擴展名(ext)不確定,你也不要用if(ext.equals("gif"))......這樣來判斷,我教你一個
          技巧,我之所以說是技巧,是我沒有在別的地方發現有人用這種方法,對我來說我是絕對不會把別人的
          方法拿來說是我的技巧的:
          構造一個file類型的URL,我們知道URL目前JAVA可以支持HTTP,FTP,MAILTO,FILE,LDAP等,從FILE類型
          的URL就可以得到它的MIME:

          URL u = new URL("file://a.exe");
          String mime = u.openConnection().getContentType();
          這樣你就可以直接response.setContType(mime);而不用一個一個類型判斷了.
          好了,大對象存儲就說到這兒,不同的數據仍然和些特殊的規定,不在此一一列舉了.
          posted on 2006-01-09 10:08 javaGrowing 閱讀(315) 評論(0)  編輯  收藏 所屬分類: JDBC

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 腾冲县| 台北市| 内江市| 永靖县| 福海县| 扬州市| 体育| 旌德县| 江口县| 平乡县| 济源市| 四会市| 金川县| 洛浦县| 苏尼特右旗| 丹棱县| 沁阳市| 宾川县| 周至县| 海口市| 博爱县| 闽清县| 舟山市| 锡林浩特市| 团风县| 监利县| 永年县| 彰化县| 鹤壁市| 澄城县| 南靖县| 梅州市| 平邑县| 林西县| 鹤壁市| 湘乡市| 夹江县| 白玉县| 高台县| 新河县| 宁武县|