全局hibernate过滤所有数据库查询

时间:2014-09-15 19:15:25

标签: java spring hibernate spring-mvc oracle10g

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

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

欢迎任何和所有想法!

1 个答案:

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