栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 面试经验 > 面试问答

在Spring Data JPA存储库方法查询上附加自定义条件

面试问答 更新时间:发布时间: 百科书网 趣学号

TL; DR: 我使用了Hibernate的@Filter,然后创建了一个Aspect来拦截方法

定义具有以下结构的基类实体

OwnerAwareEntity.java

import org.hibernate.annotations.Filter;import org.hibernate.annotations.FilterDef;import org.hibernate.annotations.ParamDef;    import javax.persistence.Column;import javax.persistence.MappedSuperclass;import java.io.Serializable;@MappedSuperclass@FilterDef(name = "ownerFilter", parameters = {@ParamDef(name = "ownerRef", type = "long")})@Filter(name = "ownerFilter", condition = "OWNER_REF = :ownerRef")public class OwnerAwareEntity implements Serializable{    @Column(name = "OWNER_REF",nullable = true)    private Long ownerRef;}

我们对此实体设置过滤器。hibernate@Filter允许我们设置要附加到select where子句的条件。

接下来,为类型OwnerAwareEntity的实体定义基础存储库

OwnerAwareRepository.java

import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.repository.NoRepositoryBean;@NoRepositoryBeanpublic interface OwnerAwareRepository<T, ID extends java.io.Serializable> extends JpaRepository<T, ID> {}

创建了一个Aspect将拦截扩展OwnerAwareRepository的存储库中的所有方法

OwnerFilterAdvisor.java

import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.hibernate.Filter;import org.hibernate.Session;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;@Aspect@Component@Slf4jpublic class OwnerFilterAdvisor {    @PersistenceContext    private EntityManager entityManager;    @Pointcut("execution(public * com.xyz.app.repository.OwnerAwareRepository+.*(..))")    protected void ownerAwareRepositoryMethod(){    }    @Around(value = "ownerAwareRepositoryMethod()")    public Object enableOwnerFilter(ProceedingJoinPoint joinPoint) throws Throwable{        // Variable holding the session        Session session = null;        try { // Get the Session from the entityManager in current persistence context session = entityManager.unwrap(Session.class); // Enable the filter Filter filter = session.enableFilter("ownerFilter"); // Set the parameter from the session filter.setParameter("ownerRef", getSessionOwnerRef());        } catch (Exception ex) { // Log the error log.error("Error enabling ownerFilter : Reason -" +ex.getMessage());        }        // Proceed with the joint point        Object obj  = joinPoint.proceed();        // If session was available        if ( session != null ) { // Disable the filter session.disableFilter("ownerFilter");        }        // Return        return obj;    }    private Long getSessionOwnerRef() {// Logic to return the ownerRef from current session    }}

顾问程序设置为拦截扩展OwnerAwareRepository的类中的所有方法。在侦听时,从(当前持久性上下文的)entityManager获取当前的hibernate会话,并使用参数值“
ownerRef”启用过滤器。

还创建一个配置文件以扫描顾问程序

import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan(basePackages = {"com.xyz.app.advisors"})public class AOPConfig {}

这些文件放置到位后,您需要对需要了解所有者的实体执行以下操作

  1. 该实体需要扩展OwnerAwareEntity
  2. 实体存储库类需要扩展OwnerAwareRepository

依存关系

此设置要求spring aop处于依赖关系中。您可以将以下内容添加到pom.xml中

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-aop</artifactId></dependency>

优点

  1. 适用于所有选择查询(findBy方法,findAll等)
  2. @Query方法也被拦截
  3. 实施简单

注意事项

  • 删除或更新的where子句不受
    此过滤器的影响。

  • 如果存储库包含一个save / update / delete方法,并且该
    方法未标记为@Transactional,则拦截器将给出
    错误信息(在这种
    情况下,您可以捕获并让方法正常进行)



转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/417590.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号