2006年3月16日

          整理P大點(diǎn)兒的硬盤空間居然整理出來俺曾經(jīng)做過的幾個(gè)東東,哎呀,想當(dāng)年啊……成長(zhǎng)歷程啊。
          第一個(gè)正把經(jīng)的個(gè)人網(wǎng)站的首頁(yè)
          ?進(jìn)步了一些的第二版?zhèn)€人主頁(yè)

          又做了一些小東東而且跟著DFLYING大蝦學(xué)會(huì)PHP以后,開始接校內(nèi)的小活做……一個(gè)團(tuán)委旗下網(wǎng)站
          加入Enwell.net開始欄目制作。其中一個(gè),Enwell商城。

          成立Enwell Studio
          做的第一個(gè)商業(yè)網(wǎng)站,反而不知道咋做了
          又陸續(xù)寫了一些PHP以后,進(jìn)入Hywave多媒體開始寫Delphi和ASP.NET,為hywave改版提出兩套方案
          ASP.NET寫了一些,包括一個(gè)巨惡心的OA以后開始和差沙,范例華寫J2ME,要不是因?yàn)槠谀]時(shí)間了,俺們相信瘋狂坦克對(duì)打網(wǎng)絡(luò)版肯定能產(chǎn)出,差沙小伙兒一個(gè)星期就把是男人就下一百層從無到有寫出來了(以前從來不做JAVA何況J2ME)
          開始寫DELPHI以后俺就成了一個(gè)職業(yè)的程序員了,和頁(yè)面沒關(guān)系了……就走進(jìn)了JAVA的世界。也不知道現(xiàn)在開始寫SAP ABAP是不是對(duì)得起自己。sigh,好多東西翻不到了,都是大學(xué)逃課的心血啊……

          posted @ 2006-07-31 22:47 BlueO2 閱讀(470) | 評(píng)論 (0)編輯 收藏

          我很早以前便開始使用bloglines的訂閱服務(wù)。在那里我訂閱了很多常去的技術(shù)站點(diǎn)和一些朋友們的blog,使用總發(fā)現(xiàn)了一些不便之處也產(chǎn)生了自己的一些想法,今天偶然看keso的一篇blog發(fā)現(xiàn)了抓蝦網(wǎng)以及rojo,眼前為之一亮,很多想法,這兩個(gè)網(wǎng)站已經(jīng)替我實(shí)現(xiàn)了。
          rss訂閱服務(wù)衍生的門戶
          在bloglines這樣的純粹訂閱服務(wù)來說,用戶群的大小,用戶群訂閱的內(nèi)容的相似度,用戶的閱讀頻率對(duì)網(wǎng)站產(chǎn)生不了任何貢獻(xiàn)。這實(shí)在是大大的浪費(fèi)。我當(dāng)時(shí)就想,如果在每個(gè)種子旁邊有個(gè)方便的"頂"也就是digg it功能,那么,將用戶頂?shù)淖疃嗟膕tory聚合起來,分門別類,這就是一個(gè)dzone.com這樣的網(wǎng)站啊。現(xiàn)在類似dzone以及更加出名的digg我都認(rèn)為是rss訂閱服務(wù)網(wǎng)站的失敗之處,他們完全有優(yōu)勢(shì)快速聚合出來一個(gè)這樣的小型門戶。現(xiàn)在抓蝦網(wǎng)以及rojo都有這樣的服務(wù)了,也都由此衍生出了一個(gè)熱文排行樣式的東西,但是我感覺做得還不夠,這樣太雜。泛泛的講內(nèi)容一列。應(yīng)該根絕用戶訂閱時(shí)此feed的tag做分析,整理出來分類,做類似daqi.com或者qihoo.com一樣的布局。
          rss訂閱衍生出來的朋友圈
          web20有一點(diǎn)很重要,就是社會(huì)網(wǎng)絡(luò)。就拿豆瓣網(wǎng)來說,我通過豆瓣提供的以書會(huì)友的功能認(rèn)識(shí)了幾個(gè)志趣相投的朋友。豆瓣會(huì)根據(jù)你喜歡讀的書,看的電影,聽得音樂,推薦給你和你興趣相投的人,rss訂閱也應(yīng)該這樣。比如Bloglines可以查看都有誰訂閱了這個(gè)feed,可是為什么不更近一步,將兩個(gè)人的訂閱內(nèi)容作比較,做匹配呢?通過在你的網(wǎng)站提供的 rss訂閱服務(wù)我可以認(rèn)識(shí)朋友,這也是網(wǎng)站粘性之一。否則像我現(xiàn)在可以毫無顧忌的從bloglines搬家到rojo和抓蝦網(wǎng)。而更多自取相同的人可以組成圈子。甚至衍生更廣一點(diǎn),大家通過查看你的profile,瀏覽你的Blog,決定跟你做朋友的時(shí)候,你會(huì)得到一個(gè)vote的分?jǐn)?shù),在朋友圈的聚合門戶上排名考前,這個(gè)不就是聯(lián)絡(luò)家么?
          推薦給我其他讀物
          當(dāng)我用豆瓣的時(shí)候,還有一個(gè)功能特別貼心,就是它會(huì)推薦給我相類似的圖書。比如我讀兄弟,它會(huì)在旁邊給我推薦活著,許三關(guān)賣血等等……rss的小門戶,可以根據(jù)每個(gè)人的興趣不同,推薦在此類別中背digg次數(shù)最多的blog給我,省得我總是感慨:哎呀,怎么沒早點(diǎn)看到這個(gè)網(wǎng)站呢?
          信息篩選
          訂閱了好多rss feed的人都有此種經(jīng)歷,那就是有的時(shí)候忙,你好久沒看了,突然以上來,成百上千的新條目,當(dāng)即暈倒。貼心的篩選是很必要的,rss訂閱服務(wù)網(wǎng)站完全可以根據(jù)其他用戶的digg rank來按照重要程度給我排序,大家認(rèn)為重要的先看,大家認(rèn)為不重要的后看……我想,群眾的眼睛還是雪亮的。
          冗余的剔除
          訂閱了大量rss的人來說,有一些種子可能已經(jīng)壞掉了,或者作者更新頻率很低,或者過了一段時(shí)間以后,你已經(jīng)不太認(rèn)為那個(gè)對(duì)你有價(jià)值了(這個(gè)可以從你digg it和收藏的頻率來判斷),但是因?yàn)槲覀冞M(jìn)行了大量的訂閱,要把它剔除需要花費(fèi)時(shí)間的。RSS訂閱服務(wù)只需要替訂閱者看著點(diǎn)壞掉的種子,統(tǒng)計(jì)下訂閱者對(duì)其的關(guān)注度,然后建議剔除哪些沒有價(jià)值的feed,這將給我?guī)砭薮蟮姆奖恪?br />抓蝦與rojo相比bloglines的改進(jìn)
          rojo有一點(diǎn)很好,當(dāng)你大開一個(gè)feed的時(shí)候,他們顯示的是title,只有當(dāng)點(diǎn)擊小十字查看具體內(nèi)容,它才認(rèn)為你讀過了,下次你再打開這個(gè)種子,這個(gè)條目便不會(huì)顯示出來。之前用bloglines有的條目很多,一天可能看不完,下一次再打開就看不到了,因?yàn)槟阒暗拇蜷_被bloglines認(rèn)為是閱讀過的表現(xiàn)。而有些條目我們認(rèn)為是很有價(jià)值的,rojo和抓蝦都提供了收藏的功能。此外rojo對(duì)bloglines對(duì)feed死板的分類功能進(jìn)行了改善,替代的是tag,就是說一個(gè)feed可以屬于多個(gè)tag,你甚至可以對(duì)條目進(jìn)行tag,這樣更加有利于小門戶分門別類的聚合。
          更進(jìn)一步
          我一直感覺blog的互動(dòng)性還不夠,這個(gè)不動(dòng)不是指comment。而是無法像BBS一樣,對(duì)一個(gè)討論形成一個(gè)有主線的跟進(jìn)。大家對(duì)一些東西都有自己的看法,可是都是零敲碎打,自己說自己的,對(duì)別人的想法可能不了解。僅僅靠track back是無法串聯(lián)起來的。如果你的rss訂閱服務(wù)能夠有足夠的粘性,那么用戶基本都從你這里獲得信息,當(dāng)他要發(fā)表對(duì)某個(gè)條目的看法,讓用戶登陸他自己的 Blog,快捷的引用到自己的blog里面,而訂閱服務(wù)網(wǎng)站將通過某種方式將用戶的評(píng)論內(nèi)容得到。這樣,將眾多的用戶的內(nèi)容整理出來,類似BBS討論的形式,聚合在門戶里。這樣,Blog之間才形成了有效的互動(dòng)??上?,這個(gè)想法,似乎還不知道怎么實(shí)現(xiàn)。
          我的頁(yè)面&&個(gè)人門戶
          幾乎這種rss訂閱服務(wù)網(wǎng)站都提供我收藏的feed的展示,我感覺這個(gè)是不夠的。而還應(yīng)該展示的則是跟我上面所說的有聯(lián)系的,最近digg的條目,最近收藏的條目,以及我最近評(píng)論的條目,以及我的朋友圈等等。這才形成了真正的“我的頁(yè)面”。
          用keso的話說,rss閱讀器的技術(shù)門檻很高啊。

          posted @ 2006-07-27 10:26 BlueO2 閱讀(483) | 評(píng)論 (0)編輯 收藏

          public ? class ?Artist? {
          ????
          ????String[]?others;
          ????
          /** ?Creates?a?new?instance?of?Artist? */
          ????
          public ?Artist()? {
          ????}

          ????
          public ?Artist(String?name,String??others) {
          ????????
          for (String?other?:?others) {
          ????????????System.out.println(other);
          ????????}

          ????????
          this .others? = ?others;
          ????}

          ????
          public ? void ?wildestMethod(Object??objs) {
          ????
          // this?method?will?accept?any?arguments
          ????}

          ????
          public ? static ? void ?main(String[]?args) {
          ????????Artist?artist?
          = ? new ?Artist( " You " ,? " 1 " ,? " 2 " );
          ????????artist.wildestMethod(
          1 ,? 3.5 ,? " AA " ,? new ?Artist());
          ????}

          ????
          }

          posted @ 2006-06-26 20:25 BlueO2 閱讀(392) | 評(píng)論 (0)編輯 收藏

          public ? class ?AutoBoxing? {
          ????
          ????
          /** ?Creates?a?new?instance?of?AutoBoxing? */
          ????
          public ?AutoBoxing()? {
          ????}

          ????
          public ? void ?boxingDemo() {
          ????????
          // auto?boxing
          ????????Integer?i? = ? 0 ;
          ????????
          float ?f? = ? 1.66f ;
          ????????Float?F?
          = ?f;
          ????????
          // auto?unboxing
          ????????Integer?I? = ? new ?Integer( 1 );
          ????????
          int ?i2? = ?I;
          ????????
          // null?value?test,?it?will?case?NullPointerException
          ????????Integer?I2? = ? null ;
          ????????
          int ?i3? = ?I2;
          ????}

          ????
          public ? void ?testOperator() {
          ????????Integer?i?
          = ? 1 ;
          ????????
          while ( true ) {
          ????????????i
          ++ ;
          ????????????System.out.println(
          " Counter: " + i);
          ????????????
          if (i > 5 )? break ;
          ????????}

          ????}

          ????
          public ? void ?testCompare() {
          ????????
          // it's?equal?because?-127~127?are?immutable?objects
          ????????Integer?i? = ? 1 ;
          ????????Integer?i2?
          = ? 1 ;
          ????????
          if (i? == ?i2)?System.out.println( " 1:Equal " );
          ????????
          else ?System.out.println( " 1:Not?Equal " );
          ????????
          // it's?not?equal?because?j?and?j2?are?different?objects
          ????????Integer?j? = ? 200 ;
          ????????Integer?j2?
          = 200 ;
          ????????
          if (j? == ?j2)?System.out.println( " 200:Equal " );
          ????????
          else ?System.out.println( " 200:Not?Equal " );
          ????}

          ????
          public ? void ?testControl() {
          ????????Boolean?flag?
          = ? true ;
          ????????Integer?i?
          = ? 20 ;
          ????????Integer?j?
          = ? 30 ;
          ????????
          if (flag) {
          ????????????System.out.println(
          " Boolean?affects " );
          ????????}

          ????????
          if (i < j)
          ????????????System.out.println(
          " Integer?affects " );
          ????}

          ????
          public ? void ?testMethod( double ?arg) {
          ????????System.out.println(
          " public?void?testMethod(double?arg)?is?invoked " );
          ????}

          ????
          public ? void ?testMethod(Integer?arg) {
          ????????System.out.println(
          " public?void?testMethod2(Integer?arg)?is?invoked " );
          ????}

          ????
          public ? static ? void ?main(String?args[]) {
          ????????AutoBoxing?auto?
          = ? new ?AutoBoxing();
          ????????auto.testCompare();
          ????????auto.testOperator();
          ????????auto.testControl();
          ????????
          int ?i? = ? 1 ;
          ????????
          // ?public?void?testMethod(Integer?arg)?wouldn't?be?invoked
          ????????
          // because??public?void?testMethod(double?arg)?will?be?invoked?in?JDK1.4
          ????????
          // Java?tiger?consider?the?backward?capability
          ????????auto.testMethod(i);
          ????????auto.boxingDemo();
          ????}

          ????
          }

          posted @ 2006-06-22 18:34 BlueO2 閱讀(409) | 評(píng)論 (0)編輯 收藏

          public ? enum ?User? {
          ????Admin,User,Guest,Unknown???
          }

          public ? class ?Login? {
          ????
          ????
          private ?User?user;
          ????EnumMap
          < User,String > ?userName? = ? new ?EnumMap < User,?String > (User. class );
          ????
          /** ?Creates?a?new?instance?of?Login? */
          ????
          public ?Login()? {
          ????????userName.put(User.Admin,?
          " Administrator " );
          ????????userName.put(User.User,?
          " David " );
          ????????userName.put(User.Guest,?
          " Steve " );
          ????}

          ????
          public ? boolean ?isAdmin(User?user) {
          ????????
          if (user.equals(User.Admin)) {
          ????????????
          return ? true ;
          ????????}

          ????????
          return ? false ;
          ????}

          ????
          public ? void ?printUserRole() {
          ????????User[]?users?
          = ?user.values();
          ????????
          for (User?u?:?user.values()) {
          ????????????System.out.println(u.toString());
          ????????}

          ????}

          ????
          public ? void ?isRole(User?user) {
          ????????
          switch (user) {
          ????????????
          case ?Admin:
          ????????????????System.out.println(
          " admin " );
          ????????????????
          break ;
          ????????????
          case ?User:
          ????????????????System.out.println(
          " User " );
          ????????????????
          break ;
          ????????????
          case ?Guest:
          ????????????????System.out.println(
          " Guest " );
          ????????????????
          break ;
          ????????????
          default :
          ????????????????System.out.println(
          " unknow " );
          ????????}

          ????}

          ????
          public ? static ? void ?main(String[]?args) {
          ????????Login?login?
          = ? new ?Login();
          ????????System.out.println(login.isAdmin(User.Admin));
          ????????login.printUserRole();
          ????????login.isRole(User.User);
          ????}

          ????
          }

          posted @ 2006-06-22 18:22 BlueO2 閱讀(348) | 評(píng)論 (0)編輯 收藏

               摘要: public ? class ?Generic? {???????? /**?*/ /** ?Creates?a?new?instance?of?Generic? */ ...  閱讀全文

          posted @ 2006-06-20 18:18 BlueO2 閱讀(397) | 評(píng)論 (0)編輯 收藏

          Rasmus Lerdorf, creator of the PHP langauge, has a new tutorial on his site today that looks at the creation of a "no-framework PHP MVC framework" using PHP5, the Yahoo! User Interface Library, and JSON.

          He steps through the entire process of working up the "non-framework" - the goals of the project, why to go with the MVC approach for the structure, and, of course, the code.

          That arose the PHP's own MVC Pattern discussion in PHP Community.But i have my own view.Here is my response in one of most famous PHP community:


          其实我认为由于lerdorf演示的是一个PHP AJAX应用,所以其实很难跟cid的方案有什么对比。由于AJAX应用的特殊性,lerdorf这个所谓的controller根本不需要考虑进行完了相关的操作以后View到底应该去哪里,应该转向哪里?因为直接push给客户端JSON对象就好了,完全不用操心到a.php还是b.php
          另外,虽然lerdorf说以后可能可以多个请求Include一个xxx.inc就是他的controller,但是目前的状况,即使成为MVC也是page controller,而cid想要做的是一个Front controller做请求委派,Front Controller的复杂的明显要比PC要高,考虑的问题也多。但是并不是说FC就好,asp.net不就是典型的page controller模式么?
          但是说句我的真实感受:读完之后我把它看作PHP AJAX应用示例教程更合适,lerdorf的标题起的有点大了,而且读完以后没有给我任何架构上启示性的东西??
          而且那个if(isset($_POST[''])){}在里面做相关操作,我还是认为挺简陋甚至丑陋的。如果一个挺复杂的view采用此种方式,还是不优雅。
          所以AJAX应用的controller有一部分应该放在View里面,一个页面a.html不一定非要请求到a.php,叶面里面的操作也是要有不同逻辑划分的,但是目前没有成熟的应用示例和解决方案。大家有没有自己的尝试?

          文章來源:http://blueoxygen.dflying.net/3/archive/42_lerdorfs_no-framework_php_mvc_framework.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(478) | 評(píng)論 (0)編輯 收藏

          一场精彩的CMMI论战 Here
          quoted from o6z's post:
          文档最忌讳繁琐无比,事无巨细的都要说明,如果是这样我直接去看代码好了。实际上多数人都默认文档的抽象程度比代码级别高,看文档比看代码省事。但是如果你的文档过于细节化,那么你的代码很难做到同步于文档。这将是一个巨大的威胁。很多人抱怨要看一堆没文档的代码,但是他们很少真的看到过合适的文档。实际上文档的作用应该是让阅读者快速找的代码的位置,而不是用文字说明代码的作用,那些应该是单元测试的事情。
          人员的流动带来的最大问题,实际是知识的流失。文档可以固定下一部分的知识,但是如果文档的抽象层次不够,这些知识并不能很容易的被掌握,那么这些就是无用功。



          文章來源:http://blueoxygen.dflying.net/3/archive/45_working_software_over_comprehensive_documentation.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(358) | 評(píng)論 (0)編輯 收藏

          本来还要自己写一个auto-complete,但是大多数此类功能并没有提供类似google suggest提供的键盘选择功能,auto-complete便失去了一大半的交互改善。于是前两天还特意扒了google suggest来看ac.js 发现google定是用了混淆器。虽然代码没有压缩,但是代码的回车空行和函数名字全部混乱。正在要自己写的时候发现了此中国自产的AutoAssist。Very Cool!


          AutoAssist is an auto completion web widget that written in pure JavaScript. It can help enhance the accessibility of existing website, let the users to work effective and feel comfortable. AutoAssist Javascript only and is built upon prototype and rico. Its main features are :

          * improve the User Experience
          * Don't require an Ajax experience
          * pretty managed JavaScript, easy to understand and customize
          * works well on Mozilla/FireFox, IE and Opera
          * have a nice solution for fast user typing, reduce a lot of corresponding server loading (20% - 80% *)

          autoassist.png

          The code for the screenshot is very simple :

          var foo = function() {
          var tt = new AutoAssist("t", {setRequestOptions: function() {
          var pars = "name=" + this.txtBox.value;
          return { url: "/country.php", parameters: pars };
          }});
          }
          Event.observe(window, "load", foo);

          You can find a ten minutes tutorial for AutoAssist explaining in details how to use this script to create an auto-complete list based on country data.

          By the way,script.aculo.us also has it's impelmention:http://demo.script.aculo.us/ajax/autocompleter


          文章來源:http://blueoxygen.dflying.net/3/archive/53_ajax_auto-complete_component.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(907) | 評(píng)論 (0)編輯 收藏

          See DFlying's finding:
          Yep,No Block Scope concept in JavaScript.Only the global and function Scope.You can use "var" to declare a global variable and use "var" agian to declare a homonymous variable in a function.In the function ,the second one works.But there is no Block scope.
          Check the codes below,it's a demo for "NO BLOCK SCOPE"
          function test(o) {var i = 0; // i is defined throughout functionif (typeof o == "object") {var j = 0; // j is defined everywhere, not just blockfor(var k = 0; k < 10; k++) { // k is defined everywhere, not just loopdocument.write(k);

          }document.write(k); // k is still defined: prints 10}document.write(j); // j is defined, but may not be initialized}

          But,You still need to care javascript's FUNCTION SCOPE.Also see code snippet:
          var scope = "global";

          function f( ) {alert(scope); // Displays "undefined", not "global"var scope = "local"; // Variable initialized here, but defined everywherealert(scope); // Displays "local"}f( );
          Right,thought you alert(scope) first and then define a new functin scope variable scope.However,once you define a function scope vriable,it will hide the global variable in the function body,whatever the definition order.



          文章來源:http://blueoxygen.dflying.net/3/archive/68_variables_scope_in_javascript.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(496) | 評(píng)論 (0)編輯 收藏

          Two useful liks:
          http://jibbering.com/faq/faq_notes/closures.html#clMem
          http://javascript.weblogsinc.com/2005/03/07/javascript-memory-leaks/

          文章來源:http://blueoxygen.dflying.net/3/archive/69_no_more_crap_about_ie_memeory_leak.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(292) | 評(píng)論 (0)編輯 收藏

          Venkman is a Javascript Debugger as a FireFox extenstion.It's at least powerful than IE's default script debugger(not Visual InterDev's).You can watch varaiable,set breakpoint and use "step over" "step into" "step out" "continue" buttons to debug your niffy javascript codes.
          It's ease to use.And tutorial is HERE:http://www.svendtofte.com/code/learning_venkman/index.php

          文章來源:http://blueoxygen.dflying.net/3/archive/75_ajax_tool_box---venkman.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(397) | 評(píng)論 (0)編輯 收藏

          eclipsePOJO used by Hibernate needs to implement hashCode() and equals() method.That's a kind of stuffy work and will be done many many times during development.Some IDEs support automatical generation feature such as IDEA.Eclipse famous plug-in--MyElipse also suppots but it's not free of charge.
          I think nearly all JAVAers know Apache Commons open source project.We can use Commons lib to generate hashCode() and equals() method.I wanna tell you that there is also a plugin for Eclipse called Commons4E which help you generate hasCode() and equals().
          It also can generate toString() and compareTo() method.That's a smart plugin.Enjoy it.Link



          文章來源:http://blueoxygen.dflying.net/3/archive/79_hibernate_pojos_good_assistant-commons_for_eclipse.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(442) | 評(píng)論 (0)編輯 收藏

          Hibernate and Lazy Initialization

          Hibernate object relational mapping offers both lazy and non-lazy modes of object initialization. Non-lazy initialization retrieves an object and all of its related objects at load time. This can result in hundreds if not thousands of select statements when retrieving one entity. The problem is compounded when bi-directional relationships are used, often causing entire databases to be loaded during the initial request. Of course one could tediously examine each object relationship and manually remove those most costly, but in the end, we may be losing the ease of use benefit sought in using the ORM tool.

          The obvious solution is to employ the lazy loading mechanism provided by hibernate. This initialization strategy only loads an object's one-to-many and many-to-many relationships when these fields are accessed. The scenario is practically transparent to the developer and a minimum amount of database requests are made, resulting in major performance gains. One drawback to this technique is that lazy loading requires the Hibernate session to remain open while the data object is in use. This causes a major problem when trying to abstract the persistence layer via the Data Access Object pattern. In order to fully abstract the persistence mechanism, all database logic, including opening and closing sessions, must not be performed in the application layer. Most often, this logic is concealed behind the DAO implementation classes which implement interface stubs. The quick and dirty solution is to forget the DAO pattern and include database connection logic in the application layer. This works for small applications but in large systems this can prove to be a major design flaw, hindering application extensibility.


          Being Lazy in the Web Layer

          Fortunately for us, the Spring Framework has developed an out of box web solution for using the DAO pattern in combination with Hibernate lazy loading. For anyone not familiar with using the Spring Framework in combination with Hibernate, I will not go into the details here, but I encourage you to read Hibernate Data Access with the Spring Framework. In the case of a web application, Spring comes with both the OpenSessionInViewFilter and the OpenSessionInViewInterceptor. One can use either one interchangeably as both serve the same function. The only difference between the two is the interceptor runs within the Spring container and is configured within the web application context while the Filter runs in front of Spring and is configured within the web.xml. Regardless of which one is used, they both open the hibernate session during the request binding this session to the current thread. Once bound to the thread, the open hibernate session can transparently be used within the DAO implementation classes. The session will remain open for the view allowing lazy access the database value objects. Once the view logic is complete, the hibernate session is closed either in the Filter doFilter method or the Interceptor postHandle method. Below is an example of the configuration of each component:

          Interceptor Configuration

          <beans> 
            <bean id="urlMapping"     
               class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">    
                 <property name="interceptors">
                   <list>
                        <ref bean="openSessionInViewInterceptor"/>
                   </list>
                 </property>
                 <property name="mappings">
            ...
            </bean>
            ...
            <bean name="openSessionInViewInterceptor"  
              class="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor">
                 <property name="sessionFactory"><ref bean="sessionFactory"/></property>
            </bean>
          </beans>
           

          Filter Configuration

          <web-app>
           ...      
            <filter>
              <filter-name>hibernateFilter</filter-name>
              <filter-class>
                org.springframework.orm.hibernate.support.OpenSessionInViewFilter
              </filter-class>
             </filter>
            ...      
            <filter-mapping>
              <filter-name>hibernateFilter</filter-name>
               <url-pattern>*.spring</url-pattern>
            </filter-mapping>
            ...
          </web-app>

          Implementing the Hibernate DAO's to use the open session is simple. In fact, if you are already using the Spring Framework to implement your Hibernate DAO's, most likely you will not have to change a thing. The DAO's must access Hibernate through the convenient HibernateTemplate utility, which makes database access a piece of cake. Below is an example DAO.

          Example DAO

          public class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO  {      
           
                 public Product getProduct(Integer productId) {
                        return (Product)getHibernateTemplate().load(Product.class, productId);
                 }
           
                 public Integer saveProduct(Product product) {
                        return (Integer) getHibernateTemplate().save(product);
                 }       
           
                 public void updateProduct(Product product) {
                        getHibernateTemplate().update(product);
                 }
           }

          Being Lazy in the Business Layer

          Even outside the view, the Spring Framework makes it easy to use lazy load initialization, through the AOP interceptor HibernateInterceptor. The hibernate interceptor transparently intercepts calls to any business object configured in the Spring application context, opening a hibernate session before the call, and closing the session afterward. Let's run through a quick example. Suppose we have an interface BusinessObject:

          public interface BusinessObject { 
               public void doSomethingThatInvolvesDaos(); 
          }</pre><p><font size="2">The class BusinessObjectImpl implements BusinessObject:</font></p>
          <p />
          <pre>public class BusinessObjectImpl implements BusinessObject {
              public void doSomethingThatInvolvesDaos() {
                  // lots of logic that calls
                  // DAO classes Which access 
                  // data objects lazily
              }
          }

          Through some configurations in the Spring application context, we can instruct the HibernateInterceptor to intercept calls to the BusinessObjectImpl allowing it's methods to lazily access data objects. Take a look at the fragment below:

          <beans>
              <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
                   <property name="sessionFactory">
                     <ref bean="sessionFactory"/>
                   </property>
              </bean>
              <bean id="businessObjectTarget" class="com.acompany.BusinessObjectImpl">
                 <property name="someDAO"><ref bean="someDAO"/></property>
              </bean>
              <bean id="businessObject" class="org.springframework.aop.framework.ProxyFactoryBean">
                   <property name="target"><ref bean="businessObjectTarget"/></property>
                   <property name="proxyInterfaces">
                     <value>com.acompany.BusinessObject</value>
                   </property>
                   <property name="interceptorNames">
                     <list>
                        <value>hibernateInterceptor</value>
                     </list>
                   </property>
               </bean>            
          </beans>
           
           

          When the businessObject bean is referenced, the HibernateInterceptor opens a hibernate session and passes the call onto the BusinessObjectImpl. When the BusinessObjectImpl has finished executing, the HibernateInterceptor transparently closes the session. The application code has no knowledge of any persistence logic, yet it is still able to lazily access data objects.

          Being Lazy in your Unit Tests

          Last but not least, we'll need the ability to test our lazy application from J-Unit. This is easily done by overriding the setUp and tearDown methods of the TestCase class. I prefer to keep this code in a convenient abstract TestCase class for all of my tests to extend.

          public abstract class MyLazyTestCase extends TestCase {
           
                  private SessionFactory sessionFactory;
                  private Session session;
          	
                  public void setUp() throws Exception {
          	    super.setUp();
          	    SessionFactory sessionFactory = (SessionFactory) getBean(\"sessionFactory&quot<img alt=";)" src="http://www.dflying.net/plugins/smileys/icons/default/wink_smile.gif" />;
          	    session = SessionFactoryUtils.getSession(sessionFactory, true);
          	    Session s = sessionFactory.openSession();
          	    TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));
           
                  }
           
                  protected Object getBean(String beanName) {
                      //Code to get objects from Spring application context
                  }
          	
                  public void tearDown() throws Exception {
          	    super.tearDown();
          	    SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
          	    Session s = holder.getSession(); 
          	    s.flush();
          	    TransactionSynchronizationManager.unbindResource(sessionFactory);
          	    SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);
                  }
          }


          文章來源:http://blueoxygen.dflying.net/3/archive/84_hibernate_performance_tuning.html

          posted @ 2006-03-16 11:19 BlueO2 閱讀(662) | 評(píng)論 (0)編輯 收藏

          寫了一些sample在我的Blog上面。還沒入門的朋友可以看看
          http://blueoxygen.dflying.net/3/archive/20_prototype_samples.html

          posted @ 2006-03-16 11:18 BlueO2 閱讀(282) | 評(píng)論 (0)編輯 收藏


          posts - 29, comments - 3, trackbacks - 0, articles - 0

          Copyright © BlueO2

          主站蜘蛛池模板: 吉安市| 台北县| 拉萨市| 分宜县| 乐安县| 合作市| 镇江市| 姚安县| 台南市| 鄂托克前旗| 衡山县| 蓬安县| 剑川县| 盐边县| 布拖县| 香格里拉县| 临猗县| 襄垣县| 崇仁县| 武强县| 青冈县| 巴楚县| 涟源市| 双鸭山市| 井陉县| 望奎县| 新营市| 县级市| 连城县| 嘉黎县| 松江区| 渭源县| 新巴尔虎左旗| 梁山县| 清镇市| 邳州市| 抚州市| 蓬溪县| 石屏县| 隆林| 收藏|