Подтвердить что ты не робот

Spring запрос данных JPA с параметрами

Какой самый простой способ объявить запрос JPA данных Spring, который использует свойства входного параметра в качестве параметров запроса?

Например, предположим, у меня есть класс сущности:

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.

Какая самая приятная альтернатива?

4b9b3361

Ответ 1

Эта ссылка поможет вам: Spring Данные JPA M1 с выражениями SpEL поддерживаются. Аналогичным примером будет:

@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

Ответ 2

Определите метод запроса с сигнатурами следующим образом.

@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 Ссылка на данные JPA

Ответ 3

То, что вы хотите, невозможно. Вы должны создать два параметра и связать их отдельно:

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

Ответ 4

Вы можете попробовать что-то вроде этого:

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

Ответ 5

Вы также можете решить его с помощью метода по умолчанию для интерфейса:

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

Конечно, у вас все еще будет видимая функция репозитория...

Ответ 6

Вы работаете с @Service тоже? Потому что если вы, то вы можете @Autowired ваш PersonRepository на @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);
}

и при вызове метода из репозитория в службе вы можете передать эти параметры.

Ответ 7

если мы используем 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);

Ответ 8

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

Ответ 9

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