2016-03-25 13 views
6

Il mio compito è effettuare una ricerca avanzata con Spring Data REST. Come posso implementarlo?Come effettuare una ricerca avanzata con Spring Data REST?

sono riuscito a fare un metodo per fare una semplice ricerca, come questo:

public interface ExampleRepository extends CrudRepository<Example, UUID>{ 

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

} 

Questo esempio funziona perfettamente se devo andare semplicemente alla url:

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

Ma cosa Devo fare se ci sono più di un campo da cercare?

Ad esempio, se la mia classe Example ha 5 campi, quale implementazione dovrei fare per effettuare una ricerca avanzata con tutti i campi possibili?

Considerate questo:

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

e questo:

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

Cosa devo fare per implementare questa ricerca in modo appropriato?

Grazie.

+1

dare uno sguardo qui https://spring.io/blog/2011/04/26/advanced-spring-data-jpa- specifications-and-querydsl/ –

+0

Trovato un modo migliore, rispetto a quello che hai iniziato? – Lemonade

+0

Dai un'occhiata alla mia risposta. –

risposta

5

L'implementazione di metodi di interrogazione ampiamente documentati in Springreferencedocumentation e tonnellate di blog tecnici, anche se un bel po 'obsoleto.

Poiché la tua domanda è probabilmente "Come posso eseguire una ricerca a più parametri con qualsiasi combinazione di campi senza dichiarare un sacco di metodi findBy *?", La risposta è Querydsl, che è supportata da Spring.

+0

Non pensare che query dsl possa essere combinata con SDR. –

+1

@ matr0s dare un'occhiata all'interfaccia [Interfaccia QueryDslPredicateExecutor] (http://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/querydsl/QueryDslPredicateExecutor.html). [Il supporto Querydsl in primavera] (https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#querydsl-support) è uscito dalla versione di Gosling di primavera. Io per primo lo uso da mesi, posso tranquillamente garantirlo per questo;) –

+0

Mai saputo che query dsl è stata integrata in SDR. Grazie mille per questo link. –

0

Credo che si può provare a seguire:

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

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

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

+1

Sì, questo è uno dei link che ho indicato nella mia precedente risposta. Fino a due parametri, questo è OK, ma con tre o più, diventa un po 'scomodo definire tutti i metodi findBy. Se i tuoi campi di ricerca sono "A", "B" e "C", ti ritroverai rapidamente: findByA, findByB, findByC, findByAAndBndnd, findByAAndB, findByAAndC, findByBAndC ... ora immagina A, B, C come variabile significativa nomi, come "nome, descrizione, createDate". –

+0

per ora sto provando qualcosa del genere: personRepo.findAll (new PersonAdvancedSearch (nome, cognome, età, ecc ...)), dove PersonAdvancedSearch implementa la Specifica . PersonAdvancedSearch esegue l'override del metodo suPredicate. Sembra funzionare, ma ho ancora problemi se l'attributo è di tipo complesso. –

+0

@AlessandroC forse crea manualmente il tuo metodo con [@Query] (http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query) l'annotazione potrebbe aiutarti a gestire meglio la ricerca sul tuo oggetto dominio. –

0

Ho trovato una soluzione di lavoro per questo compito.

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

} 

Con questa soluzione, utilizzando questo URL di base:

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

Possiamo fare ricerche avanzate con tutti i campi di cui abbiamo bisogno.

Alcuni esempi:

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

primavera dati Riposo ha integrato QueryDSL con il supporto web così che è possibile utilizzare per il vostro requisito ricerca avanzata. È necessario modificare il repository per implementare QueryDslPredicateExecutor e le cose funzioneranno immediatamente.

Ecco un esempio dalla blog articolo sulla funzione:

$ 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 
    } 
} 
Problemi correlati