Siirry pääsisältöön

Tietojen kysely 25.02

Avaa ChatGPT:ssä

QueryableRepository -rajapinta laajentaa Repository -toimintoa tarjoamalla edistyneitä kyselymahdollisuuksia RepositoryCriteria -luokan kautta. Toisin kuin perusrekisterit, jotka tukevat vain yksinkertaista suodatusta, kyselyrekisterit tarjoavat jäsenneltyjä kyselyitä mukautettujen suodatin tyyppien, lajittelun ja sivutuksen avulla.

Suodatin tyyppien ymmärtäminen

QueryableRepository esittelee toisen geneerisen parametrin suodatin tyyppille: QueryableRepository<T, F> missä T on entiteettisi tyyppi ja F on mukautettu suodatin tyyppi.

Tämä erottelu on olemassa, koska eri tietolähteet käyttävät erilaisia kyselykieliä:

// Ennustepohjaiset suodattimet muistissa oleville kokoelmille
QueryableRepository<Product, Predicate<Product>> inMemoryRepo =
new CollectionRepository<>(products);

// Mukautetut suodatinobjektit REST-rajapinnoille tai tietokannoille
QueryableRepository<User, UserFilter> apiRepo =
new DelegatingRepository<>(/* toteutus */);

// Merkkijonokyselyt hakukoneille
QueryableRepository<Document, String> searchRepo =
new DelegatingRepository<>(/* toteutus */);

CollectionRepository käyttää Predicate<Product> koska se suodattaa Java-objekteja muistissa. REST API -rekisteri käyttää UserFilter -luokkaa, jossa on kenttiä kuten department ja status, jotka vastaavat kyselyparametreja. Hakurepository käyttää yksinkertaisia merkkijonoja täysimittaisten kyselyjen suorittamiseen.

Käyttöliittymäkomponentit eivät välitä näistä eroista. Ne kutsuvat setBaseFilter() -menetelmää millä tahansa suotimen tyypillä, jota rekisteri odottaa, ja rekisteri käsittelee käännöksen.

Kyselyiden rakentaminen rekisterikriteerien avulla

RepositoryCriteria kokoaa kaikki kyselyparametrit yhdeksi muuttumattomaksi objektiksi. Sen sijaan, että kutsuisit erillisiä metodeja suodatin, lajittelu ja sivutus, annat kaiken kerralla:

// Täydellinen kysely kaikilla parametreilla
RepositoryCriteria<Product, Predicate<Product>> criteria =
new RepositoryCriteria<>(
20, // offset - ohita ensimmäiset 20
10, // limit - ota 10 kohdetta
orderCriteria, // lajittelusäännöt
product -> product.getPrice() < 100.0 // suodatin ehto
);

// Suorita kysely
Stream<Product> results = repository.findBy(criteria);
int totalMatching = repository.size(criteria);

findBy() -metodi suorittaa täydellisen kyselyn - se soveltaa suodatinta, lajittelee tulokset, ohittaa offsetin ja ottaa limitin. size() -metodi laskee kaikki kohteet, jotka vastaavat suodatinta, unohtaen sivutuksen.

Voit myös luoda kriteerejä vain niillä osilla, joita tarvitset:

// Vain suodatin
RepositoryCriteria<Product, Predicate<Product>> filterOnly =
new RepositoryCriteria<>(product -> product.isActive());

// Vain sivutus
RepositoryCriteria<Product, Predicate<Product>> pageOnly =
new RepositoryCriteria<>(0, 25);

Eri suodatin tyyppien kanssa työskentely

Ennustepohjaiset suodattimet

Muistissa oleville kokoelmille käytä Predicate<T> -menetelmää koostamaan toiminnallisia suodattimia:

CollectionRepository<Product> repository = new CollectionRepository<>(products);

// Rakenna monimutkaisia ennusteita
Predicate<Product> activeProducts = product -> product.isActive();
Predicate<Product> inStock = product -> product.getStock() > 0;
Predicate<Product> affordable = product -> product.getPrice() < 50.0;

// Yhdistä ehdot
repository.setBaseFilter(activeProducts.and(inStock).and(affordable));

// Dynaaminen suodatus
Predicate<Product> filter = product -> true;
if (categoryFilter != null) {
filter = filter.and(p -> p.getCategory().equals(categoryFilter));
}
if (maxPrice != null) {
filter = filter.and(p -> p.getPrice() <= maxPrice);
}
repository.setBaseFilter(filter);

Mukautetut suodatinobjektit

Ulkopuoliset tietolähteet eivät voi suorittaa Java-ennusteita. Sen sijaan luot suodatinluokkia, jotka edustavat sitä, mitä taustajärjestelmäsi voi etsiä:

public class ProductFilter {
private String category;
private BigDecimal maxPrice;
private Boolean inStock;

// getterit ja setterit...
}

// käytetään mukautetun rekisterin kanssa
ProductFilter filter = new ProductFilter();
filter.setCategory("Elektroniikka");
filter.setMaxPrice(new BigDecimal("99.99"));
filter.setInStock(true);

RepositoryCriteria<Product, ProductFilter> criteria =
new RepositoryCriteria<>(filter);

Stream<Product> results = customRepository.findBy(criteria);

Mukautetun rekisterin findBy() -metodissa kääntelet tämän suodatinobjektin:

  • REST-rajapinnoille: Muunna kyselyparametreiksi kuten ?category=Elektroniikka&maxPrice=99.99&inStock=true
  • SQL: Luo where-ehto kuten WHERE category = ? AND price <= ? AND stock > 0
  • GraphQL: Rakenna kysely asianmukaisilla kenttävalinnoilla

Repository -toteutuksen tulisi käsitellä tämä käännös, pitäen käyttöliittymäkoodisi puhtaana.

Tietojen lajittelu

OrderCriteria määrittelee, kuinka lajittelet tietosi. Jokaisella OrderCriteria -tavalla on arvotoimittaja (kuinka saada arvo entiteetistäsi) ja suunta:

// Yksittäisen kentän lajittelu
OrderCriteria<Employee, String> byName =
new OrderCriteria<>(Employee::getName, OrderCriteria.Direction.ASC);

// Monitasoinen lajittelu - ensin osasto, sitten palkka, sitten nimi
OrderCriteriaList<Employee> sorting = new OrderCriteriaList<>();
sorting.add(new OrderCriteria<>(Employee::getDepartment, OrderCriteria.Direction.ASC));
sorting.add(new OrderCriteria<>(Employee::getSalary, OrderCriteria.Direction.DESC));
sorting.add(new OrderCriteria<>(Employee::getName, OrderCriteria.Direction.ASC));

// Käytä kriteereissä
RepositoryCriteria<Employee, Predicate<Employee>> criteria =
new RepositoryCriteria<>(0, 50, sorting, employee -> employee.isActive());

Arvotoimittaja (Employee::getName) toimii muistissa lajittelussa. Mutta ulkoiset tietolähteet eivät voi suorittaa Java-funktioita. Näissä tapauksissa OrderCriteria hyväksyy ominaisuuden nimen:

// Ulkoisia rekisterejä varten - tarjoa sekä arvon hakija että ominaisuuden nimi
OrderCriteria<Employee, String> byName = new OrderCriteria<>(
Employee::getName, // Muistissa lajittelua varten
Direction.ASC,
null, // Mukautettu vertailija (valinnainen)
"name" // Ominaisuuden nimi taustajärjestelmää varten
);

CollectionRepository käyttää arvotoimittajaa lajittelemassa Java-objekteja. DelegatingRepository -toteutukset voivat käyttää ominaisuuden nimeä rakennettaessa järjestyslausekkeita SQL:ssä tai sort=name:asc REST-rajapinnoissa.

Sivutuksen hallinta

Aseta offset ja limit hallitaksesi, mikä tietojen osa ladataan:

// Sivupohjainen sivutus
int page = 2; // nollapohjainen sivunumero
int pageSize = 20; // kohteet per sivu
int offset = page * pageSize;

RepositoryCriteria<Product, Predicate<Product>> criteria =
new RepositoryCriteria<>(offset, pageSize, null, yourFilter);

// Progressiivinen lataaminen - lataa lisää tietoa asteittain
int currentlyLoaded = 50;
int loadMore = 25;

repository.setOffset(0);
repository.setLimit(currentlyLoaded + loadMore);