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

37

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

Это должно быть динамично? Почему вы не можете просто добавитьName таблица после заявления от? Tulio F.
Name не обязательно является сущностью. Kkkev

Ваш Ответ

9   ответов
-2
    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);
10

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

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

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

@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

Это не отвечает на вопрос. Уместным является то, что я хотел бы использовать свойства входного параметра в качестве параметров запроса, а не отдельные входные параметры. Kkkev
К сожалению, я неправильно прочитал ваш запрос. Я считаю, что поддержка Spring Data JPA не предоставляется (возможно, даже JDBC не может; я могу ошибаться здесь). В качестве другой альтернативы (кроме подхода к пользовательскому репозиторию) вы можете написать метод-обертку службы, который принимает объект Person в качестве параметра и передает соответствующие параметры в метод репозитория. Преимущество этого подхода заключается в том, что ожидаемая подпись (передать объект Person) не повреждена, а также вы используете реализацию, предоставленную Spring Data JPA.
-2
@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();
    }
74

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

И я могу подтвердить, что у меня та же проблема, даже с пружинной загрузкой 1.4 / пружиной 4 / пружиной данных jpa 1.10 -
Кажется, что клиент здесь должен быть организацией, оценка POJO не работает для меня.
Он работает с POJO.
это spring-data-jpa 1.7.2 + и требует весны 4
Я не пытался использовать pojo, я могу подтвердить, что это работает по крайней мере с сущностями. Кто-то еще упомянул, что они столкнулись с проблемами, если они включают как объект, так и дополнительные аргументы (см. Комментарии здесь) -spring.io/blog/2014/07/15/…
1

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

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

0

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

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

 @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

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

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

Похожие вопросы