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

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

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

    posts - 32, comments - 153, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    使用AOP實現(xiàn)類型安全的泛型DAO

    Posted on 2006-11-26 21:08 Zou Ang 閱讀(5441) 評論(8)  編輯  收藏 所屬分類:

    由于要求在項目中使用泛型的DAO,所以上網(wǎng)Google了一下,找到了IBM的一篇文章。文章講得不錯,但是有些地方不清楚,如果完全按照那篇文章可能還會遇到一些困難。所以寫了這篇文章,解釋如何在項目中加入泛型的DAO實現(xiàn)。

    首先是總的類關(guān)系的UML圖:

    然后是在配置文件中的關(guān)系圖:??

    其中,IStaffDao是我們自己定義的接口,這個接口類似:

    public ? interface ?IStaffDAO? extends ?GenericDao < Staff,?Integer > {?

    public ?List?listAll();?

    public ?Staff?getByLogonAndId(String?logon,?Integer?id);?

    // more??

    }
    ?

    ?

    GenericDao<T , PK extends Serilizable> 是泛型的 Dao 接口:

    /**
    ?*?2006-11-22
    ?*?范型DAO接口
    ?*?
    @author ?Zou?Ang
    ?*?Contact?<a?href?="mailto:richardeee@gmail.com">Zou?Ang</a>
    ?
    */

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

    ????
    /**
    ?????*?保存一個對象到數(shù)據(jù)庫
    ?????*?
    @param ?newInstance?需要保存的對象
    ?????*?
    @return
    ?????
    */

    ????PK?create(T?newInstance);
    ????
    /**
    ?????*?從數(shù)據(jù)庫讀取一個對象
    ?????*?
    @param ?id?主鍵
    ?????*?
    @return
    ?????
    */

    ????T?read(PK?id);
    ????
    ????
    /**
    ?????*?更新一個對象
    ?????*?
    @param ?transientObject?被更新的對象
    ?????
    */

    ????
    void ?update(T?transientObject);
    ????
    ????
    /**
    ?????*?刪除一個對象
    ?????*?
    @param ?transientObject?被刪除的對象
    ?????
    */

    ????
    void ?delete(T?transientObject);
    }

    GenericDaoHibernateImpl GenericDao 接口的泛型實現(xiàn) :


    /**
    ?*?2006-11-22
    ?*?范型DAO實現(xiàn)
    ?*?
    @author ?Zou?Ang
    ?*?Contact?<a?href?="mailto:richardeee@gmail.com">Zou?Ang</a>
    ?
    */

    public ? class ?GenericDaoHibernateImpl < T,PK? extends ?Serializable > ?
    ????
    extends ?HibernateDaoSupport?
    ????????
    implements ?GenericDao < T,?PK > ?,FinderExecutor {
    ????
    ????
    private ?Class < T > ?type;
    ????
    private ?FinderNamingStrategy?namingStrategy? = ? new ?SimpleFinderNamingStrategy();? // ?Default.?Can?override?in?config
    ???? private ?FinderArgumentTypeFactory?argumentTypeFactory? = ? new ?SimpleFinderArgumentTypeFactory();? // ?Default.?Can?override?in?config
    ????
    ????
    public ?GenericDaoHibernateImpl(Class < T > ?type) {
    ????????
    this .type? = ?type;
    ????}


    ????
    /* ?(non-Javadoc)
    ?????*?@see?com.gdnfha.atcs.common.service.dao.GenericDao#create(java.lang.Object)
    ?????
    */

    ????
    public ?PK?create(T?newInstance)? {
    ????????
    return ?(PK)getHibernateTemplate().save(newInstance);
    ????}


    ????
    /* ?(non-Javadoc)
    ?????*?@see?com.gdnfha.atcs.common.service.dao.GenericDao#delete(java.lang.Object)
    ?????
    */

    ????
    public ? void ?delete(T?transientObject)? {
    ????????getHibernateTemplate().delete(transientObject);
    ????}


    ????
    /* ?(non-Javadoc)
    ?????*?@see?com.gdnfha.atcs.common.service.dao.GenericDao#read(java.io.Serializable)
    ?????
    */

    ????
    public ?T?read(PK?id)? {
    ????????
    return ?(T)getHibernateTemplate().get(type,?id);
    ????}


    ????
    /* ?(non-Javadoc)
    ?????*?@see?com.gdnfha.atcs.common.service.dao.GenericDao#update(java.lang.Object)
    ?????
    */

    ????
    public ? void ?update(T?transientObject)? {
    ????????getHibernateTemplate().update(transientObject);
    ????}


    ????
    public ?List < T > ?executeFinder(Method?method,? final ?Object[]?queryArgs)
    ????
    {
    ????????
    final ?Query?namedQuery? = ?prepareQuery(method,?queryArgs);
    ????????
    return ?(List < T > )?namedQuery.list();
    ????}


    ????
    public ?Iterator < T > ?iterateFinder(Method?method,? final ?Object[]?queryArgs)
    ????
    {
    ????????
    final ?Query?namedQuery? = ?prepareQuery(method,?queryArgs);
    ????????
    return ?(Iterator < T > )?namedQuery.iterate();
    ????}

    ????
    ????
    private ?Query?prepareQuery(Method?method,?Object[]?queryArgs)
    ????
    {
    ????????
    final ?String?queryName? = ?getNamingStrategy().queryNameFromMethod(type,?method);
    ????????
    final ?Query?namedQuery? = ?getSession().getNamedQuery(queryName);
    ????????String[]?namedParameters?
    = ?namedQuery.getNamedParameters();
    ????????
    if (namedParameters.length == 0 )
    ????????
    {
    ????????????setPositionalParams(queryArgs,?namedQuery);
    ????????}
    ? else ? {
    ????????????setNamedParams(namedParameters,?queryArgs,?namedQuery);
    ????????}

    ????????
    return ?namedQuery;
    ????}


    ????
    private ? void ?setPositionalParams(Object[]?queryArgs,?Query?namedQuery)
    ????
    {
    ????????
    // ?Set?parameter.?Use?custom?Hibernate?Type?if?necessary
    ???????? if (queryArgs != null )
    ????????
    {
    ????????????
    for ( int ?i? = ? 0 ;?i? < ?queryArgs.length;?i ++ )
    ????????????
    {
    ????????????????Object?arg?
    = ?queryArgs[i];
    ????????????????Type?argType?
    = ?getArgumentTypeFactory().getArgumentType(arg);
    ????????????????
    if (argType? != ? null )
    ????????????????
    {
    ????????????????????namedQuery.setParameter(i,?arg,?argType);
    ????????????????}

    ????????????????
    else
    ????????????????
    {
    ????????????????????namedQuery.setParameter(i,?arg);
    ????????????????}

    ????????????}

    ????????}

    ????}


    ????
    private ? void ?setNamedParams(String[]?namedParameters,?Object[]?queryArgs,?Query?namedQuery)
    ????
    {
    ????????
    // ?Set?parameter.?Use?custom?Hibernate?Type?if?necessary
    ???????? if (queryArgs != null )
    ????????
    {
    ????????????
    for ( int ?i? = ? 0 ;?i? < ?queryArgs.length;?i ++ )
    ????????????
    {
    ????????????????Object?arg?
    = ?queryArgs[i];
    ????????????????Type?argType?
    = ?getArgumentTypeFactory().getArgumentType(arg);
    ????????????????
    if (argType? != ? null )
    ????????????????
    {
    ????????????????????namedQuery.setParameter(namedParameters[i],?arg,?argType);
    ????????????????}

    ????????????????
    else
    ????????????????
    {
    ????????????????????
    if (arg? instanceof ?Collection)? {
    ????????????????????????namedQuery.setParameterList(namedParameters[i],?(Collection)?arg);
    ????????????????????}

    ????????????????????
    else
    ????????????????????
    {
    ????????????????????????namedQuery.setParameter(namedParameters[i],?arg);
    ????????????????????}

    ????????????????}

    ????????????}

    ????????}

    ????}

    ????
    ????
    public ?FinderNamingStrategy?getNamingStrategy()
    ????
    {
    ????????
    return ?namingStrategy;
    ????}


    ????
    public ? void ?setNamingStrategy(FinderNamingStrategy?namingStrategy)
    ????
    {
    ????????
    this .namingStrategy? = ?namingStrategy;
    ????}


    ????
    public ?FinderArgumentTypeFactory?getArgumentTypeFactory()
    ????
    {
    ????????
    return ?argumentTypeFactory;
    ????}


    ????
    public ? void ?setArgumentTypeFactory(FinderArgumentTypeFactory?argumentTypeFactory)
    ????
    {
    ????????
    this .argumentTypeFactory? = ?argumentTypeFactory;
    ????}


    }


    FinderNamingStrategy 是查找方法的命名規(guī)范:

    public ? interface ?FinderNamingStrategy
    {
    ????
    public ?String?queryNameFromMethod(Class?findTargetType,?Method?finderMethod);
    }


    目前有兩個命名查找策略,使用的是

    Simple 的,也就是直接是 < 類型名 >.< 方法名 > 的形式。

    public ? class ?SimpleFinderNamingStrategy? implements ?FinderNamingStrategy
    {
    ????
    public ?String?queryNameFromMethod(Class?findTargetType,?Method?finderMethod)
    ????
    {
    ????????
    return ?findTargetType.getSimpleName()? + ? " . " ? + ?finderMethod.getName();
    ????}

    }

    FinderArgumentTypeFactory 目前還沒有什么作用,主要是返回自定義的 Hibernate 類型:

    ?

    public ? class ?SimpleFinderArgumentTypeFactory? implements ?FinderArgumentTypeFactory
    {
    ????
    public ?Type?getArgumentType(Object?arg)
    ????
    {
    // ????????if(arg?instanceof?Enum)
    // ????????{
    // ????????????return?getEnumType(arg.getClass());
    // ????????}
    // ????????else
    // ????????{
    ???????????? return ? null ;
    // ????????}
    ????}


    // ????private?Type?getEnumType(Class<??extends?Object>?argClass)
    // ????{
    // ????????Properties?p?=?new?Properties();
    // ????????p.setProperty("enumClassName",?argClass.getName());
    // ????????Type?enumType?=?TypeFactory.heuristicType("org.hibernate.demo.EnumUserType",?p);
    // ????????return?enumType;
    // ????}
    }

    ?

    FinderIntroductionAdvisor FinderIntroductionInterceptor:

    ?

    public ? class ?FinderIntroductionAdvisor? extends ?DefaultIntroductionAdvisor
    {
    ????
    public ?FinderIntroductionAdvisor()
    ????
    {
    ????????
    super ( new ?FinderIntroductionInterceptor());
    ????}

    }

    public ? class ?FinderIntroductionInterceptor? implements ?IntroductionInterceptor
    {

    ????
    public ?Object?invoke(MethodInvocation?methodInvocation)? throws ?Throwable
    ????
    {

    ????????FinderExecutor?executor?
    = ?(FinderExecutor)?methodInvocation.getThis();

    ????????String?methodName?
    = ?methodInvocation.getMethod().getName();
    ????????
    if (methodName.startsWith( " get " )? || ?methodName.startsWith( " list " ))
    ????????
    {
    ????????????Object[]?arguments?
    = ?methodInvocation.getArguments();
    ????????????
    return ?executor.executeFinder(methodInvocation.getMethod(),?arguments);
    ????????}

    ????????
    else ? if (methodName.startsWith( " iterate " ))
    ????????
    {
    ????????????Object[]?arguments?
    = ?methodInvocation.getArguments();
    ????????????
    return ?executor.iterateFinder(methodInvocation.getMethod(),?arguments);
    ????????}

    // ????????else?if(methodName.startsWith("scroll"))
    // ????????{
    // ????????????Object[]?arguments?=?methodInvocation.getArguments();
    // ????????????return?executor.scrollFinder(methodInvocation.getMethod(),?arguments);
    // ????????}
    ???????? else
    ????????
    {
    ????????????
    return ?methodInvocation.proceed();
    ????????}

    ????}


    ????
    public ? boolean ?implementsInterface(Class?intf)
    ????
    {
    ????????
    return ?intf.isInterface()? && ?FinderExecutor. class .isAssignableFrom(intf);
    ????}

    }


    然后就到了配置文件了:

    ?????? <!-- ??Start?:范型DAO配置?? --> ?
    ?????
    < ?bean?? id? ="abstractDaoTarget" ?
    ????????class?
    ="com.gdnfha.atcs.common.service.dao.hibernate.GenericDaoHibernateImpl" ?
    ????????abstract?
    ="true" ? > ?
    ?????????
    < ?property?? name? ="sessionFactory" ? > ?
    ?????????????
    < ?ref?? local? ="sessionFactory" ??? /> ?
    ?????????
    </ ?property? > ?
    ?????????
    < ?property?? name? ="namingStrategy" ? > ?
    ?????????????
    < ?ref?? bean? ="simpleFinderNamingStratrgy" ??? /> ?
    ?????????
    </ ?property? > ?
    ?????
    </ ?bean? > ?
    ?
    ?????
    < ?bean?? id? ="abstractDao" ?
    ????????class?
    ="org.springframework.aop.framework.ProxyFactoryBean" ?
    ????????abstract?
    ="true" ? > ?
    ?????????
    < ?property?? name? ="interceptorNames" ? > ?
    ?????????????
    < ?list? > ?
    ?????????????????
    < ?value? > ?finderIntroductionAdvisor? </ ?value? > ?
    ?????????????
    </ ?list? > ?
    ?????????
    </ ?property? > ?
    ?????
    </ ?bean? > ?
    ?
    ?????
    < ?bean?? id? ="finderIntroductionAdvisor" ?
    ????????class?
    ="com.gdnfha.atcs.common.service.dao.finder.FinderIntroductionAdvisor" ??? /> ?
    ?
    ?????
    < ?bean?? id? ="namingStrategy" ?
    ????????class?
    ="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" ? > ?
    ?????????
    < ?property?? name? ="staticField" ? > ?
    ?????????????
    < ?value? > ?org.hibernate.cfg.ImprovedNamingStrategy.INSTANCE? </ ?value? > ?
    ?????????
    </ ?property? > ?
    ?????
    </ ?bean? > ?
    ?
    ?????
    < ?bean?? id? ="extendedFinderNamingStrategy" ?
    ????????class?
    ="com.gdnfha.atcs.common.service.dao.finder.impl.ExtendedFinderNamingStrategy" ??? /> ?
    ????????
    ?????
    < ?bean?? id? ="simpleFinderNamingStratrgy" ??class? ="com.gdnfha.atcs.common.service.dao.finder.impl.SimpleFinderNamingStrategy" ? /> ?
    ??????
    <!-- ??End:?范型DAO配置?? --> ?
    ?
    ?????
    <!-- ??Start:?測試范型DAO?? --> ?
    ??
    ?????
    < ?bean?? id? ="staffDao" ??parent? ="abstractDao" ? > ?
    ?????????
    < ?property?? name? ="proxyInterfaces" ? > ?
    ?????????????
    < ?value? > ?com.gdnfha.atcs.maintain.service.dao.IStaffDAO????? </ ?value? > ?
    ?????????
    </ ?property? > ?
    ?????????
    < ?property?? name? ="target" ? > ?
    ?????????????
    < ?bean?? parent? ="abstractDaoTarget" ? > ?
    ?????????????????
    < ?constructor-arg? > ?
    ?????????????????????
    < ?value? > ?com.gdnfha.atcs.common.pojo.Staff? </ ?value? > ?
    ?????????????????
    </ ?constructor-arg? > ?
    ?????????????
    </ ?bean? > ?
    ?????????
    </ ?property? > ?
    ?????
    </ ?bean? > ?
    ?
    ?????
    <!-- ???End:測試范型DAO?? --> ?


    還要在Staff.hbm.xml中配置:

    < ?query?? name? ="Staff.getByLogonAndId" ? > ??
    ????????
    <![CDATA[ ?select?s?from?Staff?s?where?s.staffLogon?=???and?s.staffId?=???? ]]> ??
    </ ?query? > ?

    這里要特別注意<query></query>這個要寫在<class></class>的外面,否則會提示Mapping Exception:No Named Query

    好了,大公告成了!現(xiàn)在可以跟以前一樣使用

    appContext.getBean("staffDao"); 這樣進行測試了

    staffDao.read(new Integer(1));

    staffDao.getByLogonAndId("abc",new Integer(2));


    評論

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2006-11-27 10:18 by Nicholas Ding
    原文的翻譯在 http://www.nirvanastudio.org/java/dont-repeat-the-dao.html

    摟主有沒有道德啊,抄別人的代碼還不忘把Author改成自己。

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2006-11-27 11:03 by Zou Ang[匿名]
    這篇文章是我寫的啊,圖也是我畫的啊,我用在項目里,叫別人有問題來找我有什么不對

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2006-11-27 11:20 by
    哇~~~你們組也搞這個??不會延期得更厲害么?

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2006-11-27 11:52 by Zou Ang[匿名]
    好,為了尊重他人的勞動成果,我把原作者加上

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2006-12-07 15:52 by zhongbai
    按以上的配置,事務(wù)要怎樣處理呢?
    按常規(guī)方法配置事務(wù)后,引介攔截器 FinderIntroductionInterceptor 會出錯,因為配置事務(wù)后 攔截到的已不是 FinderExecutor 接口的實現(xiàn)了,而是其包裝器,所以會報告錯誤,不知道你們是怎么處理的呀??

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2006-12-08 06:24 by Zou Ang
    要在DAO層加上事務(wù)么?為什么不直接在Business Logic層加事務(wù)呢

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2006-12-08 19:32 by zhongbai
    是的,正如你所說,我把事務(wù)配置在了業(yè)務(wù)邏輯層,但是Spring啟動時報告數(shù)據(jù)源Bean循環(huán)引用的問題,不知道您在使用中是否遇到該問題?是如何解決的呢?
    http://www.javaeye.com/topic/38166 有我對該問題的詳細描述,希望你能不吝指點。

    # re: 使用AOP實現(xiàn)類型安全的泛型DAO  回復(fù)  更多評論   

    2008-04-03 10:27 by 海狼
    請問大俠們,使用這個Dao,的那個方法實現(xiàn)分頁呀?在映射文件里面怎么設(shè)置?
    主站蜘蛛池模板: 一级毛片免费播放试看60分钟| 亚洲精品福利你懂| 麻豆安全免费网址入口| 热99re久久精品精品免费| 亚洲不卡在线观看| 国产人在线成免费视频| 久久精品国产亚洲αv忘忧草| 日本免费xxxx色视频| 中文字幕在线观看亚洲日韩| 麻豆国产精品入口免费观看| 立即播放免费毛片一级| 亚洲福利在线播放| 中文字幕乱码免费看电影| 久久青青草原亚洲AV无码麻豆| 久久永久免费人妻精品下载| 亚洲国产模特在线播放| 超pen个人视频国产免费观看| 亚洲国产成人精品无码区二本| 国产不卡免费视频| 9久热这里只有精品免费| 亚洲an天堂an在线观看| 91成年人免费视频| 亚洲国产精品成人午夜在线观看| 免费一级毛片不卡在线播放| 中文毛片无遮挡高清免费| 久久香蕉国产线看观看亚洲片| A在线观看免费网站大全| 黄网站在线播放视频免费观看 | 亚欧免费一级毛片| 99热亚洲色精品国产88| 亚洲区小说区图片区| 亚洲一区二区在线免费观看| 亚洲成A人片在线播放器| 亚洲?V乱码久久精品蜜桃| 日韩视频免费在线观看| 久久精品国产亚洲av麻豆图片 | 福利免费观看午夜体检区| 美女露100%胸无遮挡免费观看| 久久久久久久综合日本亚洲| 无码日韩人妻av一区免费| eeuss影院免费92242部|