程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了在Spring Data JPA存储库方法查询上附加自定义条件大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决在Spring Data JPA存储库方法查询上附加自定义条件?

开发过程中遇到在Spring Data JPA存储库方法查询上附加自定义条件的问题如何解决?下面主要结合日常开发的经验,给出你关于在Spring Data JPA存储库方法查询上附加自定义条件的解决方法建议,希望对你解决在Spring Data JPA存储库方法查询上附加自定义条件有所启发或帮助; @H_419_0@ 我使用了Hibernate的@Filter,然后创建了一个Aspect来拦截方法

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

@H_419_0@

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;

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

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

@H_419_0@

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.norepositoryBean;

@norepositoryBean
public interface ownerAwareRepository<T, ID extends java.io.serializable> extends JpaRepository<T, ID> {

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

@H_419_0@

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
@Slf4j
public 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

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

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

import org.springframework.context.Annotation.ComponentScan;
import org.springframework.context.Annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {"com.xyz.app.advisors"})
public class AOPConfig {
}
@H_419_0@这些文件放置到位后,您需要对需要了解所有者的实体执行以下操作

  1. 该实体需要扩展ownerAwareEntity
  2. 实体存储库类需要扩展ownerAwareRepository
@H_419_0@

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

<dependency>
    <groupID>org.springframework.boot</groupID>
    <artifactID>spring-boot-starter-aop</artifactID>
</dependency>
@H_419_0@

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

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

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

解决方法

简洁版本

我正在寻找一种将存储库类的所有findBy方法附加特定条件的方法

完整版

假设我有一个Product实体和一个Customer实体。它们都扩展了ownerAwareEntity,并且它们都继承了ownerRef字段,该字段标识实体的所有者(它可以是商人或合作伙伴)。我想在运行时修改Product和Customer的findBy方法,以便将它们附加有ownerRef的附加条件。可以从用户会话中识别ownerRef值。

提供公共ownerRef字段的父实体类

public class ownerAwareEntity implements serializable {

 private String ownerRef;

}

扩展ownerAwareEntity的客户实体

public class Customer extends ownerAwareEntity {

  private String firstname;

  private String mobile ;

}

扩展ownerAwareEntity的产品实体

public class Product extends ownerAwareEntity {

  private String code;

  private String name;

}

产品和客户的存储库类,用于扩展ownerAwareRepository

public interface ownerAwareRepository extends JpaRepository {

}

public interface ProductRepository extends ownerAwareRepository {

  Product findByCode(String code );

}

public interface CustomerRepository extends ownerAwareRepository {

  Customer findByFirstname(String firstname );

}

当执行时,这将导致如下查询

SELEct P from Product P where P.code=?1 and P.ownerRef='aValue'
&
SELEct C from Customer C where C.firstname=?1 and C.ownerRef='aValue'

要实现这种条件附加,我应该采取什么方法?我只希望在父存储库为ownerAwareRepository时进行此追加。

大佬总结

以上是大佬教程为你收集整理的在Spring Data JPA存储库方法查询上附加自定义条件全部内容,希望文章能够帮你解决在Spring Data JPA存储库方法查询上附加自定义条件所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。