REST dotazovací jazyk s jarnými a JPA kritériami
Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:
>> SKONTROLUJTE KURZ Tento článok je súčasťou série: • REST dotazovací jazyk s jarnými a JPA kritériami (aktuálny článok) • REST dotazovací jazyk s jarnými údajmi JPA špecifikácie• REST dotazovací jazyk s Spring Data JPA a Querydsl
• REST Query Language - Pokročilé vyhľadávacie operácie
• REST Query Language - implementácia ALEBO prevádzka
• REST dotazovací jazyk s RSQL
• REST Query Language s webovou podporou Querydsl
1. Prehľad
V tomto prvom článku tejto novej série to preskúmame jednoduchý dotazovací jazyk pre REST API. Jar dobre využijeme pre REST API a kritériá JPA 2 pre aspekty perzistencie.
Prečo dopytovací jazyk? Pretože - pre akékoľvek dostatočne zložité API - vyhľadávanie / filtrovanie vašich zdrojov podľa veľmi jednoduchých polí jednoducho nestačí. Dotazovací jazyk je flexibilnejší a umožňuje vám filtrovať presne také zdroje, aké potrebujete.
2. Používateľ Subjekt
Najprv - poďme predstaviť jednoduchú entitu, ktorú použijeme pre naše API filtrovania / vyhľadávania - základ Používateľ:
@Entity verejná trieda Používateľ {@Id @GeneratedValue (strategy = GenerationType.AUTO) private Long id; private String meno; private String priezvisko; súkromný reťazcový e-mail; súkromný int vek; }
3. Filtrovať pomocou CriteriaBuilder
Teraz - poďme na podstatu problému - dotaz vo vrstve vytrvalosti.
Vytvorenie abstrakcie dotazu je vecou rovnováhy. Na jednej strane potrebujeme dostatočnú flexibilitu a na druhej strane musíme udržiavať zvládnuteľnosť zložitosti. Vysoká úroveň, funkčnosť je jednoduchá - splníte určité obmedzenia a získate späť nejaké výsledky.
Pozrime sa, ako to funguje:
@Repository verejná trieda UserDAO implementuje IUserDAO {@PersistenceContext private EntityManager entityManager; @Override public List searchUser (Zoznam parametrov) {CriteriaBuilder builder = entityManager.getCriteriaBuilder (); CriteriaQuery query = builder.createQuery (User.class); Root r = query.from (User.class); Predikát predikát = builder.conjunction (); UserSearchQueryCriteriaConsumer searchConsumer = nový UserSearchQueryCriteriaConsumer (predikát, staviteľ, r); params.stream (). forEach (searchConsumer); predicate = searchConsumer.getPredicate (); dotaz.kde (predikát); Výsledok zoznamu = entityManager.createQuery (dotaz) .getResultList (); návratový výsledok; } @Override public void save (entita používateľa) {entityManager.persist (entita); }}
Poďme sa pozrieť na UserSearchQueryCriteriaConsumer trieda:
verejná trieda UserSearchQueryCriteriaConsumer implementuje Consumer {private Predicate predicate; súkromný tvorca CriteriaBuilder; súkromný Koreň r; @Override public void accept (SearchCriteria param) {if (param.getOperation (). EqualsIgnoreCase (">")) {predicate = builder.and (predicate, builder .greaterThanOrEqualTo (r.get (param.getKey ()), param .getValue (). toString ())); } else if (param.getOperation (). equalsIgnoreCase ("<")) {predicate = builder.and (predicate, builder.lessThanOrEqualTo (r.get (param.getKey ()), param.getValue (). toString () )); } else if (param.getOperation (). equalsIgnoreCase (":")) {if (r.get (param.getKey ()). getJavaType () == String.class) {predicate = builder.and (predicate, builder .like (r.get (param.getKey ()), "%" + param.getValue () + "%")); } else {predikát = builder.and (predikát, builder.equal (r.get (param.getKey ()), param.getValue ())); }}} // štandardný konštruktor, getter, setter}
Ako vidíte, searchUser API vezme zoznam veľmi jednoduchých obmedzení, na základe týchto obmedzení vytvorí dotaz, vykoná vyhľadávanie a vráti výsledky.
Trieda obmedzenia je tiež celkom jednoduchá:
public class SearchCriteria {private String key; súkromná prevádzka reťazca; hodnota súkromného objektu; }
The Kritériá vyhľadávania implementácia drží naše Dopyt parametre:
- kľúč: slúži na uchovanie názvu poľa - napríklad: krstné meno, Vek, … atď.
- prevádzka: používa sa na vykonanie operácie - napríklad: Rovnosť, menej ako, ... atď.
- hodnotu: slúži na uchovanie hodnoty poľa - napríklad: john, 25, ... atď.
4. Vyskúšajte vyhľadávacie dotazy
Teraz - otestujme náš vyhľadávací mechanizmus, aby sme sa uistili, že drží vodu.
Najprv - inicializujme našu databázu na testovanie pridaním dvoch používateľov - ako v nasledujúcom príklade:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = {PersistenceConfig.class}) @Transactional @TransactionConfiguration verejná trieda JPACriteriaQueryTest {@Autowired private IUserDAO userApi; súkromný používateľ userJohn; súkromný používateľ userTom; @ Pred public void init () {userJohn = nový používateľ (); userJohn.setFirstName ("John"); userJohn.setLastName ("Laň"); userJohn.setEmail ("[chránený e-mailom]"); userJohn.setAge (22); userApi.save (userJohn); userTom = nový užívateľ (); userTom.setFirstName ("Tom"); userTom.setLastName ("Srnka"); userTom.setEmail ("[chránený e-mailom]"); userTom.setAge (26); userApi.save (userTom); }}
Teraz poďme Používateľ s konkrétnym krstné meno a priezvisko - ako v nasledujúcom príklade:
@Test public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (new SearchCriteria ("firstName", ":", "John")); params.add (new SearchCriteria ("lastName", ":", "Doe")); Zoznam výsledkov = userApi.searchUser (parametre); assertThat (userJohn, isIn (výsledky)); assertThat (userTom, nie (isIn (výsledky))); }
Ďalej poďme Zoznam z Používateľ s tým istým priezvisko:
@Test public void givenLast_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (new SearchCriteria ("lastName", ":", "Doe")); Zoznam výsledkov = userApi.searchUser (parametre); assertThat (userJohn, isIn (výsledky)); assertThat (userTom, isIn (výsledky)); }
Ďalej poďme používateľov získať Vekväčšie alebo rovné 25:
@Test public void givenLastAndAge_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (new SearchCriteria ("lastName", ":", "Doe")); params.add (new SearchCriteria ("age", ">", "25")); Zoznam výsledkov = userApi.searchUser (parametre); assertThat (userTom, isIn (výsledky)); assertThat (userJohn, nie (isIn (results))); }
Ďalej hľadajme používateľov vlastne neexistujú:
@Test public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (new SearchCriteria ("firstName", ":", "Adam")); params.add (new SearchCriteria ("lastName", ":", "Fox")); Zoznam výsledkov = userApi.searchUser (parametre); assertThat (userJohn, nie (isIn (results))); assertThat (userTom, nie (isIn (výsledky))); }
Na záver vyhľadajme iba zadaných používateľov čiastočnékrstné meno:
@Test public void givenPartialFirst_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (new SearchCriteria ("firstName", ":", "jo")); Zoznam výsledkov = userApi.searchUser (parametre); assertThat (userJohn, isIn (výsledky)); assertThat (userTom, nie (isIn (výsledky))); }
6. UserController
Na záver poďme teraz zapojiť podporu vytrvalosti pre toto flexibilné vyhľadávanie do nášho REST API.
Budeme nastavovať jednoduchý UserController - s findAll ()pomocou „Vyhľadávanie”Na odovzdanie celého výrazu vyhľadávania / filtra:
@Controller verejná trieda UserController {@Autowired private IUserDao api; @RequestMapping (method = RequestMethod.GET, value = "/ users") @ResponseBody public List findAll (@RequestParam (value = "search", required = false) String search) {List params = new ArrayList (); if (search! = null) {Pattern pattern = Pattern.compile ("(\ w +?) (: |) (\ w +?),"); Matcher matcher = pattern.matcher (hľadať + ","); while (matcher.find ()) {params.add (new SearchCriteria (matcher.group (1), matcher.group (2), matcher.group (3))); }} vrátiť api.searchUser (parametre); }}
Všimnite si, ako jednoducho vytvárame objekty kritérií vyhľadávania z hľadaného výrazu.
Teraz sme v bode, kedy môžeme začať hrať s API a skontrolovať, či všetko funguje správne:
// localhost: 8080 / users? search = lastName: doe, age> 25
A tu je jeho odpoveď:
[{"id": 2, "firstName": "tom", "lastName": "doe", "email": "[e-mail chránený]", "vek": 26}]
7. Záver
Táto jednoduchá, ale výkonná implementácia umožňuje dosť inteligentného filtrovania na rozhraní REST API. Áno - po okrajoch je stále drsný a dá sa vylepšiť (a bude vylepšené v nasledujúcom článku) - ale je to solídny východiskový bod pre implementáciu tohto druhu funkcie filtrovania do vašich API.
The úplná implementácia tohto článku nájdete v projekte GitHub - jedná sa o projekt založený na Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.
Ďalšie » Dotazovací jazyk REST so špecifikáciami JPA Spring Data REST dole