REST Lekérdezés nyelve a Spring Data JPA-val és a Querydsl-lel
• REST lekérdezési nyelv a Spring Data JPA specifikációkkal
• REST Query Language a Spring Data JPA-val és a Querydsl-lel (aktuális cikk) • 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
Ebben az oktatóanyagban a a REST API a Spring Data JPA és a Querydsl használatával.
A sorozat első két cikkében ugyanazt a keresési / szűrési funkciót építettük fel a JPA Criteria és a Spring Data JPA Specifications segítségével.
Így - 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 szűrje le pontosan a szükséges erőforrásokat.
2. Querydsl konfiguráció
Először - nézzük meg, hogyan konfigurálhatjuk a projektünket a Querydsl használatára.
Hozzá kell adnunk a következő függőségeket pom.xml:
com.querydsl querydsl-apt 4.2.2 com.querydsl querydsl-jpa 4.2.2
Az APT - Annotation processing tool - plugint az alábbiak szerint kell konfigurálnunk:
com.mysema.maven apt-maven-plugin 1.1.3 folyamat cél / generált források / java com.mysema.query.apt.jpa.JPAAnnotationProcessor
Ez generálja a Q-típusokat entitásaink számára.
3. Az MyUser Entitás
Következő - vessünk egy pillantást aMyUser”Entitás, amelyet a Keresési API-nkban használni fogunk:
@Entity public class MyUser {@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; }
4. Egyedi Predikátum With PathBuilder
Most - hozzunk létre egy egyéni Állítmány néhány önkényes korlátozás alapján.
Használjuk PathBuilder itt az automatikusan generált Q-típusok helyett, mert az elvontabb felhasználás érdekében dinamikusan kell utakat létrehoznunk:
public class MyUserPredicate {private SearchCriteria feltételek; public BooleanExpression getPredicate () {PathBuilder entitásPath = új PathBuilder (MyUser.class, "felhasználó"); IF int érték = Integer.parseInt (feltételek.getValue (). toString ()); kapcsoló (feltételek.getOperation ()) {case ":": return path.eq (érték); case ">": return path.goe (érték); case "<": return path.loe (érték); }} else {StringPath elérési útja = entitásPath.getString (feltételek.getKey ()); if (feltételek.getOperation (). equalsIgnoreCase (":")) {return path.containsIgnoreCase (feltételek.getValue (). toString ()); }} return null; }}
Vegye figyelembe, hogy az állítmány megvalósulása milyen többféle művelettel általában foglalkozik. Ez azért van, mert a lekérdezés nyelve definíció szerint egy nyitott nyelv, ahol bármilyen mező alapján szűrhet, bármilyen támogatott művelettel.
Az ilyen típusú nyílt szűrési feltételek képviseletéhez egyszerű, de meglehetősen rugalmas megvalósítást alkalmazunk - Keresési feltétel:
public class SearchCriteria {private String kulcs; privát húr művelet; magánobjektum értéke; }
A Keresési feltétel megtartja azokat a részleteket, amelyekre korlátozást kell képviselnünk:
- kulcs: a mező neve - például: keresztnév, kor,… Stb
- művelet: a művelet - például: Egyenlőség, kevesebb, mint… stb
- érték: a mező értéke - például: john, 25,… stb
5. MyUserRepository
Most - vessünk egy pillantást a mi MyUserRepository.
Szükségünk van a miénkre MyUserRepository kiterjeszteni QuerydslPredicateExecutor hogy használhassuk Jóslatok később a keresési eredmények szűréséhez:
nyilvános felület A MyUserRepository kiterjeszti a JpaRepository, QuerydslPredicateExecutor, QuerydslBinderCustomizer {@Orride default public void customize (QuerydslBindings bindings, QMyUser root) {bindings.bind (String.class) .first ((SingleValueBpression) String; kötések.kizárva (root.email); }}
Ne feledje, hogy itt a létrehozott Q-típust használjuk MyUser entitás, amelyet meg fognak nevezni QMyUser.
6. Össze Jóslatok
Következő - vessünk egy pillantást az Előrejelzések kombinálására, hogy több korlátot használjunk az eredmények szűrésében.
A következő példában - építőkkel dolgozunk - MyUserPredicatesBuilder - kombinálni Jóslatok:
public class MyUserPredicatesBuilder {privát lista paraméterek; public MyUserPredicatesBuilder () {params = new ArrayList (); } public MyUserPredicatesBuilder with (String kulcs, String művelet, Object érték) {params.add (új SearchCriteria (kulcs, művelet, érték)); adja vissza ezt; } public BooleanExpression build () {if (params.size () == 0) {return null; } Lista predikátumok = params.stream (). Map (param -> {MyUserPredicate predicate = új MyUserPredicate (param); return predicate.getPredicate ();}). Filter (Objects :: nonNull) .collect (Collectors.toList () ); BooleanExpression eredmény = Expressions.asBoolean (true) .isTrue (); for (BooleanExpression predikátum: predikátumok) {eredmény = eredmény.és (állítmány); } visszatérési eredmény; }}
7. Tesztelje a keresési lekérdezéseket
Következő - teszteljük a Keresési API-t.
Kezdjük azzal, hogy néhány felhasználóval inicializáljuk az adatbázist - hogy ezek készen állnak és tesztelésre rendelkezésre állnak:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (class = {PersistenceConfig.class}) @Transactional @Rollback public class JPAQuerydslIntegrationTest {@Autowired private MyUserRepository repo; saját MyUser userJohn; saját MyUser userTom; @A nyilvános void előtt init () {userJohn = new MyUser (); userJohn.setFirstName ("John"); userJohn.setLastName ("Doe"); userJohn.setEmail ("[e-mail védett]"); userJohn.setAge (22); repo.save (userJohn); userTom = new MyUser (); userTom.setFirstName ("Tom"); userTom.setLastName ("Doe"); userTom.setEmail ("[e-mail védett]"); userTom.setAge (26); repo.save (userTom); }}
Ezután nézzük meg, hogyan lehet megtalálni a felhasználókat adott vezetéknevet:
@Test public void givenLast_whenGettingListOfUsers_thenCorrect () {MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder (). With ("lastName", ":", "Doe"); Megismételhető eredmények = repo.findAll (builder.build ()); assertThat (eredmények, tartalmazInAnyOrder (userJohn, userTom)); }
Most nézzük meg, hogyan lehet megtalálni a megadott felhasználót kereszt- és utónév is:
@Test public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect () {MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder () .with ("firstName", ":", "John") with ("lastName", ":", "Doe"); Megismételhető eredmények = repo.findAll (builder.build ()); assertThat (eredményei tartalmazzák (userJohn)); assertThat (eredmény, nem (tartalmazza (userTom))); }
Ezután nézzük meg, hogyan lehet megtalálni a felhasználót adottval a vezetéknév és a minimális életkor
@Test public void givenLastAndAge_whenGettingListOfUsers_thenCorrect () {MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder () .with ("lastName", ":", "Doe") with ("age", ">", "25"); Megismételhető eredmények = repo.findAll (builder.build ()); assertThat (eredmény, tartalmazza (userTom)); assertThat (eredmény, nem (tartalmazza (userJohn))); }
Most nézzük meg, hogyan lehet keresni MyUser hogy valójában nem létezik:
@Test public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect () {MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder () .with ("firstName", ":", "Adam") with ("lastName", ":", "Fox"); Megismételhető eredmények = repo.findAll (builder.build ()); assertThat (eredmények, emptyIterable ()); }
Végül - nézzük meg, hogyan lehet megtalálni a MyUser a keresztnévnek csak egy részét adták - mint a következő példában:
@Test public void givenPartialFirst_whenGettingListOfUsers_thenCorrect () {MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder (). With ("keresztnév", ":", "jo"); Megismételhető eredmények = repo.findAll (builder.build ()); assertThat (eredményei tartalmazzák (userJohn)); assertThat (eredmény, nem (tartalmazza (userTom))); }
8. UserController
Végül rakjunk össze mindent és készítsük el a REST API-t.
Meghatározzuk a UserController amely meghatároz egy egyszerű módszert Találd meg mindet() val,-vel "keresés“A lekérdezési karakterláncban átadandó paraméter:
@Controller public class UserController {@Autowired private MyUserRepository myUserRepository; @RequestMapping (method = RequestMethod.GET, value = "/ myusers") @ResponseBody public Iterable search (@RequestParam (value = "search") String search) {MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder (); if (keresés! = null) {Pattern pattern = Pattern.compile ("(\ w +?) (: |) (\ w +?),"); Matcher matcher = minta.matcher (keresés + ","); míg (matcher.find ()) {builder.with (matcher.group (1), matcher.group (2), matcher.group (3)); }} BooleanExpression exp = builder.build (); return myUserRepository.findAll (exp); }}
Íme egy példa egy teszt URL-re:
// localhost: 8080 / myusers? search = lastName: őz, kor> 25
És a válasz:
[{"id": 2, "keresztnév": "tom", "vezetékNév": "őz", "e-mail": "[e-mail védett]", "kor": 26}]
9. Következtetés
Ez a harmadik cikk lefedte a REST API lekérdezési nyelvének felépítésének első lépései, jól kihasználva a Querydsl könyvtárat.
A megvalósítás természetesen korai, de könnyen fejleszthető a további műveletek támogatása érdekében.
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 Query Language - Speciális keresési műveletek « Előző REST lekérdezési nyelv a Spring Data JPA specifikációkkal