posts - 22, comments - 17, trackbacks - 0, articles - 15
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          2006年12月13日

          1Mark

          posted @ 2014-10-13 15:57 碼農(nóng)cz 閱讀(113) | 評(píng)論 (0)編輯 收藏

          2Mark

          posted @ 2014-10-13 15:57 碼農(nóng)cz 閱讀(111) | 評(píng)論 (0)編輯 收藏



          至此,準(zhǔn)備工作就可以了。

          看看頁(yè)面怎么寫的

          運(yùn)行,就可以了。

          posted @ 2014-10-13 15:50 碼農(nóng)cz 閱讀(164) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文

          posted @ 2012-07-18 15:07 碼農(nóng)cz 閱讀(850) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文

          posted @ 2012-07-18 14:45 碼農(nóng)cz 閱讀(1271) | 評(píng)論 (0)編輯 收藏

          在struts2中,獲取表單元素有三種方式:
          1.在action類中,為屬性提供get/set方法。
          2.使用javabean的引用,提供get/set方法。但是表單中名字必須是javabean引用的名字.屬性名。
          3.實(shí)現(xiàn)Modeldriven接口。

          posted @ 2012-07-05 14:59 碼農(nóng)cz 閱讀(182) | 評(píng)論 (0)編輯 收藏

               摘要: 說(shuō)實(shí)話,eclipse我受夠了.自從用了Intellijidea ,我的腰不酸了,腿不疼了,一口氣能上一層樓.先上代碼結(jié)構(gòu)數(shù)據(jù)庫(kù)表結(jié)構(gòu) Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1 CREATE DATABASE...  閱讀全文

          posted @ 2012-07-05 14:48 碼農(nóng)cz 閱讀(265) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文

          posted @ 2008-05-15 10:42 碼農(nóng)cz 閱讀(951) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文

          posted @ 2008-05-15 10:39 碼農(nóng)cz 閱讀(6534) | 評(píng)論 (8)編輯 收藏

               摘要:   閱讀全文

          posted @ 2008-05-15 10:37 碼農(nóng)cz 閱讀(1743) | 評(píng)論 (3)編輯 收藏

               摘要:   閱讀全文

          posted @ 2008-05-14 09:24 碼農(nóng)cz 閱讀(244) | 評(píng)論 (0)編輯 收藏

          Map接口:
              |
              + -- WeakHashMap: 以弱鍵 實(shí)現(xiàn)的基于哈希表的 Map。在 WeakHashMap 中,當(dāng)某個(gè)鍵不再正常使用時(shí),將自動(dòng)移除其條
              |      目。更精確地說(shuō),對(duì)于一個(gè)給定的鍵,其映射的存在并不阻止垃圾回收器對(duì)該鍵的丟棄,這就使該鍵成為可終止的,被終
              |      止,然后被回收。丟棄某個(gè)鍵時(shí),其條目從映射中有效地移除,因此,該類的行為與其他的 Map 實(shí)現(xiàn)有所不同。此實(shí)現(xiàn)
              |      不是同步的。
              |
              + -- TreeMap:該映射根據(jù)其鍵的自然順序進(jìn)行排序,或者根據(jù)創(chuàng)建映射時(shí)提供的 Comparator 進(jìn)行排序,具體取決于使用的
              |    構(gòu)造方法。此實(shí)現(xiàn)不是同步的。
              |
              + -- HashMap:基于哈希表的 Map 接口的實(shí)現(xiàn)。此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了      
              |        非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順   
              |       序恒久不變。此實(shí)現(xiàn)不是同步的。
              |
              +-- SortedMap: 進(jìn)一步提供關(guān)于鍵的總體排序 的 Map。該映射是根據(jù)其鍵的自然順序進(jìn)行排序的,或者根據(jù)通常在創(chuàng)建有
                   序映射時(shí)提供的 Comparator 進(jìn)行排序。對(duì)有序映射的 collection 視圖(由 entrySet、keySet 和 values 方法返回
                   )進(jìn)行迭代時(shí),此順序就會(huì)反映出來(lái)。要采用此排序方式,還需要提供一些其他操作(此接口是 SortedSet 的對(duì)應(yīng)映
                   射)。

          Collection接口:
              |
              + -- Set接口:一個(gè)不包含重復(fù)元素的 collection。更正式地說(shuō),set 不包含滿足 e1.equals(e2) 的元素對(duì) e1 和 e2,并
              |      |     且最多包含一個(gè) null 元素。正如其名稱所暗示的,此接口模仿了數(shù)學(xué)上的 set 抽象。
              |      |
              |      + -- HashSet:此類實(shí)現(xiàn) Set 接口,由哈希表(實(shí)際上是一個(gè) HashMap 實(shí)例)支持。它不保證 set 的迭代順序;
              |      |    特別是它不保證該順序恒久不變。此類允許使用 null 元素。此類為基本操作提供了穩(wěn)定性能,此實(shí)現(xiàn)不是同
              |      |    步的。
              |      |
              |      + -- LinkedHashSet:具有可預(yù)知迭代順序的 Set 接口的哈希表和鏈接列表實(shí)現(xiàn)。此實(shí)現(xiàn)與 HashSet 的不同之外在
              |      |    于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,即按照將元素插入到 set
              |      |    中 的順序(插入順序)進(jìn)行迭代。注意,插入順序不 受在 set 中重新插入的 元素的影響。此實(shí)現(xiàn)不是同步
              |      |    的。
              |      |
              |      + -- TreeSet:基于 TreeMap 的 NavigableSet 實(shí)現(xiàn)。使用元素的自然順序?qū)υ剡M(jìn)行排序,或者根據(jù)創(chuàng)建 set 時(shí)
              |           提供的 Comparator 進(jìn)行排序,具體取決于使用的構(gòu)造方法。此實(shí)現(xiàn)為基本操作(add、remove 和 contains)
              |           提供受保證的 log(n) 時(shí)間開(kāi)銷。此實(shí)現(xiàn)不是同步的。
              |
              + -- List接口:有序的 collection(也稱為序列)。此接口的用戶可以對(duì)列表中每個(gè)元素的插入位置進(jìn)行精確地控制。用戶
                     |      可以根據(jù)元素的整數(shù)索引(在列表中的位置)訪問(wèn)元素,并搜索列表中的元素。
                     |
                     + -- ArrayList:List 接口的大小可變數(shù)組的實(shí)現(xiàn)。實(shí)現(xiàn)了所有可選列表操作,并允許包括 null 在內(nèi)的所有元素。
                     |    除了實(shí)現(xiàn) List 接口外,此類還提供一些方法來(lái)操作內(nèi)部用來(lái)存儲(chǔ)列表的數(shù)組的大小。(此類大致上等同于
                     |    Vector 類,除了此類是不同步的。)每個(gè) ArrayList 實(shí)例都有一個(gè)容量。該容量是指用來(lái)存儲(chǔ)列表元素的數(shù)
                     |    組的大小。它總是至少等于列表的大小。隨著向 ArrayList 中不斷添加元素,其容量也自動(dòng)增長(zhǎng)。并未指定增
                     |    長(zhǎng)策略的細(xì)節(jié),因?yàn)檫@不只是添加元素會(huì)帶來(lái)分?jǐn)偣潭〞r(shí)間開(kāi)銷那樣簡(jiǎn)單。此實(shí)現(xiàn)不是同步的。
                     |
                     + -- LinkedList:List 接口的鏈接列表實(shí)現(xiàn)。實(shí)現(xiàn)所有可選的列表操作,并且允許所有元素(包括 null)。除了實(shí)
                     |    現(xiàn) List 接口外,LinkedList 類還為在列表的開(kāi)頭及結(jié)尾 get、remove 和 insert 元素提供了統(tǒng)一的命名方
                     |    法。這些操作允許將鏈接列表用作堆棧、隊(duì)列或雙端隊(duì)列。提供先進(jìn)先出隊(duì)列操作(FIFO)。此實(shí)現(xiàn)不是同步的。
                     |
                     + -- Vector:Vector 類可以實(shí)現(xiàn)可增長(zhǎng)的對(duì)象數(shù)組。與數(shù)組一樣,它包含可以使用整數(shù)索引進(jìn)行訪問(wèn)的組件。但是
                          ,Vector 的大小可以根據(jù)需要增大或縮小,以適應(yīng)創(chuàng)建 Vector 后進(jìn)行添加或移除項(xiàng)的操作。此實(shí)現(xiàn)是同步的
                          。

          posted @ 2007-04-18 11:18 碼農(nóng)cz 閱讀(332) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文

          posted @ 2007-03-13 16:22 碼農(nóng)cz 閱讀(948) | 評(píng)論 (0)編輯 收藏

          自從用上了tomcat5.5,發(fā)現(xiàn)日志信息沒(méi)了,出錯(cuò)了也找不著有用的信息,上apache找答案,果然

          Tomcat 5.5 uses Commons Logging throughout its internal code allowing the developer to choose a logging configuration that suits their needs, e.g java.util.logging or Log4J. Commons Logging provides Tomcat the ability to log hierarchially across various log levels without needing to rely on a particular logging implementation.

          An important consequence for Tomcat 5.5 is that the <Logger> element found in previous versions to create a localhost_log is no longer a valid nested element of <Context>. Instead, the default Tomcat configuration will use java.util.logging. If the developer wishes to collect detailed internal Tomcat logging (i.e what is happening within the Tomcat engine), then they should configure a logging system such as java.util.logging or log4j as detailed next

          習(xí)慣用log4j來(lái)配置log信息的輸出。

          新建log4j.properties,內(nèi)容為

          log4j.rootLogger=info,Console,R

          log4j.appender.Console=org.apache.log4j.ConsoleAppender
          log4j.appender.Console.layout=org.apache.log4j.PatternLayout
          #log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
          log4j.appender.Console.layout.ConversionPattern=%d{yy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n

          log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
          log4j.appender.R.File=${catalina.home}/logs/tomcat.log
          log4j.appender.R.layout=org.apache.log4j.PatternLayout
          log4j.appender.R.layout.ConversionPattern=%d{yyyy.MM.dd HH:mm:ss} %5p %c{1}(%L):? %m%n

          log4j.logger.org.apache=info, R
          log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG, R
          log4j.logger.org.apache.catalina.core=info, R
          log4j.logger.org.apache.catalina.session=info, R

          最后四行是tomcat的信息,如果改為debug日志文件將十分龐大。

          將這個(gè)文件放入${catalina.home}/common/classes下,再將log4j.jar和commons-logging.jar放入${catalina.home}/common/lib下,就可以在${catalina.home}/logs/下見(jiàn)到日志了。

          posted @ 2007-01-09 18:42 碼農(nóng)cz 閱讀(1405) | 評(píng)論 (0)編輯 收藏

          我在做項(xiàng)目時(shí)曾碰到這個(gè)問(wèn)題,怎樣動(dòng)態(tài)地添加一個(gè)文本框或文件域,這在網(wǎng)上很容易找到。但對(duì)怎樣處理提交的動(dòng)態(tài)數(shù)據(jù)就很少有這方面的信息了。本人翻閱了一些資料,把自己的方法寫了下來(lái),以饗讀者。

          1.提交表單

          ?

          <html>
          <body>
          ?<form?name
          = " form " ?method = " post " ?action = " add.jsp " >
          ???<input?name
          = " button " ?type = button?onClick = 'additem( " tb " )'?value = " 添加>> " >
          ?<table?id
          = " tb " >
          ?</table>
          <script?language
          = " javascript " >

          function?additem(id)
          {
          ??var?row
          , cell , str ;
          ??row? = ?eval( " document.all[ " +' " '+id+' " '+ " ] " ).insertRow() ;
          ??if(row?! = ?null?)
          ?????{
          ????????cell?
          = ?row.insertCell() ;
          ????????str = " <input?type= " +' " '+ " text " +' " '+ " ?name= " +' " '+ " StuName " +' " '+ " ><input?type= " +' " '+ " button " +' " '+ " ?value= " +' " '+ " 刪除 " +' " '+ " ?onclick='deleteitem(this, " +' " '+ " tb " +' " '+ " );'> "
          ???cell.innerHTML
          = str ;

          ??????}
          }
          function?deleteitem(obj
          , id)
          {
          ??var?rowNum
          , curRow ;
          ??curRow? = ?obj.parentNode.parentNode ;
          ??rowNum? = ?eval( " document.all. " +id).rows.length?-? 1 ;
          ??eval( " document.all[ " +' " '+id+' " '+ " ] " ).deleteRow(curRow.rowIndex) ;
          }
          </script>
          ???<p>
          ?????<input?type
          = " submit " ?name = " submit " ?value = " 提交 " >
          ???</p>
          ?</form>
          </body>
          </html>

          ?

          2.處理數(shù)據(jù)

          < body >
          < table? border ="1" >< tr >< td? colspan ="2" > eg </ td ></ tr >
          <%
          Enumeration?params
          = request.getParameterNames();
          while (params.hasMoreElements()){
          String ?name = ( String )params.nextElement();
          String []?values = request.getParameterValues(name);
          if (name.equals( " StuName " )){
          %>
          < tr >
          < td > <% = name %> </ td >
          < td >
          <%
          for ( int ?index = 0 ;index < values.length;index ++ ){
          %>
          <% = values[index] %>
          <% }} %>
          </ td >
          </ tr >
          </ table >
          </ body >

          posted @ 2007-01-04 14:44 碼農(nóng)cz 閱讀(1429) | 評(píng)論 (1)編輯 收藏

          ?ServletfilterJ2EE開(kāi)發(fā)中常用的技術(shù),使用方便,配置簡(jiǎn)單,老少皆宜。估計(jì)大多數(shù)朋友都是直接配置用,也沒(méi)有關(guān)心過(guò)具體的細(xì)節(jié),今天遇到一個(gè)問(wèn)題,上網(wǎng)查了servlet的規(guī)范才發(fā)現(xiàn),servletfilter中的url-pattern還是有一些文章在里面的,總結(jié)了一些東西,放出來(lái)供大家參考,以免遇到問(wèn)題又要浪費(fèi)時(shí)間。

          ??? 一,servlet容器對(duì)url的匹配過(guò)程:

          ?????

          當(dāng)一個(gè)請(qǐng)求發(fā)送到servlet容器的時(shí)候,容器先會(huì)將請(qǐng)求的url減去當(dāng)前應(yīng)用上下文的路徑作為servlet的映射url,比如我訪問(wèn)的是http://localhost/test/aaa.html,我的應(yīng)用上下文是test,容器會(huì)將http://localhost/test去掉,剩下的/aaa.html部分拿來(lái)做servlet的映射匹配。這個(gè)映射匹配過(guò)程是有順序的,而且當(dāng)有一個(gè)servlet匹配成功以后,就不會(huì)去理會(huì)剩下的servlet了(filter不同,后文會(huì)提到)。其匹配規(guī)則和順序如下:

          1.???? 精確路徑匹配。例子:比如servletA url-pattern /testservletBurl-pattern/* ,這個(gè)時(shí)候,如果我訪問(wèn)的urlhttp://localhost/test,這個(gè)時(shí)候容器就會(huì)先進(jìn)行精確路徑匹配,發(fā)現(xiàn)/test正好被servletA精確匹配,那么就去調(diào)用servletA,也不會(huì)去理會(huì)其他的servlet了。

          2.???? 最長(zhǎng)路徑匹配。例子:servletAurl-pattern/test/*,而servletBurl-pattern/test/a/*,此時(shí)訪問(wèn)http://localhost/test/a時(shí),容器會(huì)選擇路徑最長(zhǎng)的servlet來(lái)匹配,也就是這里的servletB

          3.???? 擴(kuò)展匹配,如果url最后一段包含擴(kuò)展,容器將會(huì)根據(jù)擴(kuò)展選擇合適的servlet。例子:servletAurl-pattern*.action

          4.???? 如果前面三條規(guī)則都沒(méi)有找到一個(gè)servlet,容器會(huì)根據(jù)url選擇對(duì)應(yīng)的請(qǐng)求資源。如果應(yīng)用定義了一個(gè)default servlet,則容器會(huì)將請(qǐng)求丟給default servlet(什么是default servlet?后面會(huì)講)

          ???? 根據(jù)這個(gè)規(guī)則表,就能很清楚的知道servlet的匹配過(guò)程,所以定義servlet的時(shí)候也要考慮url-pattern的寫法,以免出錯(cuò)。

          ????? 對(duì)于filter,不會(huì)像servlet那樣只匹配一個(gè)servlet,因?yàn)?/span>filter的集合是一個(gè)鏈,所以只會(huì)有處理的順序不同,而不會(huì)出現(xiàn)只選擇一個(gè)filterFilter的處理順序和filter-mappingweb.xml中定義的順序相同。

          ??? 二,url-pattern詳解

          ???????? web.xml文件中,以下語(yǔ)法用于定義映射:

          l? ”/’開(kāi)頭和以”/*”結(jié)尾的是用來(lái)做路徑映射的。

          l? 以前綴”*.”開(kāi)頭的是用來(lái)做擴(kuò)展映射的。

          l? “/” 是用來(lái)定義default servlet映射的。

          l? 剩下的都是用來(lái)定義詳細(xì)映射的。比如: /aa/bb/cc.action

          所以,為什么定義”/*.action”這樣一個(gè)看起來(lái)很正常的匹配會(huì)錯(cuò)?因?yàn)檫@個(gè)匹配即屬于路徑映射,也屬于擴(kuò)展映射,導(dǎo)致容器無(wú)法判斷。

          posted @ 2006-12-18 10:45 碼農(nóng)cz 閱讀(387) | 評(píng)論 (0)編輯 收藏

          使用servlet來(lái)下載文件,其原理非常簡(jiǎn)單,只要得到文件的輸入流(或相應(yīng)字節(jié)),然后寫輸出流即可。現(xiàn)就其中的幾個(gè)細(xì)節(jié)問(wèn)題展開(kāi):
          1. MIME類型的設(shè)置:
          Web 瀏覽器使用 MIME 類型來(lái)識(shí)別非 HTML 文檔,并決定如何顯示該文檔內(nèi)的數(shù)據(jù)。
          例如EXCEL文件的 MIME 類型是 "application/vnd.ms-excel "。要用servlet 來(lái)打開(kāi)一個(gè) EXCEL 文檔,需要將 response 對(duì)象中 header 的 contentType 設(shè)置成“application/vnd.ms-excel ”。
          response.setContentType(contentType);
          2. Content disposition
          HTTP response header中的content-disposition 允許 servlet 指定文檔表示的信息。使用這種header ,你就可以將文檔指定成單獨(dú)打開(kāi)(而不是在瀏覽器中打開(kāi)),還可以根據(jù)用戶的操作來(lái)顯示。
          如果用戶要保存文檔,你還可以為該文檔建議一個(gè)文件名。這個(gè)建議名稱會(huì)出現(xiàn)在 Save As 對(duì)話框的“文件名”欄中。如果沒(méi)有指定,則對(duì)話框中就會(huì)出現(xiàn) servlet 的名字。
          servlet 中,將 header 設(shè)置成下面這樣:
          response.setHeader("Content-disposition","attachment;filename="+ "Example.xls" );

          response.setHeader("Content-Disposition", "inline; filename="fliename)
          點(diǎn)擊打開(kāi)會(huì)在ie中打開(kāi)。

          需要說(shuō)明的有三點(diǎn):
          ? 中文文件名需要進(jìn)行iso8859-1轉(zhuǎn)碼方可正確顯示:
          fileName = new String(fileName.getBytes("GBK"),"iso8859-1");
          ? 傳遞的文件名,需要包含后綴名(如果此文件有后綴名),否則丟失文件的屬性,而不能自行選擇相關(guān)程序打開(kāi)。
          ? 有下載前詢問(wèn)(是打開(kāi)文件還是保存到計(jì)算機(jī))和通過(guò)IE瀏覽器直接選擇相關(guān)應(yīng)用程序插件打開(kāi)兩種方式,前者如上代碼所示,后者如下:
          response.setHeader("Content-disposition","filename="+ "Example.xls" );
          3. 在研究文件的上傳及下載過(guò)程中,有幾點(diǎn)體會(huì)
          程序的I/O操作往往是性能的瓶頸所在,java io定義了兩個(gè)基本的抽象類:InputStream和OutputStream,對(duì)于不同的數(shù)據(jù)類型比如磁盤,網(wǎng)絡(luò)又提供了不同的實(shí)現(xiàn),java.io也提供了一些緩沖流(BufferedStream),使硬盤可以很快的讀寫一大塊的數(shù)據(jù), 而Java基本的I/O類一次只能讀寫一個(gè)字節(jié),但緩沖流(BufferedStream)可以一次讀寫一批數(shù)據(jù),,緩沖流(Buffered Stream)大大提高了I/O的性能。所以:
          ?小塊小塊的讀寫數(shù)據(jù)會(huì)非常慢,因此,盡量大塊的讀寫數(shù)據(jù)
          ?使用BufferedInputStream和BufferedOutputStream來(lái)批處理數(shù)據(jù)以提高性能
          ?對(duì)象的序列化(serialization)非常影響I/O的性能,盡量少用

          posted @ 2006-12-18 10:41 碼農(nóng)cz 閱讀(199) | 評(píng)論 (0)編輯 收藏

          希望對(duì)剛開(kāi)始學(xué)Hibernate的同學(xué)有所幫助

          一、saveorUpdate與unsaved-value
          到底是sava還是update
          Hibernate需要判斷被操作的對(duì)象究竟是一個(gè)已經(jīng)持久化過(guò)的持久對(duì)象還是臨時(shí)對(duì)象。
          1).主鍵Hibernate的id generator產(chǎn)生
          <id name="id" type="java.lang.Long">
          <column name="ID" precision="22" scale="0" />
          <generator class="increment" />
          </id>

          Project project = new Project();
          project.setId(XXX);
          this.projectDao.saveOrUpdate(project);

          1、默認(rèn)unsaved-value="null"
          主鍵是對(duì)象類型,hebernate判斷project的主鍵是否位null,來(lái)判斷project是否已被持久化
          是的話,對(duì)project對(duì)象發(fā)送save(project),
          若自己設(shè)置了主鍵則直接生成update的sql,發(fā)送update(project),即便數(shù)據(jù)庫(kù)里沒(méi)有那條記錄。
          主鍵是基本類型如int/long/double/
          自己設(shè)置unsaved-null="0"。
          所以這樣的話save和update操作肯定不會(huì)報(bào)錯(cuò)。

          2、unsaved-value="none",
          由于不論主鍵屬性為任何值,都不可能為none,因此Hibernate總是對(duì)project對(duì)象發(fā)送update(project)

          3、unsaved-value="any"
          由于不論主鍵屬性為任何值,都肯定為any,因此Hibernate總是對(duì)project對(duì)象發(fā)送save(project),hibernate生成主鍵。

          Hibernate文檔中寫到
          saveOrUpdate()完成了如下工作:
          如果對(duì)象已經(jīng)在這個(gè)session中持久化過(guò)了,什么都不用做
          如果對(duì)象沒(méi)有標(biāo)識(shí)值,調(diào)用save()來(lái)保存它
          如果對(duì)象的標(biāo)識(shí)值與unsaved-value中的條件匹配,調(diào)用save()來(lái)保存它
          如果對(duì)象使用了版本(version或timestamp),那么除非設(shè)置unsaved-value="undefined",版本檢查會(huì)發(fā)生在標(biāo)識(shí)符檢查之前.
          如果這個(gè)session中有另外一個(gè)對(duì)象具有同樣的標(biāo)識(shí)符,拋出一個(gè)異常

          2).主鍵由自己來(lái)賦值
          <id name="id" type="java.lang.Long">
          <column name="ID" precision="22" scale="0" />
          <generator class="assigned" />
          </id>

          Project project = new Project();
          project.setId(XXX);
          this.projectDao.saveOrUpdate(project);

          1、默認(rèn)unsaved-value="null"
          這時(shí)有所不同,hibernate會(huì)根據(jù)主鍵產(chǎn)生一個(gè)select,來(lái)判斷此對(duì)象是否已被持久化
          已被持久化則update,未被持久化則save。
          2、unsaved-value="none",update對(duì)象,同上

          3、unsaved-value="any" ,save對(duì)象,
          如果自己自己設(shè)置的ID在數(shù)據(jù)庫(kù)中已存在,則報(bào)錯(cuò)。

          二、save與update操作
          顯式的使用session.save()或者session.update()操作一個(gè)對(duì)象的時(shí)候,實(shí)際上是用不到unsaved-value的
          在同一Session,save沒(méi)什么可說(shuō)得
          update對(duì)象時(shí), 最直接的更改一個(gè)對(duì)象的方法就是load()它,保持Session打開(kāi),然后直接修改即可:
          Session s =…
          Project p = (Project) sess.load(Project.class, id) );
          p.setName(“test”);
          s.flush();
          不用調(diào)用s.update(p);hibernate能察覺(jué)到它的變化,會(huì)自動(dòng)更新。當(dāng)然顯示調(diào)用的話也不會(huì)錯(cuò)

          Hibernate文檔中寫到
          update()方法在下列情形下使用:
          程序在前面的session中裝載了對(duì)象
          對(duì)象被傳遞到UI(界面)層
          對(duì)該對(duì)象進(jìn)行了一些修改
          對(duì)象被傳遞回業(yè)務(wù)層
          應(yīng)用程序在第二個(gè)session中調(diào)用update()保存修改

          三、delete操作
          刪除時(shí)直接自己構(gòu)造一個(gè)project即可刪除
          this.projectDao.delete(preojct);

          以前刪除我是這樣寫的
          public void deleteProject(String id) {
          Project project = (Project) this.projectDao.get(Project.class, id);
          if (project != null) {
          this.projectDao.delete(project);
          }
          即這樣也是可以的
          Project project = new Project();
          project.setId(id);
          this.projectDao.delete(project).

          如果有級(jí)聯(lián)關(guān)系,需要把級(jí)聯(lián)的子類也構(gòu)造出來(lái)add進(jìn)去,同樣可以刪除。

          好了,羅嗦的夠多了。

          posted @ 2006-12-18 10:40 碼農(nóng)cz 閱讀(507) | 評(píng)論 (0)編輯 收藏

          1、遍歷workbook

          代碼
          1. //?load源文件 ??
          2. POIFSFileSystem?fs?=? new ?POIFSFileSystem( new ?FileInputStream(filePath)); ??
          3. HSSFWorkbook?wb?=? new ?HSSFWorkbook(fs); ??
          4. for ?( int ?i?=? 0 ;?i?<?wb.getNumberOfSheets();?i++)?{ ??
          5. ????HSSFSheet?sheet?=?wb.getSheetAt(i); ??
          6. ???? for ?( int ?i?=?sheet.getFirstRowNum();?i?<?sheet.getLastRowNum();?i?++)?{ ??
          7. ????HSSFRow?row?=?sheet.getRow(i); ??
          8. ???????????? if ?(row?!=? null )?{ ??
          9. ????????。。。操作} ??
          10. ???????} ??
          11. ?????} ??
          12. //?目標(biāo)文件 ??
          13. FileOutputStream?fos?=? new ?FileOutputStream(objectPath); ??
          14. //寫文件 ??
          15. swb.write(fos); ??
          16. fos.close();??

          2、得到列和單元格

          代碼
          1. HSSFRow?row?=?sheet.getRow(i); ??
          2. HSSFCell?cell?=?row.getCell(( short )?j);??

          3、設(shè)置sheet名稱和單元格內(nèi)容為中文

          代碼
          1. wb.setSheetName(n,? "中文" ,HSSFCell.ENCODING_UTF_16);???? ??
          2. cell.setEncoding(( short )? 1 ); ??
          3. cell.setCellValue( "中文" );??

          4、單元格內(nèi)容未公式或數(shù)值,可以這樣讀寫

          代碼
          1. cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); ??
          2. cell.getNumericCellValue()??


          5、設(shè)置列寬、行高

          代碼
          1. sheet.setColumnWidth(( short )column,( short )width); ??
          2. row.setHeight(( short )height);??


          6、添加區(qū)域,合并單元格

          代碼
          1. Region?region?=? new ?Region(( short )rowFrom,( short )columnFrom,( short )rowTo,( short )columnTo); ??
          2. sheet.addMergedRegion(region); ??
          3. //得到所有區(qū)域 ??
          4. sheet.getNumMergedRegions()??

          7、常用方法
          根據(jù)單元格不同屬性返回字符串?dāng)?shù)值

          代碼
          1. public ?String?getCellStringValue(HSSFCell?cell)?{ ??
          2. ????????String?cellValue?=? "" ; ??
          3. ???????? switch ?(cell.getCellType())?{ ??
          4. ???????? case ?HSSFCell.CELL_TYPE_STRING: ??
          5. ????????????cellValue?=?cell.getStringCellValue(); ??
          6. ???????????? if (cellValue.trim().equals( "" )||cellValue.trim().length()<= 0 ) ??
          7. ????????????????cellValue= "?" ; ??
          8. ???????????? break ; ??
          9. ???????? case ?HSSFCell.CELL_TYPE_NUMERIC: ??
          10. ????????????cellValue?=?String.valueOf(cell.getNumericCellValue()); ??
          11. ???????????? break ; ??
          12. ???????? case ?HSSFCell.CELL_TYPE_FORMULA: ??
          13. ????????????cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); ??
          14. ????????????cellValue?=?String.valueOf(cell.getNumericCellValue()); ??
          15. ???????????? break ; ??
          16. ???????? case ?HSSFCell.CELL_TYPE_BLANK: ??
          17. ????????????cellValue= "?" ; ??
          18. ???????????? break ; ??
          19. ???????? case ?HSSFCell.CELL_TYPE_BOOLEAN: ??
          20. ???????????? break ; ??
          21. ???????? case ?HSSFCell.CELL_TYPE_ERROR: ??
          22. ???????????? break ; ??
          23. ???????? default : ??
          24. ???????????? break ; ??
          25. ????????} ??
          26. ???????? return ?cellValue; ??
          27. ????}??


          8、常用單元格邊框格式

          虛線HSSFCellStyle.BORDER_DOTTED
          實(shí)線HSSFCellStyle.BORDER_THIN

          代碼
          1. public ? static ?HSSFCellStyle?getCellStyle( short ?type) ??
          2. ????{??? ??
          3. ???????HSSFWorkbook?wb?=? new ?HSSFWorkbook(); ??
          4. ???????HSSFCellStyle?style?=?wb.createCellStyle(); ??
          5. ???????style.setBorderBottom(type); //下邊框? ??
          6. ????????style.setBorderLeft(type); //左邊框? ??
          7. ????????style.setBorderRight(type); //右邊框? ??
          8. ????????style.setBorderTop(type); //上邊框? ??
          9. ??????? return ?style; ??
          10. ????}??


          9、設(shè)置字體和內(nèi)容位置

          代碼
          1. HSSFFont?f??=?wb.createFont(); ??
          2. f.setFontHeightInPoints(( short )? 11 ); //字號(hào) ??
          3. f.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); //加粗 ??
          4. style.setFont(f); ??
          5. style.setAlignment(HSSFCellStyle.ALIGN_CENTER); //左右居中 ??
          6. style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //上下居中 ??
          7. style.setRotation( short ?rotation); //單元格內(nèi)容的旋轉(zhuǎn)的角度 ??
          8. HSSFDataFormat?df?=?wb.createDataFormat(); ??
          9. style1.setDataFormat(df.getFormat( "0.00%" )); //設(shè)置單元格數(shù)據(jù)格式 ??
          10. cell.setCellFormula(string); //給單元格設(shè)公式 ??
          11. style.setRotation( short ?rotation); //單元格內(nèi)容的旋轉(zhuǎn)的角度 ??
          12. cell.setCellStyle(style); ??


          10、插入圖片

          論壇里看到的
          代碼
          1. //先把讀進(jìn)來(lái)的圖片放到一個(gè)ByteArrayOutputStream中,以便產(chǎn)生ByteArray ??
          2. ??????ByteArrayOutputStream?byteArrayOut?=?new?ByteArrayOutputStream(); ??
          3. ??????BufferedImage?bufferImg?=?ImageIO.read(new?File("ok.jpg")); ??
          4. ??????ImageIO.write(bufferImg,"jpg",byteArrayOut); ??
          5. //讀進(jìn)一個(gè)excel模版 ??
          6. FileInputStream?fos?=?new?FileInputStream(filePathName+"/stencil.xlt");? ??
          7. fs?=?new?POIFSFileSystem(fos); ??
          8. //創(chuàng)建一個(gè)工作薄 ??
          9. HSSFWorkbook?wb?=?new?HSSFWorkbook(fs); ??
          10. HSSFSheet?sheet?=?wb.getSheetAt(0); ??
          11. HSSFPatriarch?patriarch?=?sheet.createDrawingPatriarch(); ??
          12. HSSFClientAnchor?anchor?=?new?HSSFClientAnchor(0,0,1023,255,(short)?0,0,(short)10,10);????? ??
          13. patriarch.createPicture(anchor?,?wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));??

          最后更新:2006-10-30 20:12

          posted @ 2006-12-18 10:36 碼農(nóng)cz 閱讀(612) | 評(píng)論 (0)編輯 收藏

          一.POI簡(jiǎn)介

          Jakarta POI 是apache的子項(xiàng)目,目標(biāo)是處理ole2對(duì)象。它提供了一組操縱Windows文檔的Java API

          目前比較成熟的是HSSF接口,處理MS Excel(97-2002)對(duì)象。它不象我們僅僅是用csv生成的沒(méi)有格式的可以由Excel轉(zhuǎn)換的東西,而是真正的Excel對(duì)象,你可以控制一些屬性如sheet,cell等等。

          二.HSSF概況

          HSSF 是Horrible SpreadSheet Format的縮寫,也即“討厭的電子表格格式”。也許HSSF的名字有點(diǎn)滑稽,就本質(zhì)而言它是一個(gè)非常嚴(yán)肅、正規(guī)的API。通過(guò)HSSF,你可以用純Java代碼來(lái)讀取、寫入、修改Excel文件。

          HSSF 為讀取操作提供了兩類API:usermodel和eventusermodel,即“用戶模型”和“事件-用戶模型”。前者很好理解,后者比較抽象,但操作效率要高得多。

          三.開(kāi)始編碼

          1 . 準(zhǔn)備工作

          要求:JDK 1.4+POI開(kāi)發(fā)包

          可以到 http://www.apache.org/dyn/closer.cgi/jakarta/poi/ 最新的POI工具包

          2 . EXCEL 結(jié)構(gòu)

          HSSFWorkbook excell 文檔對(duì)象介紹
          HSSFSheet excell的表單
          HSSFRow excell的行
          HSSFCell excell的格子單元
          HSSFFont excell字體
          HSSFName 名稱
          HSSFDataFormat 日期格式
          在poi1.7中才有以下2項(xiàng):
          HSSFHeader sheet頭
          HSSFFooter sheet尾
          和這個(gè)樣式
          HSSFCellStyle cell樣式
          輔助操作包括
          HSSFDateUtil 日期
          HSSFPrintSetup 打印
          HSSFErrorConstants 錯(cuò)誤信息表

          3 .具體用法實(shí)例 (采用 usermodel )

          如何讀Excel

          讀取Excel文件時(shí),首先生成一個(gè)POIFSFileSystem對(duì)象,由POIFSFileSystem對(duì)象構(gòu)造一個(gè)HSSFWorkbook,該HSSFWorkbook對(duì)象就代表了Excel文檔。下面代碼讀取上面生成的Excel文件寫入的消息字串:
          try{
          ?? POIFSFileSystem fs=new POIFSFileSystem(new FileInputStream("d:/workbook.xls"));
          ?? HSSFWorkbook wb = new HSSFWorkbook(fs);
          ?? HSSFSheet sheet = wb.getSheetAt(0);
          ?? HSSFRow row = sheet.getRow(0);
          ?? HSSFCell cell = row.getCell((short) 0);
          ?? String msg = cell.getStringCellValue();
          ?? System.out.println(msg);
          ? }catch(Exception e){
          ?? e.printStackTrace();
          ? }

          如何寫excel,

          將excel的第一個(gè)表單第一行的第一個(gè)單元格的值寫成“a test”。

          POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream("workbook.xls"));

          ??? HSSFWorkbook wb = new HSSFWorkbook(fs);

          ??? HSSFSheet sheet = wb.getSheetAt(0);

          ??? HSSFRow row = sheet.getRow(0);

          ??? HSSFCell cell = row.getCell((short)0);

          ??? cell.setCellValue("a test");

          ??? // Write the output to a file

          ??? FileOutputStream fileOut = new FileOutputStream("workbook.xls");

          ??? wb.write(fileOut);

          fileOut.close();

          4 . 可參考文檔

          POI 主頁(yè): http://jakarta.apache.org/poi/

          初學(xué)者如何快速上手使用POI HSSF

          http://jakarta.apache.org/poi/hssf/quick-guide.html

          里面有很多例子代碼,可以很方便上手。

          四.使用心得

          POI HSSF 的usermodel包把Excel文件映射成我們熟悉的結(jié)構(gòu),諸如Workbook、Sheet、Row、Cell等,它把整個(gè)結(jié)構(gòu)以一組對(duì)象的形式保存在內(nèi)存之中,便于理解,操作方便,基本上能夠滿足我們的要求,所以說(shuō)這個(gè)一個(gè)不錯(cuò)的選擇。

          -------------------------------
          前面已經(jīng)講過(guò)利用POI讀寫Excel,下面是一個(gè)用POI向Excel中插入圖片的例子。

          官方文檔:
          Images are part of the drawing support. To add an image just call createPicture() on the drawing patriarch. At the time of writing the following types are supported:
          PNG
          JPG
          DIB
          It is not currently possible to read existing images and it should be noted that any existing drawings may be erased once you add a image to a sheet.

          // Create the drawing patriarch. This is the top level container for
          // all shapes. This will clear out any existing shapes for that sheet.


          通過(guò)HSSFPatriarch類createPicture方法的在指定的wb中的sheet創(chuàng)建圖片,它接受二個(gè)參數(shù),第一個(gè)是HSSFClientAnchor,設(shè)定圖片的大小。

          ?1 package ?com.poi.hssf.test;
          ?2
          ?3 import ?java.io.FileOutputStream;
          ?4 import ?java.io.File;
          ?5 import ?java.io.ByteArrayOutputStream;
          ?6 import ?java.io.IOException;
          ?7
          ?8 import ?java.awt.image.BufferedImage;
          ?9 import ?javax.imageio. * ;
          10
          11 import ?org.apache.poi.hssf.usermodel.HSSFWorkbook;
          12 import ?org.apache.poi.hssf.usermodel.HSSFSheet;
          13 import ?org.apache.poi.hssf.usermodel.HSSFPatriarch;
          14 import ?org.apache.poi.hssf.usermodel.HSSFClientAnchor;;
          15
          16 public ? class ?TestPOI? {
          17
          18 ???? public ? static ? void ?main(String[]?args)? {
          19 ????????????FileOutputStream?fileOut? = ? null ;
          20 ????????????BufferedImage?bufferImg? = null ;
          21 ????????????BufferedImage?bufferImg1? = ? null ;
          22 ???????????? try {
          23 ????????????????
          24 ?????????? // 先把讀進(jìn)來(lái)的圖片放到一個(gè)ByteArrayOutputStream中,以便產(chǎn)生ByteArray
          25 ??????????ByteArrayOutputStream?byteArrayOut? = ? new ?ByteArrayOutputStream();
          26 ??????????ByteArrayOutputStream?byteArrayOut1? = ? new ?ByteArrayOutputStream();
          27 ??????????bufferImg? = ?ImageIO.read( new ?File( " d:/PieChart.jpg " ));
          28 ??????????bufferImg1? = ?ImageIO.read( new ?File( " d:/fruitBarChart.jpg " ));
          29 ??????????ImageIO.write(bufferImg, " jpg " ,byteArrayOut);
          30 ??????????ImageIO.write(bufferImg1, " jpg " ,byteArrayOut1);
          31 ??????????
          32 ???????? // 創(chuàng)建一個(gè)工作薄
          33 ????????HSSFWorkbook?wb? = ? new ?HSSFWorkbook();
          34 ????????HSSFSheet?sheet1? = ?wb.createSheet( " new?sheet " );
          35 ???????? // HSSFRow?row?=?sheet1.createRow(2);
          36 ????????HSSFPatriarch?patriarch? = ?sheet1.createDrawingPatriarch();
          37 ????????HSSFClientAnchor?anchor? = ? new ?HSSFClientAnchor( 0 , 0 , 512 , 255 ,( short )? 1 , 1 ,( short ) 10 , 20 );
          38 ????????HSSFClientAnchor?anchor1? = ? new ?HSSFClientAnchor( 0 , 0 , 512 , 255 ,( short )? 2 , 30 ,( short ) 10 , 60 );
          39 ????????anchor1.setAnchorType( 2 );
          40 ???????? // 插入圖片
          41 ????????patriarch.createPicture(anchor?,?wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));
          42 ????????patriarch.createPicture(anchor1?,?wb.addPicture(byteArrayOut1.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));
          43 ????????
          44 ????????????fileOut? = ? new ?FileOutputStream( " d:/workbook.xls " );
          45 ???????????? // 寫入excel文件
          46 ????????????wb.write(fileOut);
          47 ????????????fileOut.close();
          48 ????????
          49 ????????????}
          catch (IOException?io) {
          50 ????????????????????io.printStackTrace();
          51 ????????????????????System.out.println( " io?erorr?:?? " + ?io.getMessage());
          52 ????????????}
          ? finally
          53 ???????????? {
          54 ???????????????? if ?(fileOut? != ? null )
          55 ???????????????? {
          56 ???????????????????????????
          57 ???????????????????? try ? {
          58 ??????????????????????????????fileOut.close();
          59 ?????????????????????????}

          60 ???????????????????? catch ?(IOException?e)
          61 ???????????????????? {
          62 ???????????????????????????? // ?TODO?Auto-generated?catch?block
          63 ????????????????????????????e.printStackTrace();
          64 ?????????????????????}

          65 ????????????????}

          66 ????????????}

          67 ????}

          68 }

          posted @ 2006-12-18 10:35 碼農(nóng)cz 閱讀(1868) | 評(píng)論 (2)編輯 收藏

          目前整個(gè)開(kāi)發(fā)社區(qū)對(duì)AOP(Aspect Oriented Programing)推崇備至,也涌現(xiàn)出大量支持AOP的優(yōu)秀Framework,--Spring, JAC, Jboss AOP 等等。AOP似乎一時(shí)之間成了潮流。Java初學(xué)者不禁要發(fā)出感慨,OOP還沒(méi)有學(xué)通呢,又來(lái)AOP。本文不是要在理論上具體闡述何為AOP, 為何要進(jìn)行AOP . 要詳細(xì)了解學(xué)習(xí)AOP可以到它老家http://aosd.net去瞧瞧。這里只是意圖通過(guò)一個(gè)簡(jiǎn)單的例子向初學(xué)者展示一下如何來(lái)進(jìn)行AOP.

            為了簡(jiǎn)單起見(jiàn),例子沒(méi)有沒(méi)有使用任何第三方的AOP Framework, 而是利用Java語(yǔ)言本身自帶的動(dòng)態(tài)代理功能來(lái)實(shí)現(xiàn)AOP.

            讓我們先回到AOP本身,AOP主要應(yīng)用于日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理等方面。它的主要意圖就要將日志記錄,性能統(tǒng)計(jì),安全控制等等代碼從商業(yè)邏輯代碼中清楚的劃分出來(lái),我們可以把這些行為一個(gè)一個(gè)單獨(dú)看作系統(tǒng)所要解決的問(wèn)題,就是所謂的面向問(wèn)題的編程(不知將AOP譯作面向問(wèn)題的編程是否欠妥)。通過(guò)對(duì)這些行為的分離,我們希望可以將它們獨(dú)立地配置到商業(yè)方法中,而要改變這些行為也不需要影響到商業(yè)方法代碼。

            假設(shè)系統(tǒng)由一系列的BusinessObject所完成業(yè)務(wù)邏輯功能,系統(tǒng)要求在每一次業(yè)務(wù)邏輯處理時(shí)要做日志記錄。這里我們略去具體的業(yè)務(wù)邏輯代碼。

          public interface BusinessInterface {
           public void processBusiness();
          }

          public class BusinessObject implements BusinessInterface {
           private Logger logger = Logger.getLogger(this.getClass().getName());
           public void processBusiness(){
            try {
             logger.info("start to processing...");
             //business logic here.
             System.out.println(“here is business logic”);
             logger.info("end processing...");
            } catch (Exception e){
             logger.info("exception happends...");
             //exception handling
            }
           }
          }
            這里處理商業(yè)邏輯的代碼和日志記錄代碼混合在一起,這給日后的維護(hù)帶來(lái)一定的困難,并且也會(huì)造成大量的代碼重復(fù)。完全相同的log代碼將出現(xiàn)在系統(tǒng)的每一個(gè)BusinessObject中。

            按照AOP的思想,我們應(yīng)該把日志記錄代碼分離出來(lái)。要將這些代碼分離就涉及到一個(gè)問(wèn)題,我們必須知道商業(yè)邏輯代碼何時(shí)被調(diào)用,這樣我們好插入日志記錄代碼。一般來(lái)說(shuō)要截獲一個(gè)方法,我們可以采用回調(diào)方法或者動(dòng)態(tài)代理。動(dòng)態(tài)代理一般要更加靈活一些,目前多數(shù)的AOP Framework也大都采用了動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)。這里我們也采用動(dòng)態(tài)代理作為例子。

            JDK1.2以后提供了動(dòng)態(tài)代理的支持,程序員通過(guò)實(shí)現(xiàn)java.lang.reflect.InvocationHandler接口提供一個(gè)執(zhí)行處理器,然后通過(guò)java.lang.reflect.Proxy得到一個(gè)代理對(duì)象,通過(guò)這個(gè)代理對(duì)象來(lái)執(zhí)行商業(yè)方法,在商業(yè)方法被調(diào)用的同時(shí),執(zhí)行處理器會(huì)被自動(dòng)調(diào)用。

            有了JDK的這種支持,我們所要做的僅僅是提供一個(gè)日志處理器。

          public class LogHandler implements InvocationHandler {

           private Logger logger = Logger.getLogger(this.getClass().getName());
            private Object delegate;
            public LogHandler(Object delegate){
             this.delegate = delegate;
            }

           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object o = null;
            try {
             logger.info("method stats..." + method);
             o = method.invoke(delegate,args);
             logger.info("method ends..." + method);
            } catch (Exception e){
             logger.info("Exception happends...");
             //excetpion handling.
            }
            return o;
           }
          }
            現(xiàn)在我們可以把BusinessObject里面的所有日志處理代碼全部去掉了。

          public class BusinessObject implements BusinessInterface {

           private Logger logger = Logger.getLogger(this.getClass().getName());
           public void processBusiness(){
            //business processing
            System.out.println(“here is business logic”);
           }
          }
            客戶端調(diào)用商業(yè)方法的代碼如下:

          BusinessInterface businessImp = new BusinessObject();

          InvocationHandler handler = new LogHandler(businessImp);

          BusinessInterface proxy = (BusinessInterface) Proxy.newProxyInstance(
           businessImp.getClass().getClassLoader(),
           businessImp.getClass().getInterfaces(),
           handler);

          proxy.processBusiness();
            程序輸出如下:

          INFO: method stats...
          here is business logic
          INFO: method ends...
            至此我們的第一次小嘗試算是完成了。可以看到,采用AOP之后,日志記錄和業(yè)務(wù)邏輯代碼完全分開(kāi)了,以后要改變?nèi)罩居涗浀脑捴恍枰薷娜罩居涗浱幚砥骶托辛耍鴺I(yè)務(wù)對(duì)象本身(BusinessObject)無(wú)需做任何修改。并且這個(gè)日志記錄不會(huì)造成重復(fù)代碼了,所有的商業(yè)處理對(duì)象都可以重用這個(gè)日志處理器。

            當(dāng)然在實(shí)際應(yīng)用中,這個(gè)例子就顯得太粗糙了。由于JDK的動(dòng)態(tài)代理并沒(méi)有直接支持一次注冊(cè)多個(gè)InvocationHandler,那么我們對(duì)業(yè)務(wù)處理方法既要日志記錄又要性能統(tǒng)計(jì)時(shí),就需要自己做一些變通了。一般我們可以自己定義一個(gè)Handler接口,然后維護(hù)一個(gè)隊(duì)列存放所有Handler, 當(dāng)InvocationHandler被觸發(fā)的時(shí)候我們依次調(diào)用自己的Handler。所幸的是目前幾乎所有的AOP Framework都對(duì)這方面提供了很好的支持.這里推薦大家使用Spring。

          posted @ 2006-12-13 11:43 碼農(nóng)cz 閱讀(225) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 定安县| 江永县| 上栗县| 襄汾县| 绥江县| 博野县| 高安市| 昭平县| 普宁市| 太和县| 调兵山市| 阿鲁科尔沁旗| 阳山县| 宁海县| 台东县| 通城县| 封开县| 正蓝旗| 云阳县| 滦平县| 临澧县| 柳河县| 平江县| 卢龙县| 双城市| 钦州市| 迁西县| 无锡市| 秭归县| 玛曲县| 兴海县| 靖边县| 通渭县| 景泰县| 中西区| 拉萨市| 云浮市| 灌南县| 台湾省| 安化县| 文水县|