<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 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

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

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

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

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

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

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

    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 > ? {

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

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

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

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

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

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


    /**
    ?*?2006-11-22
    ?*?范型DAO實(shí)現(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);
    }


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

    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:?測(cè)試范型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:測(cè)試范型DAO?? --> ?


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

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

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

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

    appContext.getBean("staffDao"); 這樣進(jìn)行測(cè)試了

    staffDao.read(new Integer(1));

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


    評(píng)論

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

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

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

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

    2006-11-27 11:03 by Zou Ang[匿名]
    這篇文章是我寫的啊,圖也是我畫的啊,我用在項(xiàng)目里,叫別人有問(wèn)題來(lái)找我有什么不對(duì)

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

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

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

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

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

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

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

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

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

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

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

    2008-04-03 10:27 by 海狼
    請(qǐng)問(wèn)大俠們,使用這個(gè)Dao,的那個(gè)方法實(shí)現(xiàn)分頁(yè)呀?在映射文件里面怎么設(shè)置?
    主站蜘蛛池模板: 亚洲妇女无套内射精| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 亚洲AV无码片一区二区三区| 最新欧洲大片免费在线| 亚洲伦理一二三四| 性短视频在线观看免费不卡流畅| 亚洲国产中文在线二区三区免| 国产成人免费高清激情明星| 亚洲一区二区三区无码国产| 成人片黄网站色大片免费| 亚洲AV无码精品国产成人| 亚洲av无码专区在线观看素人| 一个人看的在线免费视频| 亚洲午夜国产精品无码老牛影视| a毛片免费全部在线播放**| 亚洲国产第一页www| 亚洲精品在线免费看| 亚洲午夜无码久久久久软件| 亚洲av手机在线观看| 91福利免费网站在线观看| 亚洲天堂中文资源| 国产一精品一AV一免费孕妇| 国产精品日本亚洲777| 亚洲中文字幕在线乱码| 最近免费中文字幕高清大全| jiz zz在亚洲| 亚洲精品乱码久久久久久不卡| 国产羞羞的视频在线观看免费| 亚洲精品在线播放视频| 一个人免费观看视频www | jizz免费在线观看| 亚洲人成影院在线| 全免费a级毛片免费看无码| fc2免费人成为视频| 亚洲白嫩在线观看| 免费人成在线观看网站视频| 日本高清免费观看| 色天使色婷婷在线影院亚洲| 亚洲AV无码久久寂寞少妇| 全免费一级午夜毛片| 久操免费在线观看|