web-dev-qa-db-ja.com

パラメータープロパティを使用したSpringデータJPAクエリ

入力パラメータのプロパティをクエリパラメータとして使用する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データ/ JPAは、?1パラメータ。

最も近い代替手段は何ですか?

46
Kkkev

このリンクは、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

92
sunday

次のように、署名を使用してクエリメソッドを定義します。

@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リファレンス を確認してください。

20
CuriosMind...

あなたが望むものは不可能です。 2つのパラメーターを作成し、それらを個別にバインドする必要があります。

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

次のようなものを試すことができます:

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

インターフェイスのデフォルトのメソッドで解決することもできます:

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

もちろん、実際のリポジトリ機能はまだ公開されています...

4
mmey

jpaRepositoryを使用している場合、内部でクエリが作成されます。

サンプル

findByLastnameAndFirstname(String lastname、String firstname)

findByLastnameOrFirstname(String lastname、String firstname)

findByStartDateBetween(Date 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);
1
Mohammad

@Serviceも?あなたがそうなら、あなたは@Autowired your PersonRepository to @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);
}

また、サービスのリポジトリからメソッドを呼び出すときに、これらのパラメーターを渡すことができます。

1
Leo