所有数据库查询的全局休眠过滤器


问题内容

我在Web应用程序中使用Spring
MVC和Hibernate。我正在寻找一种创建全局hibernate过滤器的方法,该方法可应用于我的DAO类中的每个查询,而无需在每个DAO方法中显式启用它。

要求是通过用户选择的会话变量来过滤记录。因此,我们的查询参数将保留在会话中,并且该会话中的所有DAO查询都需要使用此变量过滤结果。此处的目的是避免每种DAO方法中所有可重复的过滤代码。

任何想法都欢迎!


问题答案:

在这里说明我的处理方式。以下基于对@ Rp-的讨论以及此处提出的建议。

配置此功能的三个主要要素: -Spring 的会话范围内的bean -package - info.java -Spring AOP


我创建了一个 会话范围的Spring bean ,该 bean将保存用户选择的变量。该变量将根据用户的要求通过spring控制器映射方法进行修改。处于spring托管bean中,借助于spring的依赖注入,我可以在应用程序中的任何位置访问session变量。

@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 {
...
}

最后,使用Hibernate的会话工厂的getCurrentSession()方法中的 AspectJ 方面来拦截所有DAO查询。

下面是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方法中不需要在每个查询中进行显式的条件检查。