REST Lekérdezés nyelve - VAGY művelet végrehajtása
Most jelentettem be az újat Tanulj tavaszt tanfolyam, amelynek középpontjában az 5. tavasz és a tavaszi bakancs 2 alapjai állnak:
>> ELLENŐRIZZE A FOLYAMATOT Ez a cikk egy sorozat része: • REST Query Language with Spring and JPA Criteria• REST lekérdezési nyelv a Spring Data JPA specifikációkkal
• REST Query Language a Spring Data JPA és a Querydsl segítségével
• REST Query Language - Speciális keresési műveletek
• REST Query Language - VAGY művelet végrehajtása (aktuális cikk) • REST Query Language RSQL-lel
• REST Queryds a Querydsl webes támogatásával
1. Áttekintés
Ebben a gyors cikkben kibővítjük az előző cikkben bevezetett speciális keresési műveleteket, és belefoglaljuk azokat VAGY alapú keresési feltételek a REST API lekérdezési nyelvünkbe.
2. Megvalósítási megközelítés
Korábban az összes kritérium a keresés A kialakított lekérdezési paraméter predikátumokat csak AND operátor szerint csoportosítva. Változtassunk ezen.
Képesnek kell lennünk arra, hogy ezt a funkciót egyszerûen, gyorsan megváltoztassuk a meglévõ megközelítéshez, vagy egy újat a semmibõl.
Az egyszerű megközelítéssel megjelöljük a feltételeket annak jelzésére, hogy ezeket az OR operátorral kell kombinálni.
Például itt van az URL, amellyel tesztelni kell az API-t „keresztnév VAGY vezetéknév ”:
// localhost: 8080 / users? search = firstName: john, 'lastName: doe
Ne feledje, hogy megjelöltük a kritériumokat vezetéknév egyetlen idézettel megkülönböztetni. Fogjuk ezt az állítást az OR operátor számára a kritérium érték objektumunkban - SpecSearchCriteria:
public SpecSearchCriteria (String orPredicate, String key, SearchOperation operation, Object value) {super (); this.orPredicate = orPredicate! = null && orPredicate.equals (SearchOperation.OR_PREDICATE_FLAG); this.key = kulcs; this.művelet = művelet; ez.érték = érték; }
3. UserSpecificationBuilder Javulás
Most módosítsuk a specifikáció készítőnket, UserSpecificationBuilder, hogy a kivitelezés során vegye figyelembe a legkülsőbb feltételeket Leírás:
public Specifikáció build () {if (params.size () == 0) {return null; } Specifikáció eredménye = new UserSpecification (params.get (0)); for (int i = 1; i <params.size (); i ++) {eredmény = params.get (i) .isOrPredicate ()? Specification.where (result) .or (new UserSpecification (params.get (i))): Specification.where (result) .and (new UserSpecification (params.get (i))); } visszatérési eredmény; }
4. UserController Javulás
Végül állítsunk be egy új REST végpontot a vezérlőnkben, hogy használhassuk ezt a keresési funkciót az OR operátorral. A továbbfejlesztett elemzési logika kivonja a speciális jelzőt, amely segít azonosítani a feltételeket az OR operátorral:
@GetMapping ("/ users / espec") @ResponseBody public List findAllByOrPredicate (@RequestParam String search) {Specifikáció spec = ResolSpecification (keresés); return dao.findAll (spec); } védett Specification ResolSpecification (String searchParameters) {UserSpecificationsBuilder builder = new UserSpecificationsBuilder (); String operationSetExper = Joiner.on ("|") .join (SearchOperation.SIMPLE_OPERATION_SET); Mintaminta = Pattern.compile ("(\ p {Punct}?) (\ w +?) (" + OperationSetExper + ") (\ p {Punct}?) (\ w +?) (\ p { Pontos}?), "); Matcher matcher = minta.matcher (searchParameters + ","); míg (matcher.find ()) {builder.with (matcher.group (1), matcher.group (2), matcher.group (3), matcher.group (5), matcher.group (4), matcher. csoport (6)); } return builder.build (); }
5. Élő tesztelés VAGY Feltétel
Ebben az élő tesztpéldában az új API-végponttal a „john” VAGY a „doe” vezetéknév alapján keressük meg a felhasználókat. Vegye figyelembe azt a paramétert vezetéknév egyetlen árajánlata van, amely „VAGY állítmánynak” minősíti:
privát karakterlánc EURL_PREFIX = "// localhost: 8082 / spring-rest-full / auth / users / espec? search ="; @Test public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect () {Response response = megadottAuth (). Get (EURL_PREFIX + "keresztnév: john, 'vezetékNév: őz"); Karakterlánc eredménye = response.body (). AsString (); assertTrue (result.contains (userJohn.getEmail ())); assertTrue (result.contains (userTom.getEmail ())); }
6. Perzisztencia teszt With VAGY Feltétel
Most végezzük el ugyanazt a tesztet, amelyet fentebb tettünk, a felhasználók kitartási szintjén keresztnévvel „john” VAGY vezetéknévvel „őz”:
@Test public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect () {UserSpecificationsBuilder builder = new UserSpecificationsBuilder (); SpecSearchCriteria spec = new SpecSearchCriteria ("keresztnév", SearchOperation.EQUALITY, "john"); SpecSearchCriteria spec1 = új SpecSearchCriteria ("" "," vezetékNév ", SearchOperation.EQUALITY," őz "); Eredmények listája = adattár .findAll (építő.with (spec) .with (spec1) .build ()); assertThat (eredmények, hasSize (2)); assertThat (userJohn, isIn (eredmények)); assertThat (userTom, isIn (eredmények)); }
7. Alternatív megközelítés
Alternatív megközelítésben a keresési lekérdezést inkább teljesnek adhatnánk HOL az SQL lekérdezés záradéka.
Például itt található a bonyolultabb keresés URL-je keresztnév és kor:
// localhost: 8080 / users? search = (keresztnév: john OR keresztnév: tom) ÉS életkor> 22
Felhívjuk figyelmét, hogy külön feltételeket, operátorokat és zárójeleket csoportosítottunk szóközzel, hogy érvényes infix kifejezést alkossunk.
Az infix kifejezést elemezzük a-val CriteriaParser. A mi CriteriaParser felosztja az adott infix kifejezést tokenekre (feltételek, zárójelek, ÉS & VAGY operátorok), és létrehoz egy postfix kifejezést ehhez:
public Deque parse (String searchParam) {Deque output = new LinkedList (); Deque stack = új LinkedList (); Arrays.stream (searchParam.split ("\ s +")). ForEach (token -> {if (ops.containsKey (token)) {while (! Stack.isEmpty () && isHigerPrecedenceOperator (token, stack.peek () )) {output.push (stack.pop (). equalsIgnoreCase (SearchOperation.OR_OPERATOR)? SearchOperation.OR_OPERATOR: SearchOperation.AND_OPERATOR);} stack.push (token.equalsIgnoreCase (SearchOperation.OR_OPERATOR)? SearchOperation.OR_OPERATOR) SearchOperation.OR_OPERATOR );} else if (token.equals (SearchOperation.LEFT_PARANTHESIS)) {stack.push (SearchOperation.LEFT_PARANTHESIS);} else if (token.equals (SearchOperation.RIGHT_PARANTHESIS)) {while (!! stack.peek (). egyenlő ( SearchOperation.LEFT_PARANTHESIS)) {output.push (stack.pop ());} stack.pop ();} else {Matcher matcher = SpecCriteraRegex.matcher (token); while (matcher.find ()) {output.push ( új SpecSearchCriteria (matcher.group (1), matcher.group (2), matcher.group (3), matcher.group (4), matcher.group (5));}}}); while (! stack.isEmpty ()) {output.push (stack.pop ()); } visszatérő kimenet; }
Vegyünk fel egy új módszert a specifikáció-készítőbe, GenericSpecificationBuilder, a keresés felépítéséhez Leírás a postfix kifejezésből:
public Specification build (Deque postFixedExprStack, Function átalakító) {Deque specStack = új LinkedList (); while (! postFixedExprStack.isEmpty ()) {Object mayBeOperand = postFixedExprStack.pollLast (); if (! (mayBeOperand instanceof String)) {specStack.push (converter.apply (((SpecSearchCriteria) mayBeOperand)); } else {Specification operand1 = specStack.pop (); Specifikáció operand2 = specStack.pop (); if (mayBeOperand.equals (SearchOperation.AND_OPERATOR)) {specStack.push (Specification.where (operand1) .and (operand2)); } else if (mayBeOperand.equals (SearchOperation.OR_OPERATOR)) {specStack.push (Specification.where (operand1) .or (operand2)); }}} return specStack.pop ();
Végül adjunk hozzá egy másik REST végpontot a UserController hogy elemezze a komplex kifejezést az újval CriteriaParser:
@GetMapping ("/ users / spec / adv") @ResponseBody public List findAllByAdvPredicate (@RequestParam String search) {Specifikáció spec = ResolSpecificationFromInfixExpr (keresés); return dao.findAll (spec); } védett Specification ResolSpecificationFromInfixExpr (String searchParameters) {CriteriaParser parser = új CriteriaParser (); GenericSpecificationsBuilder specBuilder = new GenericSpecificationsBuilder (); return specBuilder.build (parser.parse (searchParameters), UserSpecification :: new); }
8. Következtetés
Ebben az oktatóanyagban továbbfejlesztettük a REST lekérdezés nyelvét azzal a képességgel, hogy OR operátorral kereshetünk.
A cikk teljes megvalósítása megtalálható a GitHub projektben. Ez egy Maven-alapú projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.
Következő » REST Query Language RSQL-lel « Előző REST lekérdezési nyelv - Speciális keresési műveletek REST alján