带有参数属性的 Spring 数据 JPA 查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10802798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:08:33  来源:igfitidea点击:

Spring data JPA query with parameter properties

springjpaspring-dataspring-data-jpa

提问by Kkkev

What is the simplest way of declaring a Spring data JPA query that uses properties of an input parameter as query parameters?

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

For example, suppose I have an entity class:

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

public class Person {
    @Id
    private long id;

    @Column
    private String forename;

    @Column
    private String surname;
}

and another class:

和另一个类:

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

    [constructor and getters]
}

... then I would like to write a Spring data repository as follows:

...然后我想写一个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);
}

... but Spring data / JPA doesn't like me specifying property names on the ?1parameter.

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

What is the neatest alternative?

什么是最简洁的选择?

回答by sunday

This link will help you: Spring Data JPA M1 with SpEL expressions supported. The similar example would be:

此链接将帮助您:支持 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

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

回答by CuriosMind...

Define the query method with signatures as follows.

定义带有签名的查询方法如下。

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

For further details, check the Spring Data JPA reference

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

回答by JB Nizet

What you want is not possible. You have to create two parameters, and bind them separately:

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

select p from Person p where p.forename = :forename and p.surname = :surname
...
query.setParameter("forename", name.getForename());
query.setParameter("surname", name.getSurname());

回答by Casi

You can try something like this:

你可以尝试这样的事情:

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);
    }

回答by mmey

You could also solve it with an interface default method:

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

 @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());
}

Of course you'd still have the actual repository function publicly visible...

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

回答by Mohammad

if we are using JpaRepository then it will internally created the queries.

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

Sample

样本

findByLastnameAndFirstname(String lastname,String firstname)

findByLastnameOrFirstname(String lastname,String firstname)

findByStartDateBetween(Date date1,Date2)

findById(int id)

findByLastnameAndFirstname(String lastname,String firstname)

findByLastnameOrFirstname(String lastname,String firstname)

findByStartDateBetween(Date date1,Date2)

findById(int id)

Note

笔记

if suppose we need complex queries then we need to write manual queries like

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

@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);

回答by Leo

Are you working with a @Servicetoo? Because if you are, then you can @Autowiredyour PersonRepositoryto the @Serviceand then in the service just invoke the Nameclass and use the form that @CuriosMind... proposed:

你也在工作@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);
}

and when invoking the method from the repository in the service, you can then pass those parameters.

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

回答by KIBOU Hassan

    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);

回答by Ram Pukar

@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();
    }