94

声明使用输入参数的属性作为查询参数的 Spring 数据 JPA 查询的最简单方法是什么?

例如,假设我有一个实体类:

public class Person {
    @Id
    private long id;

    @Column
    private String forename;

    @Column
    private String surname;
}

和另一个类:

public class Name {
    private String forename;
    private String surname;

    [constructor and getters]
}

...然后我想编写一个Spring数据存储库,如下所示:

public interface PersonRepository extends CrudRepository<Person, Long> {
    @Query("select p from Person p where p.forename = ?1.forename and p.surname = ?1.surname")
    findByName(Name name);
}

...但是 Spring data / JPA 不喜欢我在?1参数上指定属性名称。

什么是最整洁的选择?

4

10 回答 10

203

此链接将为您提供帮助:支持 SpEL 表达式的 Spring Data JPA M1。类似的例子是:

@Query("select u from User u where u.firstname = :#{#customer.firstname}")
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);

https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions

于 2015-03-11T17:48:30.203 回答
23

使用签名定义查询方法,如下所示。

@Query(select p from Person p where p.forename = :forename and p.surname = :surname)
User findByForenameAndSurname(@Param("surname") String lastname,
                             @Param("forename") String firstname);
}

有关更多详细信息,请查看Spring Data JPA 参考

于 2014-06-02T05:42:38.087 回答
10

你想要的是不可能的。您必须创建两个参数,并分别绑定它们:

select p from Person p where p.forename = :forename and p.surname = :surname
...
query.setParameter("forename", name.getForename());
query.setParameter("surname", name.getSurname());
于 2012-05-29T17:14:45.107 回答
9

您也可以使用接口默认方法解决它:

 @Query(select p from Person p where p.forename = :forename and p.surname = :surname)
User findByForenameAndSurname(@Param("surname") String lastname,
                         @Param("forename") String firstname);

default User findByName(Name name) {
  return findByForenameAndSurname(name.getLastname(), name.getFirstname());
}

当然,您仍然可以公开看到实际的存储库功能......

于 2017-12-22T11:47:22.793 回答
8

你可以尝试这样的事情:

public interface PersonRepository extends CrudRepository<Person, Long> {
       @Query("select p from Person AS p"
       + " ,Name AS n"  
       + " where p.forename = n.forename "
       + " and p.surname = n.surname"
       + " and n = :name")
       Set<Person>findByName(@Param("name") Name name);
    }
于 2015-11-13T16:04:12.490 回答
2

如果我们使用 JpaRepository,那么它将在内部创建查询。

样本

findByLastnameAndFirstname(字符串姓氏,字符串名字)

findByLastnameOrFirstname(字符串姓氏,字符串名字)

findByStartDateBetween(日期 date1,Date2)

findById(int id)

笔记

如果假设我们需要复杂的查询,那么我们需要编写手动查询,例如

@Query("SELECT salesOrder FROM SalesOrder salesOrder WHERE salesOrder.clientId=:clientId AND salesOrder.driver_username=:driver_username AND salesOrder.date>=:fdate AND salesOrder.date<=:tdate ")
 @Transactional(readOnly=true)
 List<SalesOrder> findAllSalesByDriver(@Param("clientId")Integer clientId, @Param("driver_username")String driver_username, @Param("fdate") Date fDate, @Param("tdate") Date tdate);
于 2017-09-25T08:55:38.030 回答
1

你也在和a一起工作@Service吗?因为如果您是,那么您可以@AutowiredPersonRepository服务@Service中调用Name该类并使用@CuriosMind ... 建议的形式:

@Query(select p from Person p where p.forename = :forename and p.surname = :surname)
User findByForenameAndSurname(@Param("surname") String lastname,
                         @Param("forename") String firstname);
}

并且当从服务中的存储库调用方法时,您可以传递这些参数。

于 2016-05-10T20:30:11.807 回答
0

Spring Data JPA 的简单性在于它尝试从存储库中的函数名称进行解释,而无需指定任何额外的 @Query 或 @Param 注释。如果您提供完整名称,请尝试将其分解为名字和姓氏,然后使用类似这样的内容 -

HotelEntity findByName(String name);

我的 HotelEntity 确实包含字段名称,因此 JPA 尝试自行解释以推断我尝试查询的字段的名称并在内部创建后续查询。来自 JPA 文档的更多证据 - 在此处输入图像描述

更多细节 -这里

于 2021-05-16T03:09:51.467 回答
-3
    for using this, you can create a Repository for example this one:
    Member findByEmail(String email);

    List<Member> findByDate(Date date);
    // custom query example and return a member
   @Query("select m from Member m where m.username = :username and m.password=:password")
        Member findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
于 2018-05-20T22:03:03.750 回答
-5
@Autowired
private EntityManager entityManager;

@RequestMapping("/authors/{fname}/{lname}")
    public List actionAutherMulti(@PathVariable("fname") String fname, @PathVariable("lname") String lname) {
        return entityManager.createQuery("select A from Auther A WHERE A.firstName = ?1 AND A.lastName=?2")
                .setParameter(1, fname)
                .setParameter(2, lname)
                .getResultList();
    }
于 2017-11-04T09:40:35.650 回答