REST lekérdezési nyelv tavaszi és JPA kritériumokkal

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 lekérdezési nyelv tavaszi és JPA kritériumokkal (aktuális cikk) • REST lekérdezési nyelv tavaszi adatok JPA specifikációival

• 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

• REST Query Language RSQL segítségével

• REST Queryds a Querydsl webes támogatásával

1. Áttekintés

Ennek az új sorozatnak az első cikkében fogjuk felfedezni a REST API egyszerű lekérdezési nyelve. Jól fogjuk használni a Spring-et a REST API-hoz és a JPA 2 kritériumokat a perzisztencia szempontokhoz.

Miért egy lekérdezés nyelve? Mert - bármilyen elég komplex API esetén - az erőforrások keresése / szűrése nagyon egyszerű mezőkkel egyszerűen nem elég. A lekérdezés nyelve rugalmasabb, és lehetővé teszi, hogy pontosan a szükséges erőforrásokhoz szűrjön le.

2. Felhasználó Entitás

Először - tegyük fel azt az egyszerű entitást, amelyet a szűrő / keresés API-hoz fogunk használni - egy alapot Felhasználó:

@Entity public class User {@Id @GeneratedValue (strategy = GenerationType.AUTO) private Long id; privát karakterlánc keresztnév; privát karakterlánc vezetéknév; privát karakterlánc e-mail; privát int kor; }

3. Szűrés használatával CriteriaBuilder

Most - menjünk bele a probléma húsába - a perzisztens rétegben található lekérdezés.

A lekérdezés absztrakció kiépítése egyensúly kérdése. Egyrészt jó mennyiségű rugalmasságra van szükségünk, másrészt kezelni kell a bonyolultságot. Magas szintű, a funkcionalitás egyszerű - átad bizonyos korlátokat, és visszakap néhány eredményt.

Nézzük meg, hogyan működik:

@Repository public class A UserDAO megvalósítja az IUserDAO {@PersistenceContext private EntityManager entitástManager; @Orride public List searchUser (List params) {CriteriaBuilder builder = entitásManager.getCriteriaBuilder (); CriteriaQuery lekérdezés = builder.createQuery (User.class); Root r = query.from (Felhasználó.osztály); Predikátum predikátum = builder.conjunction (); UserSearchQueryCriteriaConsumer searchConsumer = new UserSearchQueryCriteriaConsumer (predikátum, készítő, r); params.stream (). forEach (searchConsumer); predikátum = searchConsumer.getPredicate (); lekérdezés.hová (predikátum); Lista eredménye = entitásManager.createQuery (lekérdezés) .getResultList (); visszatérési eredmény; } @Orride public void save (Felhasználó entitás) {entitManager.persist (entitás); }}

Vessünk egy pillantást a UserSearchQueryCriteriaConsumer osztály:

public class UserSearchQueryCriteriaConsumer megvalósítja a Consumer {private Predicate predikátumot; saját CriteriaBuilder építő; magángyökér r; @Orride public void accept (SearchCriteria param) {if (param.getOperation (). EqualsIgnoreCase (">")) {predicate = builder.and (predikátum, builder .greaterThanOrEqualTo (r.get (param.getKey ()), param .getValue (). toString ())); } else if (param.getOperation (). equalsIgnoreCase ("<")) {predicate = builder.and (predikátum, 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 (predikátum, builder .like (r.get (param.getKey ()), "%" + param.getValue () + "%")); } else {predicate = builder.and (predikátum, builder.equal (r.get (param.getKey ()), param.getValue ())); }}} // standard konstruktor, getter, setter}

Mint láthatja, a searchUser Az API felsorolja a nagyon egyszerű korlátozások listáját, e korlátozások alapján összeállítja a lekérdezést, elvégzi a keresést és visszaadja az eredményeket.

A kényszerosztály is meglehetősen egyszerű:

public class SearchCriteria {private String kulcs; privát húr művelet; magánobjektum értéke; }

A Keresési feltétel a megvalósítás tartja magunkat Lekérdezés paraméterek:

  • kulcs: a mező nevének megtartására szolgál - például: keresztnév, kor,… Stb.
  • művelet: a művelet megtartására szolgál - például: Egyenlőség, kevesebb, mint… stb.
  • érték: a mező értékének megtartására szolgál - például: john, 25,… stb.

4. Tesztelje a keresési lekérdezéseket

Most - teszteljük a keresési mechanizmusunkat, hogy megbizonyosodjon arról, hogy víz tartja-e.

Először - inicializáljuk az adatbázisunkat tesztelésre két felhasználó hozzáadásával - ahogyan a következő példában:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (class = {PersistenceConfig.class}) @Transactional @TransactionConfiguration public class JPACriteriaQueryTest {@Autowired private IUserDAO userApi; private User userJohn; private User userTom; @A nyilvános void előtt init () {userJohn = new User (); userJohn.setFirstName ("John"); userJohn.setLastName ("Doe"); userJohn.setEmail ("[e-mail védett]"); userJohn.setAge (22); userApi.save (userJohn); userTom = új felhasználó (); userTom.setFirstName ("Tom"); userTom.setLastName ("Doe"); userTom.setEmail ("[e-mail védett]"); userTom.setAge (26); userApi.save (userTom); }}

Most vegyünk egy Felhasználó specifikus keresztnév és vezetéknév - mint a következő példában:

@Test public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (új SearchCriteria ("keresztnév", ":", "John"); params.add (új SearchCriteria ("vezetéknév", ":", "Doe"); Eredménylista = userApi.searchUser (paraméterek); assertThat (userJohn, isIn (eredmények)); assertThat (userTom, nem (isIn (eredmények))); }

Ezután vegyünk egy Lista nak,-nek Felhasználó ugyanazzal vezetéknév:

@Test public void givenLast_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (új SearchCriteria ("vezetéknév", ":", "Doe"); Eredménylista = userApi.searchUser (paraméterek); assertThat (userJohn, isIn (eredmények)); assertThat (userTom, isIn (eredmények)); }

Ezután hívjuk fel a felhasználókat kornagyobb vagy egyenlő 25:

@Test public void givenLastAndAge_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (új SearchCriteria ("vezetéknév", ":", "Doe"); params.add (új SearchCriteria ("kor", ">", "25"); Eredménylista = userApi.searchUser (paraméterek); assertThat (userTom, isIn (eredmények)); assertThat (userJohn, nem (isIn (eredmények))); }

Ezután keressük meg a felhasználókat valójában nem léteznek:

@Test public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (új SearchCriteria ("keresztnév", ":", "Ádám"); params.add (új SearchCriteria ("vezetéknév", ":", "Fox")); Eredménylista = userApi.searchUser (paraméterek); assertThat (userJohn, nem (isIn (eredmények))); assertThat (userTom, nem (isIn (eredmények))); }

Végül keressük csak a megadott felhasználókat részlegeskeresztnév:

@Test public void givenPartialFirst_whenGettingListOfUsers_thenCorrect () {List params = new ArrayList (); params.add (új SearchCriteria ("keresztnév", ":", "jo"); Eredménylista = userApi.searchUser (paraméterek); assertThat (userJohn, isIn (eredmények)); assertThat (userTom, nem (isIn (eredmények))); }

6. A UserController

Végül csatlakoztassuk a rugalmas keresés állandó támogatását a REST API-hoz.

Egy egyszerűt fogunk felállítani UserController - val,-vel Találd meg mindet()használni a "keresés”A teljes keresési / szűrési kifejezés átadásához:

@Controller public class 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 (keresés! = null) {Pattern pattern = Pattern.compile ("(\ w +?) (: |) (\ w +?),"); Matcher matcher = minta.matcher (keresés + ","); while (matcher.find ()) {params.add (új SearchCriteria (matcher.group (1), matcher.group (2), matcher.group (3))); }} return api.searchUser (paraméterek); }}

Ne feledje, hogyan hozunk létre egyszerűen a keresési feltétel objektumainkat a keresési kifejezésből.

Most vagyunk azon a ponton, ahol elkezdhetjük a játékot az API-val, és ellenőrizhetjük, hogy minden megfelelően működik:

// localhost: 8080 / users? search = lastName: őz, kor> 25

És itt van a válasz:

[{"id": 2, "keresztnév": "tom", "vezetékNév": "őz", "e-mail": "[e-mail védett]", "kor": 26}]

7. Következtetés

Ez az egyszerű, mégis hatékony megvalósítás elég sok intelligens szűrést tesz lehetővé a REST API-n. Igen - még mindig durva a szélén, és javítható (és a következő cikkben javítani fogjuk) -, de szilárd kiindulópont az effajta szűrési funkció megvalósításához az API-ken.

A teljes végrehajtása cikkünk 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 lekérdezési nyelv a Spring Data JPA specifikációival REST alul

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

$config[zx-auto] not found$config[zx-overlay] not found