我在我的Web应用程序中使用Spring MVC和Hibernate。我正在寻找一种方法来创建一个全局的hibernate过滤器,它将应用于我的DAO类中的每个查询,而不必在每个DAO方法中显式启用它。
要求是按用户选择的会话变量过滤记录。因此,我们的查询参数将保存在会话中,该会话中的所有DAO查询都需要通过此变量过滤结果。这里的目的是避免每个DAO方法中的所有可重复过滤代码。
欢迎任何和所有想法!
答案 0 :(得分:13)
我在这里解决了这个问题。以下是基于与@ Rp-的讨论和here提出的建议。
配置这个有三个主要因素:
- 春季的会议范围豆类
- package-info.java
- 春天AOP
我创建了一个会话范围的Spring bean ,它将保存我的用户选择的变量。变量将根据用户的请求通过spring Controller映射方法进行修改。由于spring的依赖注入,我可以使用spring托管bean来访问我的应用程序中的任何会话变量。
@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class SessionParam implements Serializable{
private String sessParam;
..
..
}
接下来,我在包级别定义 hibernate过滤器。
这是在package-info.java
文件中完成的。因此,此包中的所有实体都继承此过滤器。
@FilterDef(name="GLOBAL_FILTER", parameters = {@ParamDef(name="sessParam", type="string")},
defaultCondition = "sessParam = :sessParam")
package com.company.app.entity;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
import org.hibernate.annotations.ParamDef;
包中的实体使用hibernate的@Filter注释进行注释,如下所示:
@Entity
@Filter(name="GLOBAL_FILTER")
@Table(name = "TABLE_XYZ", schema = "SCHEMA_ABC")
public class TableXyz implements Serializable {
...
}
最后,所有DAO查询都是在hibernate的Session Factory的getCurrentSession()方法中使用 AspectJ 方面截获的。
以下是Aspect类。
@Aspect
@Component
public class GlobalFilter {
@Autowired
SessionParam sessionParam;
@Pointcut("execution(* org.hibernate.SessionFactory.getCurrentSession(..))")
protected void hibernateSessionFetch(){
}
@AfterReturning(pointcut = "hibernateSessionFetch()", returning = "result")
public void enableGlobalFilter(JoinPoint joinPoint, Object result){
Session session = (Session) result;
session.enableFilter("GLOBAL_FILTER").setParameter("sessParam", sessionParam.getSessParam());
}
}
对具有“GLOBAL_FILTER”的实体的所有查询现在都对所需变量进行了条件检查。 DAO方法中不需要在每个查询中进行显式条件检查。