Útmutató Jdbi-hez

1. Bemutatkozás

Ebben a cikkben megvizsgáljuk, hogyan lehet lekérdezni egy relációs adatbázist a jdbi segítségével.

A Jdbi egy nyílt forráskódú Java könyvtár (Apache licenc), amely lambda kifejezéseket és reflexiókat használ, hogy az JDBC-nél barátságosabb, magasabb szintű felületet biztosítson az adatbázis eléréséhez.

Jdbi azonban nem ORM; Annak ellenére, hogy rendelkezik opcionális SQL Object leképező modullal, nincs munkamenet csatolt objektumokkal, adatbázis-függetlenségi réteggel és egy tipikus ORM bármely más harangjával és sípjával.

2. Jdbi beállítása

A Jdbi egy központi és több opcionális modulra tagolódik.

A kezdéshez csak be kell építenünk a központi modult a függőségeinkbe:

  org.jdbi jdbi3-core 3.1.0 

A cikk során példákat mutatunk be a HSQL adatbázis használatával:

 org.hsqldb hsqldb 2.4.0 teszt 

Megtalálhatjuk a legújabb verzióját jdbi3-mag, A HSQLDB és a többi Jdbi modul a Maven Central-on.

3. Csatlakozás az adatbázishoz

Először csatlakoznunk kell az adatbázishoz. Ehhez meg kell adnunk a csatlakozási paramétereket.

A kiindulópont a Jdbi osztály:

Jdbi jdbi = Jdbi.create ("jdbc: hsqldb: mem: testDB", "sa", "");

Itt adjuk meg a kapcsolat URL-jét, egy felhasználónevet és természetesen egy jelszót.

3.1. További paraméterek

Ha más paramétereket kell megadnunk, akkor egy túlterhelt módszert alkalmazunk az a elfogadására Tulajdonságok tárgy:

Tulajdonságok tulajdonságai = új Tulajdonságok (); properties.setProperty ("felhasználónév", "sa"); tulajdonságok.setProperty ("jelszó", ""); Jdbi jdbi = Jdbi.create ("jdbc: hsqldb: mem: testDB", tulajdonságok);

Ezekben a példákban elmentettük a Jdbi például egy helyi változóban. Ez azért van, mert azt fogjuk használni, hogy utasításokat és lekérdezéseket küldjünk az adatbázisba.

Valójában pusztán hívás teremt nem hoz létre kapcsolatot a DB-vel. Csak a kapcsolati paramétereket menti későbbre.

3.2. Használva Adatforrás

Ha az a használatával csatlakozunk az adatbázishoz Adatforrás, mint általában, használhatjuk a megfelelőt teremt túlterhelés:

Jdbi jdbi = Jdbi.create (adatforrás);

3.3. Munka a fogantyúkkal

A tényleges kapcsolat az adatbázissal az Fogantyú osztály.

A fogantyúkkal való együttműködés és a bezárás legegyszerűbb módja a lambda kifejezések használata:

jdbi.useHandle (fogantyú -> {doStuffWith (fogantyú);});

Hívjuk useHandle amikor nem kell értéket adnunk.

Ellenkező esetben használjuk withHandle:

jdbi.withHandle (fogantyú -> {return computeValue (fogantyú);});

Az is lehetséges, bár nem ajánlott, de kézzel is megnyitja a csatlakozási fogantyút; ebben az esetben le kell zárnunk, ha kész vagyunk:

Jdbi jdbi = Jdbi.create ("jdbc: hsqldb: mem: testDB", "sa", ""); try (Fogantyú = jdbi.open ()) {doStuffWith (fogantyú); }

Szerencsére, mint láthatjuk, Fogantyú megvalósítja Bezárható, így az erőforrásokkal való próbálkozással használható.

4. Egyszerű állítások

Most, hogy tudjuk, hogyan szerezhetünk kapcsolatot, nézzük meg, hogyan kell használni.

Ebben a szakaszban létrehozunk egy egyszerű táblázatot, amelyet a cikkben használunk.

Nyilatkozatokat küldeni, mint pl táblázat létrehozása az adatbázishoz, a végrehajtani módszer:

handle.execute ("tábla létrehozása projekt" + "(id egész azonosító, név varchar (50), url varchar (100))");

végrehajtani adja vissza az utasítással érintett sorok számát:

int updateCount = handle.execute ("beszúrás a projektértékekbe" + "(1, 'oktatóanyagok', 'github.com/eugenp/tutorials')"); assertEquals (1, updateCount);

Valójában a végrehajtás csak egy kényelmi módszer.

A későbbi szakaszokban megvizsgáljuk a bonyolultabb felhasználási eseteket, de mielőtt ezt megtennénk, meg kell tanulnunk, hogyan vonhatók ki az eredmények az adatbázisból.

5. Az adatbázis lekérdezése

A legegyszerűbb kifejezés, amely eredményeket hoz létre a DB-ből, egy SQL-lekérdezés.

A Jdbi fogantyúval történő lekérdezéshez legalább:

  1. hozza létre a lekérdezést
  2. válassza ki az egyes sorok ábrázolásának módját
  3. ismételje meg az eredményeket

Most megvizsgáljuk a fenti pontokat.

5.1. Lekérdezés létrehozása

Nem meglepő módon A Jdbi a lekérdezéseket a Lekérdezés osztály.

Nyerhetünk egyet egy fogantyúból:

Lekérdezés = hand.createQuery ("select * from project");

5.2. Az eredmények feltérképezése

Jdbi elvonul a JDBC-től ResultSet, amelynek elég nehézkes API-ja van.

Ezért számos lehetőséget kínál az oszlopok eléréséhez, amelyek egy lekérdezésből vagy más, eredményt adó utasításból származnak. Most meglátjuk a legegyszerűbbeket.

Minden sort ábrázolhatunk térképként:

query.mapToMap ();

A térkép kulcsai a kiválasztott oszlopnevek lesznek.

Vagy ha egy lekérdezés egyetlen oszlopot ad vissza, akkor a kívánt Java típushoz hozzárendelhetjük:

hand.createQuery ("válasszon nevet a projektből"). mapTo (String.class);

A Jdbi számos közös osztály számára rendelkezik beépített térképekkel. Azokat, amelyek valamilyen könyvtárra vagy adatbázis-rendszerre jellemzőek, külön modulokban adják meg.

Természetesen definiálhatjuk és regisztrálhatjuk a térképeinket is. Egy későbbi szakaszban beszélünk róla.

Végül sorokat tudunk leképezni egy babra vagy más egyéni osztályra. Ismét egy speciális szakaszban láthatjuk a fejlettebb lehetőségeket.

5.3. Iterálva az eredmények felett

Miután eldöntöttük, hogyan térképezzük fel az eredményeket a megfelelő módszer meghívásával, kapunk egy Eredményes tárgy.

Ezután felhasználhatjuk az eredmények egymás utáni ismétlésére.

Itt megnézzük a leggyakoribb lehetőségeket.

Az eredményeket csupán felsorolhatjuk egy listában:

Lista eredmények = lekérdezés.mapToMap (). lista ();

Vagy egy másikhoz Gyűjtemény típus:

Eredmények felsorolása = query.mapTo (String.osztály) .collect (Collectors.toSet ());

Vagy streamelhetjük az eredményeket:

query.mapTo (String.class) .useStream ((Stream stream) -> {doStuffWith (stream)});

Itt kifejezetten beírtuk a folyam változó az érthetőség kedvéért, de erre nincs szükség.

5.4. Egyetlen eredmény elérése

Különleges esetként, amikor csak egy sorra számítunk, vagy érdekel bennünket, van néhány dedikált módszerünk.

Ha akarjuk legfeljebb egy eredmény, tudjuk használni findFirst:

Választható első = lekérdezés.mapToMap (). findFirst ();

Mint láthatjuk, egy Választható érték, amely csak akkor van jelen, ha a lekérdezés legalább egy eredményt ad vissza.

Ha a lekérdezés egynél több sort ad vissza, csak az elsőt adja vissza.

Ha ehelyett, azt akarjuk egyetlen és egyetlen eredmény, használunk megtalálniCsak:

Only dateResult = query.mapTo (Date.class) .findOnly ();

Végül, ha nulla vagy több eredmény van, megtalálniCsak dob egy IllegalStateException.

6. Kötési paraméterek

Gyakran, a lekérdezéseknek van egy fix és egy paraméterezett része. Ennek számos előnye van, többek között:

  • biztonság: a karakterlánc összefűzésének elkerülésével megakadályozzuk az SQL injekciót
  • egyszerűség: nem kell emlékeznünk az összetett adattípusok, például az időbélyegek pontos szintaxisára
  • teljesítmény: a lekérdezés statikus része egyszer értelmezhető és gyorsítótárazott

A Jdbi támogatja a helyzeti és a megnevezett paramétereket is.

Helyzeti paramétereket kérdőjelként illesztünk be egy lekérdezésbe vagy utasításba:

Query positionalParamsQuery = handle.createQuery ("válasszon * a projektből, ahol a név =?");

A megnevezett paraméterek helyett kettőspontot kell kezdeni:

Lekérdezés:

Mindkét esetben a paraméter értékének beállításához a paraméter egyik változatát használjuk megkötözni módszer:

positionalParamsQuery.bind (0, "oktatóanyagok"); namedParamsQuery.bind ("minta", "% github.com / eugenp /%");

Vegye figyelembe, hogy a JDBC-vel ellentétben az indexek 0-tól kezdődnek.

6.1. Több megnevezett paraméter egyidejű kötése

Egy objektum segítségével több megnevezett paramétert is összekapcsolhatunk.

Tegyük fel, hogy ez az egyszerű lekérdezés van:

Lekérdezés = hand.createQuery ("válassza ki az azonosítót a projektből, ahol name =: név és url =: url"); Térképparaméterek = new HashMap (); params.put ("név", "REST with Spring"); params.put ("url", "github.com/eugenp/REST-With-Spring");

Ezután használhatunk például egy térképet:

query.bindMap (paraméterek);

Vagy használhatunk egy objektumot különféle módokon. Itt például egy objektumot kötünk, amely a JavaBean konvenciót követi:

query.bindBean (paramsBean);

De megköthetjük egy objektum mezőit vagy metódusait is; Az összes támogatott opcióért lásd a Jdbi dokumentációját.

7. Összetettebb nyilatkozatok kiadása

Most, hogy láttunk lekérdezéseket, értékeket és paramétereket, visszatérhetünk a kijelentésekhez, és ugyanazt a tudást alkalmazhatjuk.

Emlékezzünk vissza, hogy a végrehajtani módszer, amelyet korábban láttunk, csak egy hasznos parancsikon.

Valójában, hasonlóan a lekérdezésekhez, A DDL és a DML utasítások az osztály példányaként vannak ábrázolva Frissítés.

A módszer meghívásával beszerezhetünk egyet createUpdate fogantyún:

Frissítés frissítése = handle.createUpdate ("INSERT INTO PROJECT (Név, URL) ÉRTÉKEK (: név,: url)");

Aztán egy Frissítés megvan az összes olyan kötési módszer, amely a Lekérdezés, így a 6. szakasz a frissítésekre is vonatkozik.url

Az utasításokat akkor hajtjuk végre, amikor felhívunk, meglepünk, végrehajtani:

int sorok = update.execute ();

Mint már láthattuk, az érintett sorok számát adja vissza.

7.1. Az automatikus növekményes oszlopértékek kinyerése

Különleges esetben, ha van egy beszúró utasítás automatikus generált oszlopokkal (általában automatikus növekmény vagy szekvenciák), akkor érdemes megszereznünk a létrehozott értékeket.

Akkor nem hívunk végrehajtani, de executeAndReturnGeneratedKeys:

Update update = handle.createUpdate ("INSERT INTO PROJECT (NAME, URL)" + "VALUES ('tutorials', 'github.com/eugenp/tutorials')"); ResultBearing generatedKeys = update.executeAndReturnGeneratedKeys ();

ResultBearing ugyanaz az interfész, amelyet a Lekérdezés osztály amit korábban láttunk, tehát már tudjuk, hogyan kell használni:

generáltKeys.mapToMap () .findOnly (). get ("id");

8. Tranzakciók

Szükségünk van egy tranzakcióra, amikor több utasítást kell végrehajtanunk egyetlen atomi műveletként.

A csatlakozási fogantyúkhoz hasonlóan egy tranzakciót is bevezetünk egy lezárásos módszer meghívásával:

handle.useTransaction ((h fogantyú) -> {haveFunWith (h);});

És a fogantyúkhoz hasonlóan a tranzakció is automatikusan lezárul, amikor a lezárás visszatér.

A tranzakciót azonban el kell végeznünk vagy vissza kell állítanunk visszatérés előtt:

handle.useTransaction ((h fogantyú) -> {h.execute ("..."); h.vállalás ();});

Ha azonban a lezárás alól kivételt képeznek, a Jdbi automatikusan visszaforgatja a tranzakciót.

Mint a fogantyúknál, itt is van egy dedikált módszerünk, inTransaction, ha valamit vissza akarunk adni a bezárásból:

handle.inTransaction ((h fogantyú) -> {h.execute ("..."); h.commit (); return true;});

8.1. Manuális tranzakciókezelés

Bár általános esetben ez nem ajánlott, mi is tudjuk kezdődik és Bezárás egy tranzakció manuálisan:

handle.begin (); // ... handle.commit (); fogantyú.zár ();

9. Következtetések és további olvasmányok

Ebben az oktatóanyagban bemutattuk a Jdbi magját: lekérdezések, kimutatások és tranzakciók.

Kihagytunk néhány speciális funkciót, például az egyéni sorok és oszlopok leképezését és a kötegelt feldolgozást.

Nem beszéltünk az opcionális modulokról sem, nevezetesen az SQL Object kiterjesztésről.

Mindent részletesen bemutatunk a Jdbi dokumentációjában.

Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub projektben - ez egy Maven projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.


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