我想要一个带有两个参数的spring数据存储库接口。有没有办法让它有以下行为?
MyObject findByParameterOneAndParameterTwo( String parameterOne, String parameterTwo);
如果两个参数都有一个值,我希望它能正常运行并做一个" AND"对于这两个值。
例如,如果第二个参数为null,那么它将仅通过ParameterOne
进行搜索有什么建议吗?
答案 0 :(得分:20)
我不确定存储库方法命名是否可行,但您可以使用@Query
之类的
(:parameterOne is null or parameter1 = :parameterOne) and (:parameterTwo is null or parameter2 = :parameterTwo)
答案 1 :(得分:10)
目前在Spring-data-jpa
中无法做到这一点。
有一个JIRA
ticket关于此问题,Spring
小组仍在调查下。
但是,如果您需要解决方法,可以查看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)
@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name)")
@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);
答案 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