2016-11-27 2 views
0

Так я после урока здесь: https://spring.io/guides/gs/accessing-data-jpa/Spring CommandLineRunner интерфейс Реализация

и она отлично работает, я пытаюсь реализовать его в моем приложении (Потому что это делает JPA так легко использовать), но я смущенный.

Где она имеет

@Bean 
public CommandLineRunner demo(CustomerRepository repository) 

, а затем она действует на хранилище

repository.save(new Customer("Jack", "Bauer")); 
     repository.save(new Customer("Chloe", "O'Brian")); 

Как он может действовать на интерфейсе? CustomerRepository представляет собой интерфейс, и я не могу создать его экземпляр

CustomerRepository c = new CustomerRepository() 

не может сделать, и у меня нет каких-либо классов, которые реализуют интерфейс. Я просто хотел сделать что-то вроде

CustomerRepository c = new CustomerRepository() 
c.save(new Customer("whatever", "whatever") 

но я могу использовать его только в бин-компоненте CommandLineRunner. Почему я могу сделать это с помощью commandlinerunner, но не могу сделать это с другим классом?

Я думал, что могу просто создать класс, который расширяет CustomerRepository, но затем я прочитал, что интерфейс фактически выполняет всю реализацию метода (JPA делает это), поэтому вам не нужно беспокоиться об этом.

public interface CustomerRepository extends CrudRepository<Customer, Long> { 

List<Customer> findByLastName(String lastName); 
} 

так, если я продлил его, не я должен переопределить метод findbylastname(), то есть JPA не будет делать это сам?

Спасибо за любую помощь.

+0

FWIW Ни один из них не является JPA API. Это Spring Data JPA! JPA API не имеет XXXRepository. –

ответ

0

Я расширил его, было бы не я переопределить метод findbylastname() , то есть JPA не будет делать это сам?

Нет, вам не нужно использовать методы, как весной-данных-JPA будет заботиться о нем, вы можете посмотреть here о том, как интерфейсы хранилища данных Spring фактически реализуется по доверенности во время выполнения.

Главное, что вам нужно помнить о том, что весной данные имеют несколько правил для получения sql запросов из имен методов (как findByLastName(), findByLastnameOrderByFirstnameAsc(), и т.д ..), вы можете посмотреть here, чтобы понять, как имена методов работают, и они связаны с именами полей вашего объекта bean.

Если вы хотите написать некоторые сложные запросы, которые не могут быть получены из имен методов, вы можете использовать @Query для своих методов.

Если бы я сделал публичный класс класса Касты реализуют CustomerRepository, что бы я делать, когда он спрашивает меня, я должен реализовать findByLastName (строка LastName); метод, который JPA должен принять уход?

Если вы хотите реализовать хранилище для обеспечения вашего пользовательского поведения для некоторых из методов некоторые из ваших методов, вы можете сделать это (например, класс Cust реализует CustomerRepository), вы можете обратиться к разделу «Использование JpaContext в обычае реализаций ", это хорошо объяснено в документе ref.

+0

Спасибо. Поэтому я мог бы просто использовать класс, который реализует CustomerRepository и не должен реализовывать метод, я мог бы просто назвать его? – Smithers

+0

Да, вы правы, убедитесь, что ваши имена методов правильны, то есть они должны следовать соглашениям об именах java bean, как показано выше, и в документе. – developer

+0

Так что если я сделал класс public class Cust реализует CustomerRepository Что бы я сделал, когда он спрашивает меня, мне нужно реализовать findByLastName (String lastName); метод, о котором должен заботиться JPA? – Smithers

0

так, если я продлил его, не я должен переопределить findbylastname() метод, то есть JPA не будет делать это сам?

Нет, это не JPA, которая выполняет эту работу, но Spring, которая генерирует APO некоторые обработки JPA.

С весной Repository, у вас есть кратные способы сделать:

  • написать свой собственный запрос SQL/JPQL.
  • использование именования в имени метода, чтобы написать запрос

В обоих случаях вам не нужно осуществлять непосредственно интерфейс вы заявляете здесь:

public interface CustomerRepository extends CrudRepository<Customer, Long> { 
    List<Customer> findByLastName(String lastName); 
} 

Потому что, как вы поняли, работа выполняется для вас весной.
Например, если вы указываете, вы используете соглашение об именах в имени метода для записи запроса.

Когда весна инспектирует свой интерфейс и видит метод findByLastName(String lastName), он связывает имя методы на запрос, который делает найти спичку поlastName поля. Таким образом, он генерирует запрос JPQL подобный:

select c from Customer c where c.lastName=%lastName 

и устанавливает lastName параметров с эффективным параметром, используемым при вызове методы вызова.

+0

Спасибо за объяснение этого. Мне просто интересно, есть ли способ использовать репозиторий таким же образом, как это делает CommandOpenner demo(), например, repository.save (что угодно); – Smithers

+0

Конечно, вы можете, CommandLineRunner - это только способ сделать это. Чтобы сделать это, вставьте bean-компонент, объявив '@Bean CustomerRepository repository' в любом классе, управляемом Spring (любой Spring Bean: контроллер, сервис и т. Д.), И вы можете использовать компонент репозитория и вызывать его методы – davidxxx

+0

Так объявите его как метод?Потому что просто @Bean CustomerRepository repostory; в моем контроллере указано, что для этого места запрещен bean-компонент – Smithers

Смежные вопросы