2014-10-20 68 views
1

是否有任何已知的方法來休眠模式,面向方面的註釋(或其他任何東西,沒有工作)與切入點分頁在任何給定的方法來識別Criteria,並適用於它的setFirstResultssetMaxResults API方法?Hibernate的分頁與AOP切入點

舉例來說,我想申請分頁在我休眠GenericDao實現如下:

@Paginate 
public List<T> filter(Set<Criterion> filter, Map<String, String> alias){ 
    Criteria criteria = session.createCriteria(type.class); 
    fillCriteria(criteria, filter, alias); 
    return criteria.list(); 
} 

而且@Paginate註釋將在criteria.list()電話申請setFirstResultssetMaxResults。這可能嗎?

注:@Paginate是我想使用的一個例子。

+0

請通過添加說明您的問題的可執行示例代碼來更新您的問題,然後描述所需的結果。這裏的人們喜歡討論具體的編程問題。你更有可能以這種方式得到很好的答案。 – kriegaex 2014-10-21 10:33:38

+0

謝謝你的建議;我修改了我的問題。 – nuno 2014-10-21 10:50:21

回答

1

是的,你可以通過AspectJ

這是一個獨立的獨立代碼示例。你可以複製和粘貼類和方面並運行它。我沒有使用原來的Hibernate類,但是一些虛擬的替代品,因爲我不是一個Hibernate用戶,我也想使這個通用的答案:

假人,冬眠般的接口和類:

package de.scrum_master.app; 

public interface Criterion {} 
package de.scrum_master.app; 

public class MyCriterion implements Criterion { 
    private String criterion; 

    public MyCriterion(String criterion) { 
     this.criterion = criterion; 
    } 

    @Override 
    public String toString() { 
     return "MyCriterion [criterion=" + criterion + "]"; 
    } 
} 
package de.scrum_master.app; 

import java.util.List; 

public interface Criteria { 
    Criteria add(Criterion criterion); 
    List list(); 
    Criteria setFirstResult(int firstResult); 
    Criteria setMaxResults(int maxResults); 
} 
package de.scrum_master.app; 

import java.util.LinkedList; 
import java.util.List; 

public class MyCriteria implements Criteria { 
    private List<Criterion> criteria = new LinkedList<>(); 

    @Override 
    public Criteria add(Criterion criterion) { 
     criteria.add(criterion); 
     return this; 
    } 

    @Override 
    public List list() { 
     return new LinkedList(); 
    } 

    @Override 
    public Criteria setFirstResult(int firstResult) { 
     add(new MyCriterion("first result " + firstResult)); 
     return this; 
    } 

    @Override 
    public Criteria setMaxResults(int maxResults) { 
     add(new MyCriterion("max results " + maxResults)); 
     return this; 
    } 

    @Override 
    public String toString() { 
     return "MyCriteria [criteria=" + criteria + "]"; 
    } 
} 

正如你所看到的,方法setFirstResult(..)setMaxResults(..)添加特殊標準VI一個add(..)到內部列表。我只是做了這個以便稍後說明方面的效果。

分頁註釋:

package de.scrum_master.app; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface Paginate {} 

驅動程序:

package de.scrum_master.app; 

import java.util.HashSet; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 

public class Application { 
    @Paginate 
    public List filter(Set<Criterion> filter, Map<String, String> alias) { 
     Criteria criteria = new MyCriteria(); 
     for (Criterion criterion : filter) 
      criteria.add(criterion); 
     return criteria.list(); 
    } 

    public static void main(String[] args) { 
     Set<Criterion> filterCriteria = new HashSet<>(); 
     filterCriteria.add(new MyCriterion("where")); 
     filterCriteria.add(new MyCriterion("group by")); 
     new Application().filter(filterCriteria, null); 
    } 
} 

應用程序包含由@Paginate註釋的方法,做類似的事情,你的示例代碼。它不會調用任何分頁方法。這將通過以下方面完成。

分頁方面:

package de.scrum_master.aspect; 

import java.util.List; 
import de.scrum_master.app.Paginate; 
import de.scrum_master.app.Criteria; 

public aspect PaginationAspect { 
    Object around(Criteria criteria) : 
     call(public List Criteria+.list()) && 
     cflow(execution(@Paginate * *(..))) && 
     target(criteria) 
    { 
     System.out.println(thisJoinPoint); 
     System.out.println("Original criteria: " + criteria); 
     criteria.setFirstResult(5); 
     criteria.setMaxResults(10); 
     System.out.println("Modified criteria: " + criteria); 
     return proceed(criteria); 
    } 
} 

切入點攔截調用Criteria+.list()(所述+包括亞類),但在由@Paginate註釋任何執行方法的控制流程(cflow())發出時纔可用。調用目標綁定到參數Criteria criteria,以便在綁定到該切入點的通知方法中使用它。我們需要對調用目標的引用,因爲我們想要調用它的分頁方法。這是建議所做的事情,控制檯輸出清楚地說明了這一點。

控制檯輸出:

call(List de.scrum_master.app.Criteria.list()) 
Original criteria: MyCriteria [criteria=[MyCriterion [criterion=group by], MyCriterion [criterion=where]]] 
Modified criteria: MyCriteria [criteria=[MyCriterion [criterion=group by], MyCriterion [criterion=where], MyCriterion [criterion=first result 5], MyCriterion [criterion=max results 10]]] 

享受!

+0

這絕對有幫助!謝謝。 – nuno 2014-10-21 14:51:27

+0

請注意,我已將註釋的保留策略更新爲運行時,舊值爲拼寫錯誤。 – kriegaex 2014-10-21 15:01:31