REST Lekérdezés nyelve - VAGY művelet végrehajtása

REST felső

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

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