2014-10-20 38 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