<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Tin's Blog

    You are coming a long way, baby~Thinking, feeling, memory...

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      128 隨筆 :: 0 文章 :: 221 評論 :: 0 Trackbacks
    內(nèi)容太亂,如果懶得看請只看粗體部分就可以了
    springside的一個特點就是manager繼承自DAO,其實這是個名字上的問題。
    Java EE一直強調(diào)分層架構(gòu),在Web部分比較典型的就是前端MVC、中間Business、后面持久化。而Manager對應(yīng)business,持久化由于實現(xiàn)替換的需求一般使用DAO模式。
    先分析一下在輕量化的Java EE下面他們存在的意義:
    1、有的人說過在Web項目中Manager和DAO是同意的,尤其是在透明ORM存在下,DAO由于往往是CRUD的實現(xiàn)場所,而Manager卻往往是薄薄的一層門面,很多人就在質(zhì)疑兩者的合并問題。可是robbin曾經(jīng)進行過一個精辟的分析,雖然兩者做的看起來差不多,可是兩者的事務(wù)屬性卻不一樣,Manager應(yīng)該有清晰的事務(wù)界限,而DAO不應(yīng)關(guān)心于此。也就是說Manager可能會將幾個DAO方法組合調(diào)用,然后封裝在一個事物中。這樣說明確了兩者的一個重要區(qū)別,我們也能體會在使用聲明事務(wù)的時候有一個分明的事務(wù)界限是很有意義的,否則就有可能把Manager中的一個事物拆分,這樣實際上就錯誤了。
    2、有些人質(zhì)疑透明ORM存在的情況下DAO存在的意義,因為透明ORM基本已經(jīng)隔離了不同數(shù)據(jù)庫的方言區(qū)別。這個也很簡單,Rod大叔分析過。透明ORM存在的情況下DAO起到了隔離透明ORM與EJB或者JDBC實現(xiàn)的作用,這幾種實現(xiàn)實際上是應(yīng)該考慮到的。
    3、還有一個問題,就是DAO是否應(yīng)該隱藏透明ORM的API。因為前面說到了DAO起到隔離實現(xiàn)的作用,似乎應(yīng)該隱藏特定API。可是某大叔也說過,完全隔離不可能,修改底層實現(xiàn)而不修改上層API也不劃算(應(yīng)該說往往費力不討好),其實就是Rod大叔的思想,我們寧可提供各種support或者template,但是不強求抽象出各種實現(xiàn)。所以DAO的實現(xiàn)即使依賴于部分Hibernate API也不是錯
    上面純屬貧嘴,知道的朋友們不要嫌棄。
    說說Springside的實現(xiàn)。
    其實,實際上Springside使用的就是經(jīng)典的GenericHibernateDAO+無Manager的實現(xiàn)。這么說在否定前面所說,不過其實這都是文字游戲:D
    首先,對于Hibernate為主的實現(xiàn)下,DAO使用Generic是很方便的。Spring的hibernate template受累于向JDK1.4兼容,所以沒有用generic,但是實際上DAO是generic的經(jīng)典應(yīng)用。在Hibernate網(wǎng)站上有過討論。現(xiàn)在Springside使用的GenericHibernateDAO已經(jīng)進化的非常先進了。
    Springside實際上有Manager,我說沒有其實是指它的Manager繼承自DAO。看似亂倫,但實際上非常合理。前面說了Manager與DAO的很大區(qū)別在于事物范疇,使用繼承后,兩者之間就可以分離,可以通過Spring的AOP將事物屬性配置在Manager上,也就解決了問題。這應(yīng)該說也是template模式的標準應(yīng)用。本來Manager就有很多方法可以通過模板實現(xiàn),而DAO和Generic就很好地解決了他們之間的模板關(guān)系。
    我們先看看具體的設(shè)計:
    以CustomerManager為例,我們看看類簽名:
    CustomerManager extends BaseHibernateDao<Customer>
    BaseHibernateDao<T> extends AbstractHibernateDao<T>
    AbstractHibernateDao<T> extends HibernateDaoSupport

    三層結(jié)構(gòu):
    第一層AbstractHibernateDao繼承自大家都熟悉的Spring的HibernateDaoSupport,這一層的主要作用是擴展Generic,這樣一方面減少了強行類型轉(zhuǎn)換的啰嗦,一方面使DoaminClass的信息通過Generic繼承透明聲明。這一層還有一個作用,就是說不管你是否使用Generic,你的應(yīng)用程序最好也在這里增加一層繼承,作用是在需要的時候你可以在這里擴展DAO模版:D
    第二層是BaseHibernateDao。這個其實是springside很自豪的一個地方,可以理解,因為這里真的花了很多的代碼,而且相當精妙。
    不賣官子,其實這里主要給DAO擴展了分頁支持,這顯然是異常重要的,大家google一下就知道分頁在Web應(yīng)用中的重要性了,基本上你看一個Java Web Framework都會看到它對自己分頁特性的支持方式介紹,或者說分頁的實現(xiàn)風格已經(jīng)是Java Web Framework實現(xiàn)優(yōu)劣的一個標準了。應(yīng)該說,springsdie的分頁實現(xiàn)來自javaeye上的一個經(jīng)典的討論,robbin等牛在里面仔細討論了用DetachedCriteria實現(xiàn)分頁查詢,后面引出bug,然后解決,希望沒看過的朋友都看看。(應(yīng)用Hibernate3的DetachedCriteria實現(xiàn)分頁查詢|http://forum.javaeye.com/viewtopic.php?t=14657&postdays=0&postorder=asc&start=0)
    springside的實現(xiàn)是集大成者,考慮到了Criteria(不僅是DetachedCriteria)、HQL、collection.size()幾種不同實現(xiàn),也考慮到了使用Criteria的時候Order造成的問題(這個在我的Blog中給DetachedCriteria擦屁股那個里面討論過)。
    第三層就是具體的Manager,它是用Generic繼承傳遞了DoaminModel的類信息。由于大部分CRUD已經(jīng)在DAO里面實現(xiàn)了,所以Manager只需要實現(xiàn)一些需要特殊實現(xiàn)的method的就可以了,簡單的應(yīng)用中Manager里面經(jīng)常是空空如也。

    其中,BaseHibernateDao的實現(xiàn)相對復雜,主要因為里面包裝了分頁實現(xiàn)。大家可以具體看看CriteriaPage和HqlPage兩個類,這是精妙所在。但是在這一層還有個CriteriaSetup是個比較奇怪的東西,一開始沒太看明白是做什么用的。后來問了百衣,他說這是為了解決search問題提供的,從jsp傳遞過來的東西在Controller層可以通過util(這里springside很CoC,它把search_開頭的東西自動作為“=”的查詢條件傳給Manager,但目前的缺陷在于只能默認處理“=”,其它方式需要擴展)處理查詢條件傳給Manager,但是這個東西設(shè)計得有點怪,白衣也對它不滿意,說在Springside 2.0里面要重構(gòu)掉,但還沒有什么好的想法,大家又建議可以提給他。
    我認為傳遞查詢信息大概需要這樣的設(shè)計:
    1、在Controller里面不暴露hibernate API,但是能夠順利將參數(shù)傳遞到Manager。
    2、Manager直接傳遞,或者將這些參數(shù)轉(zhuǎn)換為Hibernate API后再傳遞,因為這正是manager需要負責的商業(yè)邏輯之一。
    3、DAO里面最好不要做那么多轉(zhuǎn)換,畢竟它是持久層。
    當然,目前符合這個要求,只是限定于Map是二元容器,不能存3元的查詢條件(key、value、type)。所以可能下一步會補足。
    分析到這里,springside的DAO的結(jié)構(gòu)大概就是這樣的。
    感覺這和我們Team上個項目的結(jié)構(gòu)很象(不好意思,沒說有springside那么好),有一點區(qū)別。
    由于Manager繼承自DAO,我們讓DAO多了很多方法,主要就是想提供方便。尤其是
    <T>?T?loadById(Class<T>?persistenceClass,?Serializable?id);
    <T>?T?loadByProperty(Class<T>?persistenceClass,?String?propertyName,?Object?value);
    <T>?List<T>listAll(Class<T>?persistenceClass);
    <T>?List<T>listByProperty(Class<T>?persistenceClass,?String?propertyName,?Object?value);
    <T>?List<T>listAllOrderBy(Class<T>?persistenceClas,?boolean?isAsc,?String?orderByPropertyName);
    可是springside并沒有提供這樣的東西,有點遺憾。
    這些東西經(jīng)常用到,如果使用了會減少了很多時候遇到的Manager里面注入其他Domain的DAO,卻只是為了load或者listAll的問題(同時用generic):D

    今天有點別的事,先說到這里,好好想想,看有什么問題過兩天在說說。這Blog太流水賬,太空洞,大家見諒。
    posted on 2006-09-05 21:52 Tin 閱讀(3646) 評論(3)  編輯  收藏 所屬分類: Other Project

    評論

    # re: 看看Springside的DAO和Manager 2006-09-05 21:59 dukerr
    缺乏要點 ,亂!
    大家的時間都很寶貴!  回復  更多評論
      

    # re: 看看Springside的DAO和Manager 2006-09-05 22:30 Tin
    樓上朋友,不好意思,我修改了下,如果賞光,可以只看促體部分:D
    希望不要浪費大家過多時間。  回復  更多評論
      

    # re: 看看Springside的DAO和Manager 2006-09-05 22:49 江南白衣
    “如果使用了會減少了很多時候遇到的Manager里面注入其他Domain的DAO,卻只是為了load或者listAll的問題(同時用generic):D”

    好,SS2.0會加入他們。不過listAll的使用要注意,看是否默認就要用帶狀態(tài)過濾的list函數(shù)。  回復  更多評論
      

    主站蜘蛛池模板: 亚洲人和日本人jizz| 久久亚洲精品成人AV| 国产成人亚洲精品91专区高清| 一级成人生活片免费看| 亚洲午夜一区二区三区| 一级毛片免费播放| 亚洲AV电影院在线观看| 99re6热视频精品免费观看| 亚洲av中文无码乱人伦在线r▽ | 一个人在线观看视频免费| 亚洲Av无码一区二区二三区| 在线观看免费人成视频| 亚洲欧洲av综合色无码| 4338×亚洲全国最大色成网站| 亚洲人成在线影院| 最近中文字幕mv免费高清视频8 | 亚洲中文字幕在线乱码| 99久久婷婷国产综合亚洲| 女人被免费视频网站| 免费看一级高潮毛片| 中文字幕精品亚洲无线码二区| 国产在线精品免费aaa片| 77777_亚洲午夜久久多人| 成年女人色毛片免费看| 黄色免费网址大全| 国产国拍亚洲精品mv在线观看| 一本久久免费视频| 亚洲AV无码精品色午夜在线观看| 精品免费久久久久久久| 国产亚洲欧美日韩亚洲中文色| 狠狠亚洲婷婷综合色香五月排名| 久久久久久毛片免费播放| 亚洲AV无码专区在线电影成人| 久久精品国产精品亚洲人人| 1000部羞羞禁止免费观看视频| 国产亚洲欧美在线观看| 亚洲国产精品乱码一区二区| 好爽又高潮了毛片免费下载| 国产免费播放一区二区| 亚洲人成网站色在线观看| 色噜噜AV亚洲色一区二区|