Spring Data - 如果参数为空值,则忽略该参数

时间:2017-05-04 10:22:54

标签: spring spring-boot spring-data

我想要一个带有两个参数的spring数据存储库接口。有没有办法让它有以下行为?

MyObject findByParameterOneAndParameterTwo( String parameterOne, String parameterTwo);

如果两个参数都有一个值,我希望它能正常运行并做一个" AND"对于这两个值。

例如,如果第二个参数为null,那么它将仅通过ParameterOne

进行搜索

有什么建议吗?

11 个答案:

答案 0 :(得分:20)

我不确定存储库方法命名是否可行,但您可以使用@Query之类的

(:parameterOne is null or parameter1 = :parameterOne) and (:parameterTwo is null or parameter2 = :parameterTwo)

答案 1 :(得分:10)

目前在Spring-data-jpa中无法做到这一点。

有一个JIRA ticket关于此问题,Spring小组仍在调查下。

enter image description here

但是,如果您需要解决方法,可以查看simple criteria query示例。

答案 2 :(得分:5)

尝试这个Kolobok

@FindWithOptionalParams
Iterable<MyObject> findByParameterOneAndParameterTwo( String parameterOne, String parameterTwo);

答案 3 :(得分:4)

Spring Data JPA的Query By Example功能并利用了ExampleMatcher#ignoreNullValues,该功能正是为解决此问题而构建的,这里缺少的一种解决方案。不需要 定制查询和查询生成器。

此Spring数据查询:

ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues();
Example<MyObject> exampleQuery = Example.of(new MyObject("foo", null), matcher);
List<MyObject> results = repository.findAll(exampleQuery);

产生如下查询:

select * 
from myObject 
where parameter1 = "foo"

以下内容:

ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues();
Example<MyObject> exampleQuery = Example.of(new MyObject("foo", "bar"), matcher);
List<MyObject> results = repository.findAll(exampleQuery);

收益:

select * 
from myObject 
where parameter1 = "foo"
and parameter2 = "bar"

非常酷!

注意:您必须对Repository界面做一件事是添加QueryByExample界面。您可以通过直接扩展QueryByExample接口或通过JpaRepository隐式地做到这一点:

public interface MyObjectRepository extends JpaRepository<MyObject, Long> {}

答案 4 :(得分:2)

这是这样做的方法:

@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name) and (:email is null"
      + " or c.email = :email)")
    List<Customer> findCustomerByNameAndEmail(@Param("name") String name, @Param("email") String email);

答案 5 :(得分:1)

我使用了 3 个类的 Criteria Builder

使用 JPA 的存储库接口

 @Repository
 public interface NotificationRepository extends JpaRepository<Notification, 
 Long>, NotificationRepositoryCustom {
}

自定义界面

public interface NotificationRepositoryCustom {

    List<Notification> findNotificationByCustomerIdAndRecipientAndNotificationAckStatusAndNotificationRequestChannel
            (Long customerId, String userId, List<String> status, List<String> channels);
}

NotificationRepositoryCustom 的实现

public class NotificationRepositoryCustomImpl implements NotificationRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Notification> findNotificationByCustomerIdAndRecipientAndNotificationAckStatusAndNotificationRequestChannel(Long customerId, String userId, List<String> status, List<String> channels) {

        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Notification> query = cb.createQuery(Notification.class);
        Root<Notification> notification = query.from(Notification.class);


        List<Predicate> predicates = new ArrayList<Predicate>();
        if (userId != null)
            predicates.add(cb.equal(notification.get("recipient"), userId));
        if (customerId != null)
            predicates.add(cb.equal(notification.get("customerId"), customerId));
        if (CollectionUtils.isNotEmpty(status))
            predicates.add(notification.get("notificationAckStatus").get("ackStatusCode").in(status));
        if (CollectionUtils.isNotEmpty(channels))
            predicates.add(notification.get("notificationRequestChannel").get("notificationChannel").get("channelCode").in(channels));


        if (!predicates.isEmpty()) {
            query
                    .select(notification)
                    .where(cb.and(
                            predicates.toArray(new Predicate[predicates.size()])));

        }
        return entityManager.createQuery(query).getResultList();
    }
}

答案 6 :(得分:1)

  1. JPA 查询
@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name)")
  1. JPA 查询(nativeQuery = true)
@Query(nativeQuery = true, "SELECT id, name FROM Customer c WHERE (false = :nameOn OR name = :name)")
    List<Entity> findAll(@Param(value = "nameOn") Boolean nameOn, @Param(value = "name ") String name);
  • 如果名称为空,nativeQuery 需要将名称更改为 EMPTY 字符串。

答案 7 :(得分:0)

我是Spring / JPA领域的新手,

使用“示例查询”

我正在使用(在seviceImp中),以下所有参数都是可选的,取决于用户的选择

`
  .
    if (!firstName.isEmpty() ) {
    staff.setFirstName(firstName);
    }



    if (!lastName.isEmpty() ) {
    staff.setLastName(lastName);
    }

    if (!ptAadhar.isEmpty() ) {
        patient.setPtAadhar(ptAadhar);
    }

    if (!Cell.isEmpty() ) {
        staff.setCell(Cell);
    }


      Example<StaffEntity> example = Example.of(staff);  

      List<StaffEntity> staffList =staffRepository.findAll(example);
       .

答案 8 :(得分:0)

尝试一下,

      @Query(value = "SELECT pr FROM ABCTable pr " +
        "WHERE((pr.parameterOne = :parameterOne) or (pr.parameterOne = null and :parameterOne = null)) and 
        ((pr.parameterTwo = :parameterTwo) or (pr.parameterTwo = null and :parameterTwo = null)) ")
      List<PaymentRequest> getSomething (@Param("parameterOne") String parameterOne,
                                             @Param("parameterTwo") String parameterTwo);

答案 9 :(得分:-1)

我不确定它是否可以使用Repo作为单独的类,但您可以使用StringBuilder追加查询和option参数。这肯定会有用

 StringBuilder queryBuilder = new StringBuilder();
    queryBuilder.append("select p.name from personDemographic p "); 
    Boolean flag = true;
    if(parameterOne != null){
      if(flag){
          queryBuilder.append("where condition...");
            flag=false;
        } 
      }
    if(parameterOne != null){
    if(flag){
     queryBuilder.append("where condition...");
     flag = false;
    }else{
      queryBuilder.append("and condition...");
    }
   Query query = entityManager.createQuery(queryBuilder.toString());

答案 10 :(得分:-1)

您也可以这样做。

存储库:

`MyObject findByParameterOneAndParameterTwo( String parameterOne, String parameterTwo);`

如果传递空参数Two,则生成的JPQL将包含IS NULL条件:

`myobject0_.parameterTwo is null`

例如:repository.findByParameterOneAndParameterTwo("D", null);

参考:https://www.baeldung.com/spring-data-jpa-null-parameters#query-methods