web-dev-qa-db-de.com

Wie mache ich eine erweiterte Suche mit Spring Data REST?

Meine Aufgabe ist es, eine erweiterte Suche mit Spring Data REST durchzuführen. Wie kann ich sie implementieren?

Es ist mir gelungen, eine Methode für eine einfache Suche zu erstellen, wie diese:

public interface ExampleRepository extends CrudRepository<Example, UUID>{

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

}

Dieses Beispiel funktioniert perfekt, wenn ich einfach zur URL gehen muss:

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

Aber was muss ich tun, wenn es mehr als ein Suchfeld gibt?

Wenn meine Beispielklasse beispielsweise 5 Felder hat, welche Implementierung sollte ich für eine erweiterte Suche mit allen möglichen Dateien durchführen?

Betrachten Sie diese hier:

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

und das hier:

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

Was muss ich tun, um diese Suche angemessen umzusetzen?

Vielen Dank.

11
Alessandro C

Spring Data Rest hat QueryDSL mit Web-Unterstützung integriert, die Sie für Ihre erweiterte Suchanforderung verwenden können. Sie müssen Ihr Repository ändern, um QueryDslPredicateExecutor zu implementieren, und die Dinge funktionieren sofort.

Hier ist ein Beispiel aus dem blog Artikel über die Funktion:

$ 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
    }
}
7
Faisal Feroz

Die Implementierung von Abfragemethoden ist ausführlich in SpringReferenzDokumentation und Tonnen von technischen Blogs dokumentiert, obwohl eine Menge veraltet ist.

Da Ihre Frage wahrscheinlich lautet: "Wie kann ich eine Multiparametersuche mit einer beliebigen Kombination von Feldern ausführen, ohne sehr viele findBy * -Methoden zu deklarieren?", Lautet die Antwort Querydsl , die von Frühling .

6
Marc Tarin

Ich habe eine funktionierende Lösung für diese Aufgabe gefunden.

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

}

Verwenden Sie bei dieser Lösung diese Basis-URL:

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

Wir können erweiterte Suchvorgänge mit allen erforderlichen Feldern durchführen.

Einige Beispiele:

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"
2
Alessandro C

Es ist mir gelungen, dies mit Query by Example zu implementieren.

Nehmen wir an, Sie haben folgende Modelle:

@Entity
public class Company {

  @Id
  @GeneratedValue
  Long id;

  String name;
  String address;

  @ManyToOne
  Department department;

}


@Entity
public class Department {

  @Id
  @GeneratedValue
  Long id;

  String name;

}

Und das Repository:

@RepositoryRestResource
public interface CompanyRepository extends JpaRepository<Company, Long> {
}

(Beachten Sie, dass JpaRepository implementiert QueryByExampleExecutor ).

Jetzt implementieren Sie einen benutzerdefinierten Controller:

@RepositoryRestController
@RequiredArgsConstructor
public class CompanyCustomController {

  private final CompanyRepository repository;

  @GetMapping("/companies/filter")
  public ResponseEntity<?> filter(
      Company company,
      Pageable page,
      PagedResourcesAssembler assembler,
      PersistentEntityResourceAssembler entityAssembler
  ){

    ExampleMatcher matcher = ExampleMatcher.matching()
        .withIgnoreCase()
        .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);

    Example example = Example.of(company, matcher);

    Page<?> result = this.repository.findAll(example, page);

    return ResponseEntity.ok(assembler.toResource(result, entityAssembler));

  }
}

Und dann können Sie Fragen stellen wie:

localhost:8080/companies/filter?name=google&address=NY

Sie können sogar verschachtelte Entitäten abfragen wie:

localhost:8080/companies/filter?name=google&department.name=finances

Ich habe einige Details aus Gründen der Kürze ausgelassen, aber ich habe ein Arbeitsbeispiel auf Github erstellt.

0
Jefferson Lima

Ich denke, Sie können Folgendes versuchen:

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

und 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

0