<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

      回復  更多評論
      


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


    網站導航:
     
    主站蜘蛛池模板: 成人免费777777| 亚洲国产美国国产综合一区二区 | 新最免费影视大全在线播放| 久久精品国产亚洲7777| 99久久国产免费中文无字幕| 亚洲人成人无码.www石榴| 狠狠亚洲狠狠欧洲2019| 和日本免费不卡在线v| 免费一级毛片在线播放放视频| 久久久久久亚洲精品| 国产免费人成在线视频| 一级毛片不卡片免费观看| 免费观看亚洲人成网站| 亚洲精品乱码久久久久久下载 | 亚洲天堂2016| 亚洲色精品88色婷婷七月丁香| av无码免费一区二区三区| 国产精品九九久久免费视频 | 亚洲黄色免费观看| xvideos亚洲永久网址| 中国人xxxxx69免费视频| 一级毛片免费全部播放| 亚洲午夜精品一区二区公牛电影院| 亚洲AV无码一区二区三区国产| 国产香蕉免费精品视频| 中文字幕在线免费观看视频| 亚洲欧美日韩中文字幕一区二区三区 | 97在线视频免费公开视频| 亚洲最大av资源站无码av网址| 亚洲成a人片在线观看无码 | 无码国产亚洲日韩国精品视频一区二区三区 | 成人无遮挡毛片免费看| 久久久精品免费国产四虎| 天堂亚洲免费视频| 亚洲国产AV一区二区三区四区| 亚洲精品国产电影午夜| 亚洲爱情岛论坛永久| 亚洲乱码中文字幕综合| 亚洲成AV人网址| 国产一区二区免费在线| 四虎影院免费视频|