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

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

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

    邊城愚人

    如果我不在邊城,我一定是在前往邊城的路上。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      31 隨筆 :: 0 文章 :: 96 評論 :: 0 Trackbacks

    當你偶然路過這里時,我假定你已經很明白 java 中范型和 DAO 模式了。當然,我也會順便嘮叨幾句范型和 DAO 模式,只是它們不會這篇隨筆的重點。我早先在 DW 上看到一篇蠻不錯的文章 不要重復 DAOHibernate Spring AOP 構建泛型類型安全的 DAO ,它也促使我在一個實驗工程中使用了范型化的 DAO 模式。前幾天看到的另一篇文章 Generic Data Access Objects 使我重新想起了這檔事。以前的代碼不可追,索性就重做了一個 sample 實現范型化的 DAO 。坦白的講,和上面的兩篇文章相比,這篇隨筆并沒有太多新內容,如果你愿意的話,你可以只看上面的兩篇文章而關掉這個頁面。

    先說說范型。自從 java5 引入范型后,它就成為我代碼中不可少的一部分。在沒有范型以前,強制轉換充斥于文件的各個角落,不單代碼不易于閱讀,時不時的會出現轉換異常。就像你所經歷的,對于集合類中的對象,如果顯示聲明的話,安全性和閱讀性都大大提高。總之啦,范型是個很有用的東西。

    ?????? 再說說 DAO 模式。 Java EE 中,最經典的架構模式就是三層架構或多層架構。而數據持久化層,流行的就是 DAO 模式。盡管很多人批評這種 貧血模型 OO ,但使用上的方便使得 DAO 模式很受程序員喜愛。想一想 Spring 框架吧,支持 DAO 模式的典型框架,數據與操作的分離,使得 IOC AOP 等技術靈活的運轉起來。說到底,理論和實踐并不是完全統一的,為了滿足實際的需要,有時不得不做些折衷。

    好了,該說說我做的一個小例子。其實范型化的 DAO 就是給出一個抽象的 DAO 及其實現,實現的內容就是基本的 CRUD 操作。閑言少敘,開始我的代碼。

    范型的 DAO 接口,包含基本的 CRUD 操作。 GenericDAO 的實現,通過 Spring 模板實現了 CRUD 操作。

    import ?java.util. * ;
    import ?java.io. * ;

    public ? interface ?GenericDAO < T,?PK? extends ?Serializable > ? {

    ????T?findById(PK?id
    );

    ????List
    < T > ?findAll();

    ????
    void ?insert(T?entity);
    ????
    ????
    void ?update(T?entity);

    ????
    void ?delete(T?entity);
    }
    ??????
    ?package?org.prague.dao.hibernate;

    import?java.util.*;
    import?java.io.*;
    import?org.hibernate.Session;
    import?org.hibernate.SessionFactory;
    import?org.springframework.orm.hibernate3.HibernateTemplate;
    import?org.prague.dao.GenericDAO;
    import?java.lang.reflect.*;

    public?abstract?class?GenericHibernateDAO<T,?PK?extends?Serializable>
    ????????
    implements?GenericDAO<T,?PK>?{

    ????
    private?HibernateTemplate?hibernateTemplate;
    ????
    private?Class<T>?type;
    ????
    ????
    public?GenericHibernateDAO(){
    ????????
    this.type?=?(Class<T>)((ParameterizedType)(this.getClass().getGenericSuperclass()))
    ????????????????????????????.getActualTypeArguments()[
    0];
    ????}

    ????
    ????
    public?void?setSessionFactory(SessionFactory?sessionFactory){
    ????????
    this.hibernateTemplate?=?new?HibernateTemplate(sessionFactory);
    ????}

    ????
    ????
    public?void?delete(T?entity)?{
    ????????
    this.hibernateTemplate.delete(entity);
    ????}

    ????
    ????

    ????
    public?List<T>?findAll()?{
    ????????String?hql?
    =?"from?"+this.type.getSimpleName();
    ????????
    return?(List<T>)this.hibernateTemplate.find(hql);
    ????}


    ????
    public?T?findById(PK?id)?{
    ????????
    return?(T)this.hibernateTemplate.get(type,?id);
    ????}


    ????
    public?void?insert(T?entity)?{
    ????????
    this.hibernateTemplate.save(entity);
    ????}


    ????
    public?void?update(T?entity)?{
    ????????
    this.hibernateTemplate.update(entity);
    ????}

    ????
    ????
    protected?Session?getSession(){
    ????????
    return?this.hibernateTemplate.getSessionFactory().getCurrentSession();
    ????}

    ????
    ????
    protected?HibernateTemplate?getHibernateTemplate(){
    ????????
    return?this.hibernateTemplate;
    ????}

    ????
    }
    ??????

    如果不用Spring的話,Hibernate也能輕松的實現這些操作。但坦白的講,這些操作并不實用。對于不同的實體,可能不會調用這些操作或是調用的操作不完全相同。比如說,對于查詢數據表中的數據列表,可能的情況是要求查詢條件中按照某些字段排序。如果想給出一個通用的實現方法,接口中不可避免的要包含查詢條件,比如說包含一個Hibernate中的條件查詢對象。但這樣話,就需要在Service層構造查詢條件,還不如直接寫個方法來的實在。
    ???

    下面就是一個具體的DAO及實現。

    import?org.prague.domain.*;

    public?interface?AccountDAO?extends?GenericDAO<Account,Long>{
    ????
    public?Account?findByNameAndPwd(String?name,String?pwd);
    }


    package?org.prague.dao.hibernate;

    import?java.util.List;

    import?org.prague.dao.AccountDAO;
    import?org.prague.domain.Account;
    import?org.springframework.orm.hibernate3.HibernateCallback;
    import?org.springframework.orm.hibernate3.HibernateTemplate;

    public?class?AccountHibernateDAO?extends?GenericHibernateDAO<Account,Long>?implements
    ????????AccountDAO?
    {

    ????
    public?Account?findByNameAndPwd(final?String?name,?final?String?pwd)?{
    ????????
    final?String?hql??=?"from?Account?where?name=:name?and?pwd=:pwd";
    ????????
    /*
    ????????List<Account>?list?=?(List<Account>)this.getHibernateTemplate().executeFind(new?HibernateCallback(){
    ????????????public?Object?doInHibernate(Session?s)?throws?HibernateException,?SQLException?{
    ????????????????return?s.createQuery(hql).setString("name",?name).setString("pwd",?pwd).list();
    ????????????}
    ????????});
    ????????
    */

    ????????List
    <Account>?list?=?(List<Account>)this.getHibernateTemplate().findByNamedParam(hql,?
    ????????????????
    new?String[]{"name","pwd"},?new?String[]{name,pwd});
    ????????
    if(list!=null?&&?!list.isEmpty()){
    ????????????
    return?list.get(0);
    ????????}

    ????????
    return?null;
    ????}

    }

    ???????當然少不了實體bean了,盡管它很簡單。

    package?org.prague.domain;

    import?java.io.Serializable;

    public?abstract?class?AbstractDomain<PK?extends?Serializable>{
    ????
    protected?PK?id;

    ????
    ????
    public?PK?getId()?{
    ????????
    return?id;
    ????}


    ????
    public?void?setId(PK?id)?{
    ????????
    this.id?=?id;
    ????}


    }


    package?org.prague.domain;

    public?class?Account?extends?AbstractDomain<Long>{
    ????
    private?String?name;
    ????
    private?String?pwd;
    ????
    ????
    public?String?getName()?{
    ????????
    return?name;
    ????}

    ????
    public?void?setName(String?name)?{
    ????????
    this.name?=?name;
    ????}

    ????
    public?String?getPwd()?{
    ????????
    return?pwd;
    ????}

    ????
    public?void?setPwd(String?pwd)?{
    ????????
    this.pwd?=?pwd;
    ????}

    ????@Override
    ????
    public?String?toString()?{
    ????????
    return?"Account:?id="+this.id+"?name="+this.name+"?pwd="+this.pwd+"\n";
    ????}

    ????
    }

    ???????想要程序運行起來,還需要配置文件的作用,這里列出Account對應的Hibernate映射文件和Spring配置文件。由于該Sample沒有Service層的概念,因此DAO需要聲明性事務的作用。

    <?xml?version='1.0'?encoding='UTF-8'?>
    <!DOCTYPE?hibernate-mapping?PUBLIC?"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"?
    ????"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
    >

    <hibernate-mapping?package="org.prague.domain">
    ????
    <class?name="Account"?table="Account">
    ????????
    <id?name="id"?column="id"?type="java.lang.Long">
    ????????????
    <generator?class="identity"></generator>
    ????????
    </id>
    ????????
    <property?name="name"?column="name"></property>
    ????????
    <property?name="pwd"?column="pwd"></property>
    ????
    </class>
    </hibernate-mapping>

    ?

    <?xml?version="1.0"?encoding="UTF-8"?>
    <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">
    <beans?default-lazy-init="true">

    ????
    <bean?id="sessionFactory"
    ????????class
    ="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    ????????
    <property?name="configLocation">
    ????????????
    <value>classpath:hibernate.cfg.xml</value>
    ????????
    </property>
    ????
    </bean>

    ????
    <bean?name="transactionManager"
    ????????class
    ="org.springframework.orm.hibernate3.HibernateTransactionManager">
    ????????
    <property?name="sessionFactory">
    ????????????
    <ref?bean="sessionFactory"?/>
    ????????
    </property>
    ????
    </bean>

    ????
    <bean?id="baseTransactionProxy"
    ????????class
    ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
    ????????abstract
    ="true">
    ????????
    <property?name="transactionManager"?ref="transactionManager"?/>
    ????????
    <property?name="transactionAttributes">
    ????????????
    <props>
    ????????????????
    <prop?key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    ????????????????
    <prop?key="*">PROPAGATION_REQUIRED</prop>
    ????????????
    </props>
    ????????
    </property>
    ????
    </bean>

    ????
    <bean?id="accountDAO"?parent="baseTransactionProxy">
    ????????
    <property?name="target">
    ????????????
    <bean?class="org.prague.dao.hibernate.AccountHibernateDAO">
    ????????????????
    <property?name="sessionFactory">
    ????????????????????
    <ref?bean="sessionFactory"?/>
    ????????????????
    </property>
    ????????????
    </bean>
    ????????
    </property>
    ????
    </bean>
    </beans>

    ???????再多說幾句吧。我以前寫過一個程序,在GenericDAO中給出了更多的方法,比如:

    public?List<T>?findListBy(String?expression);
    ????
    public?void?deleteBy(String?expression);
    ????
    public?void?updateBy(String?expression);

    ??? 我的想法和做法是不言而喻的。當時想通過在GenericDAO中聲明這樣的公共方法,簡化DAO中操作。那是我還不是很清楚Hibernate中的Creteria,就實現一個類似于Hibernate Creteria包的東西,通過在Service層中構造Creteria對象并得到一個拼接后的hql語句,然后調用上面的這幾個方法。通過上面的幾個方法,基本上滿足了DAO層的操作。但問題是,我不得不在Service層構建CreteriaService因此顯得臃腫異常,而DAO層就單薄得很。好好的想一想,這樣的結果不過是變相的將DAO層和Service層合并了。依我的想法,刻意的追求公共數據庫操作并不一定實用。即便是這個例子,如果不使用Hibernate框架,而是使用JDBCIbatis等,GenericDAO 中的方法是很難以通用的方式實現的。你不得不做的就是,每個繼承自 GenericDAODAO,都需要單獨的實現基本的CRUD操作。??

    ?

    posted on 2007-04-17 08:55 kafka0102 閱讀(3598) 評論(7)  編輯  收藏 所屬分類: Pattern

    評論

    # re: 要范型,要DAO,更要范型DAO[未登錄] 2007-04-17 09:07 Matthew
    朋友,把排版重搞一下吧!  回復  更多評論
      

    # re: 要范型,要DAO,更要范型DAO 2007-04-17 09:20 kafka0102
    都要瘋掉了。昨晚第一遍寫的時候,直接在編輯器里做,結果添加代碼框出不來,IE死掉了。第二遍在word里寫,結果發表時不能連接服務器。好吧,一大早來做,結果從word到編輯器轉換時,格式都亂了。就這樣了,沒心情再改了。  回復  更多評論
      

    # re: 要范型,要DAO,更要范型DAO 2007-04-17 10:32 CrossAge
    這樣子做,還有必要搞DAO這一層么?
    目的就是為了節省CRUD的代碼量?  回復  更多評論
      

    # re: 要范型,要DAO,更要范型DAO 2007-04-18 08:40 開源英漢機器翻譯
    開源英漢機器翻譯C#.NET項目 www.liebiao.net

    我們邀請你 技術交流  回復  更多評論
      

    # re: 要范型,要DAO,更要范型DAO[未登錄] 2007-04-27 13:20 Diego
    樓主,你博客上的的代碼折疊功能是用什么工具生成的?我問了好幾個人都不知道,我也想要這個功能  回復  更多評論
      

    # re: 要范型,要DAO,更要范型DAO 2007-05-03 22:06 kafka0102
    發表文章時,代碼不是直接貼進去的,而是選擇編輯器中的“代碼”選項(應該在編輯菜單的最后一個位置),然后根據彈出來的對話框進行操作就行了。  回復  更多評論
      

    # re: 要范型,要DAO,更要范型DAO 2008-10-31 11:14 天山劍
    需要一個范型dao,

    上面的有問題,測試不了

    有沒有測通的

    請高手指點

    QQ:328152797

      回復  更多評論
      


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


    網站導航:
     
    主站蜘蛛池模板: 免费国产黄网站在线观看| 国产成人精品日本亚洲语音| 久久久久久av无码免费看大片 | 美女18一级毛片免费看| 国产h视频在线观看免费| 亚洲福利电影在线观看| 最近2019免费中文字幕视频三| 久久亚洲熟女cc98cm| 成年黄网站色大免费全看| 亚洲一级毛片视频| 无人影院手机版在线观看免费| 一区二区亚洲精品精华液| 在线免费一区二区| 日本高清不卡中文字幕免费| 国产亚洲美日韩AV中文字幕无码成人| 久久99久久成人免费播放| 国产亚洲AV无码AV男人的天堂| 久久青草免费91线频观看不卡| 亚洲精品亚洲人成在线麻豆| 一个人免费观看视频www| 色窝窝亚洲av网| 亚洲一区二区三区AV无码| 无码人妻AV免费一区二区三区| 中文字幕的电影免费网站| 久久亚洲国产精品123区| A级毛片高清免费视频在线播放| 99久久亚洲精品无码毛片| 无码乱肉视频免费大全合集| 亚洲国产一区二区三区在线观看| 国产一级淫片a免费播放口之| 一级有奶水毛片免费看| 久久精品国产亚洲精品2020| 女人被弄到高潮的免费视频| 一进一出60分钟免费视频| 日韩亚洲Av人人夜夜澡人人爽 | 免费观看的av毛片的网站| 青青久久精品国产免费看| 亚洲人成电影在在线观看网色| 好吊妞在线成人免费| www永久免费视频| 亚洲国产日韩女人aaaaaa毛片在线|