2016-03-25 7 views
6

Moje zadanie polega na wyszukiwaniu zaawansowanym z REST z Spring Data. Jak mogę to wdrożyć?Jak wykonać wyszukiwanie zaawansowane za pomocą usługi Spring Data REST?

udało mi się zrobić metodę zrobić proste wyszukiwanie, jak ten jeden:

public interface ExampleRepository extends CrudRepository<Example, UUID>{ 

    @RestResource(path="searchByName", rel="searchByName") 
    Example findByExampleName(@Param("example") String exampleName); 

} 

Przykład ten doskonale sprawdza czy mam iść po prostu do URL:

.../api/examples/search/searchByName?example=myExample 

Ale co Muszę zrobić, jeśli jest więcej niż jedno pole do wyszukania?

Na przykład, jeśli moja klasa Przykład ma 5 pól, jaką implementację powinienem wykonać, aby przeprowadzić wyszukiwanie zaawansowane ze wszystkimi dostępnymi polami?

Rozważmy to jedno:

.../api/examples/search/searchByName?filed1=value1&field2=value2&field4=value4 

i ten:

.../api/examples/search/searchByName?filed1=value1&field3=value3 

Co muszę zrobić, aby wdrożyć ten wyszukiwania w odpowiedni sposób?

Dzięki.

+1

Spójrz tutaj https://spring.io/blog/2011/04/26/advanced-spring-data-jpa- specifications-and-querydsl/ –

+0

Znalazłeś lepszy sposób niż ten, z którym zacząłeś? – Lemonade

+0

Spójrz na moją odpowiedź. –

Odpowiedz

5

Wdrożenie metod zapytań w dokumentach szeroko udokumentowanych w Springreferencedocumentation i wielu blogach technicznych, choć sporo jest nieaktualnych.

Ponieważ pytanie jest prawdopodobnie „Jak mogę przeprowadzić wyszukiwanie multi-parametru z dowolnej kombinacji pól bez deklarowania strasznie dużo findBy * metodami?”, Odpowiedź jest Querydsl, który jest obsługiwany przez Spring.

+0

Nie myśl, że zapytanie dsl można połączyć z SDR. –

+1

@ matr0s przyjrzyj się interfejsowi [QueryDslPredicateExecutor] (http://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/querydsl/QueryDslPredicateExecutor.html). [Wsparcie Querydsl na wiosnę] (https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#querydsl-support) jest już dostępne od wydania Gosling wiosny. Ja na przykład używam go od miesięcy, mogę z pokorą ręczyć za to;) –

+0

Nigdy nie wiedziałem, że zapytanie dsl zostało zintegrowane z SDR. Dziękuję bardzo za ten link. –

0

Myślę, że można spróbować następujących czynności:

List<Person> findDistinctPeopleByLastnameOrFirstname(@Param("lastName")String lastname, @Param("firstName")String firstname);

i examples/search/searchByLastnameOrFirstname?firstName=value1&lastName=value2

Check out: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation

+1

Yup, to jedno z linków, które wskazałem w mojej wcześniejszej odpowiedzi. Do dwóch parametrów, to jest OK, ale z trzema lub więcej, staje się trochę niezręczne, aby zdefiniować wszystkie metody findBy. Jeśli twoje pola wyszukiwania to "A", "B" i "C", szybko otrzymujesz: findByA, findByB, findByC, findByAAndBAndC, findByAAndB, findByAAndC, findByBAndC ... teraz wyobraź sobie, że A, B, C są znaczącymi zmiennymi nazwy, takie jak "nazwa, opis, createDate". –

+0

na razie próbuję coś takiego: personRepo.findAll (new PersonAdvancedSearch (imię, nazwisko, wiek, itp.)), Gdzie PersonAdvancedSearch implementuje specyfikację . PersonAdvancedSearch zastępuje metodę toPredicate. Wydaje się działać, ale nadal mam problemy, jeśli atrybut jest złożony. –

+0

@AlessandroC może wykonać ręcznie twoją metodę za pomocą [@Query] (http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query) Adnotacja może pomóc w lepszym zarządzaniu wyszukiwaniem w obiekcie domeny. –

0

Znalazłem roztwór roboczy dla tego zadania.

@RepositoryRestResource(excerptProjection=MyProjection.class) 
public interface MyRepository extends Repository<Entity, UUID> { 

    @Query("select e from Entity e " 
      +"where (:field1='' or e.field1=:field1) " 
      +"and (:field2='' or e.field2=:field2) " 
      //... 
      +"and (:fieldN='' or e.fieldN=:fieldN) " 
    Page Entity advancedSearch(@Param("field1") String field1, 
           @Param("field2") String field2, 
           @Param("fieldN") String fieldN, 
           Pageable page); 

} 

Dzięki temu rozwiązaniu, używając tej bazy link:

http://localhost:8080/api/examples/search/advancedSearch 

Możemy dokonać zaawansowanego wyszukiwania ze wszystkich pól, które potrzebujemy.

Kilka przykładów:

http://localhost:8080/api/examples/search/advancedSearch?field1=example 
    // filters only for the field1 valorized to "example" 

http://localhost:8080/api/examples/search/advancedSearch?field1=name&field2=surname 
    // filters for all records with field1 valorized to "name" and with field2 valorized to "surname" 
4

wiosennym Danych Rest zintegrował QueryDSL z obsługą stron internetowych, jak również, które można wykorzystać do zaawansowanej wymogu wyszukiwania. Musisz zmienić swoje repozytorium, aby zaimplementować QueryDslPredicateExecutor i wszystko będzie działać po wyjęciu z pudełka.

Oto próbka z blog artykule na temat funkcji:

$ http :8080/api/stores?address.city=York  
{ 
    "_embedded": { 
     "stores": [ 
      { 
       "_links": { 
        … 
       }, 
       "address": { 
        "city": "New York", 
        "location": { "x": -73.938421, "y": 40.851 }, 
        "street": "803 W 181st St", 
        "zip": "10033-4516" 
       }, 
       "name": "Washington Hgts/181st St" 
      }, 
      { 
       "_links": { 
        … 
       }, 
       "address": { 
        "city": "New York", 
        "location": { "x": -73.939822, "y": 40.84135 }, 
        "street": "4001 Broadway", 
        "zip": "10032-1508" 
       }, 
       "name": "168th & Broadway" 
      }, 
      … 
     ] 
    }, 
    "_links": { 
     … 
    }, 
    "page": { 
     "number": 0, 
     "size": 20, 
     "totalElements": 209, 
     "totalPages": 11 
    } 
}