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

Какой самый простой способ объявить запрос 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 параметр.

What is the neatest alternative? }

 Tulio F.29 мая 2012 г., 18:43
Это должно быть динамично? Почему вы не можете просто добавитьName таблица после заявления от?
 Kkkev29 мая 2012 г., 18:53
Name не обязательно является сущностью.

Ответы на вопрос(9)

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

если мы используем JpaRepository, то он будет внутренне создавать запросы.

Sample

findByLastnameAndFirstname(String lastname,String firstname)

findByLastnameOrFirstname(String lastname,String firstname)

findByStartDateBetween(Date date1,Date2)

findById(int id)

Note

если предположим, что нам нужны сложные запросы, то нам нужно написать ручные запросы, такие как

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

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

select p from Person p where p.forename = :forename and p.surname = :surname
...
query.setParameter("forename", name.getForename());
query.setParameter("surname", name.getSurname());
 Kkkev30 мая 2012 г., 09:53
Предположительно, это должно быть реализовано в пользовательском методе хранилища согласноstatic.springsource.org/spring-data/data-jpa/docs/current/…?
 30 мая 2012 г., 10:26
Я знаю, как работает JPA, но я не знаю, что данные Spring делают для вас и что вы должны делать сами. Сожалею.

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

@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

 Kkkev02 июн. 2014 г., 13:23
Это не отвечает на вопрос. Уместным является то, что я хотел бы использовать свойства входного параметра в качестве параметров запроса, а не отдельные входные параметры.
 04 июн. 2014 г., 15:52
К сожалению, я неправильно прочитал ваш запрос. Я считаю, что поддержка Spring Data JPA не предоставляется (возможно, даже JDBC не может; я могу ошибаться здесь). В качестве другой альтернативы (кроме подхода к пользовательскому репозиторию) вы можете написать метод-обертку службы, который принимает объект Person в качестве параметра и передает соответствующие параметры в метод репозитория. Преимущество этого подхода заключается в том, что ожидаемая подпись (передать объект Person) не повреждена, а также вы используете реализацию, предоставленную Spring Data JPA.
Решение Вопроса

Эта ссылка поможет вам: Spring Data 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

 19 мая 2017 г., 15:28
Он работает с POJO.
 14 мая 2015 г., 17:58
это spring-data-jpa 1.7.2 + и требует весны 4
 02 сент. 2016 г., 17:42
Я не пытался использовать pojo, я могу подтвердить, что это работает по крайней мере с сущностями. Кто-то еще упомянул, что они столкнулись с проблемами, если они включают как объект, так и дополнительные аргументы (см. Комментарии здесь) -spring.io/blog/2014/07/15/…
 15 мар. 2016 г., 17:11
Кажется, что клиент здесь должен быть организацией, оценка POJO не работает для меня.
 02 сент. 2016 г., 20:32
И я могу подтвердить, что у меня та же проблема, даже с пружинной загрузкой 1.4 / пружиной 4 / пружиной данных jpa 1.10 -

Вы работаете с@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);
}

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

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

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

Конечно, у вас по-прежнему есть публично видимая фактическая функция хранилища ...

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

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);
    }
 04 дек. 2017 г., 13:04
@ Kkkev верно, вам нужно сделать Name Entity для этого решения
 Kkkev13 нояб. 2015 г., 21:17
Имя не является сущностью, поэтому это не работает.

Ваш ответ на вопрос