Útmutató az Apache Commons DbUtils programhoz

1. Áttekintés

Az Apache Commons DbUtils egy kis könyvtár, amely sokkal könnyebbé teszi a JDBC-vel való munkát.

Ebben a cikkben példákat mutatunk be annak tulajdonságainak és képességeinek bemutatására.

2. Beállítás

2.1. Maven-függőségek

Először hozzá kell adnunk a commons-dbutils és h2 függőségek a mi pom.xml:

 commons-dbutils commons-dbutils 1,6 com.h2adatbázis h2 1.4.196 

A commons-dbutils és a h2 legújabb verzióját a Maven Central oldalon találja.

2.2. Tesztadatbázis

A függőségeink meglétével hozzunk létre egy szkriptet az általunk használt táblák és rekordok létrehozásához:

CREATE TABLE alkalmazott (azonosító NEM NULL PRIMARY KEY automatikus_növekedés, keresztnév varchar (255), vezetéknév varchar (255), fizetés dupla, bérleti dátum,); CREATE TABLE email (azonosító NEM NULL PRIMARY KEY automatikus_növekedés, workerid int, cím varchar (255)); INSERT INTO alkalmazott (keresztnév, vezetéknév, fizetés, bérelt dátum) ÉRTÉKEK ('John', 'Doe', 10000.10, to_date ('01 -01-2001 ',' dd-mm-yyyy ')); // ... INSERT INTO email (alkalmazott azonosító, cím) ÉRTÉKEK (1, '[email protected]'); // ...

A cikkben szereplő összes teszteset egy újonnan létrehozott kapcsolatot fog használni egy H2 memóriabelső adatbázishoz:

public class DbUtilsUnitTest {private Connection kapcsolat; @A nyilvános void beállítás előttDB () dobja a {Class.forName ("org.h2.Driver") kivételt; Karakterlánc db = "jdbc: h2: mem:; INIT = runcript from 'classpath: /employees.sql'"; kapcsolat = DriverManager.getConnection (db); } @A nyilvános void után closeBD () {DbUtils.closeQuietly (kapcsolat); } // ...}

2.3. POJO-k

Végül két egyszerű osztályra lesz szükségünk:

public class Alkalmazott {private Integer azonosító; privát karakterlánc keresztnév; privát karakterlánc vezetéknév; magán Dupla fizetés; magán dátum hiredDate; // szabványos kivitelezők, mérőeszközök és beállítók} public class Email {private Integer id; magán Integer alkalmazottId; privát String cím; // szabványos kivitelezők, mérőeszközök és beállítók}

3. Bevezetés

A DbUtils könyvtár biztosítja a QueryRunner osztály, mint fő belépési pont az elérhető funkciók nagy részéhez.

Ez az osztály úgy működik, hogy fogad egy kapcsolatot az adatbázissal, egy végrehajtandó SQL utasítást és egy opcionális paraméterlistát, amely megadja az értékeket a lekérdezés helyőrzőinek.

Mint később látni fogjuk, néhány módszer is kap egy ResultSetHandler megvalósítás - amely felelős az átalakításért ResultSet példányok azokba az objektumokba, amelyekre alkalmazásunk számít.

Természetesen a könyvtár már számos megvalósítást kínál, amelyek a leggyakoribb átalakításokat kezelik, például listákat, térképeket és JavaBeans-okat.

4. Adatok lekérdezése

Most, hogy ismerjük az alapokat, készen állunk lekérdezni az adatbázisunkat.

Kezdjük egy gyors példával arra, hogy az adatbázisban lévő összes rekordot térképek listájaként szerezzük be az a használatával MapListHandler:

@Test public void givenResultHandler_whenExecutingQuery_thenExpectedList () dobja az SQLException {MapListHandler beanListHandler = new MapListHandler (); QueryRunner runner = új QueryRunner (); Lista list = runner.query (kapcsolat, "SELECT * FROM alkalmazott", beanListHandler); assertEquals (list.size (), 5); assertEquals (list.get (0) .get ("keresztnév"), "John"); assertEquals (list.get (4) .get ("keresztnév"), "keresztény"); }

Ezután íme egy példa az a használatával BeanListHandler hogy az eredményeket átalakítsuk Munkavállaló példányok:

@Test public void givenResultHandler_whenExecutingQuery_thenEmployeeList () dobja az SQLException {BeanListHandler beanListHandler = új BeanListHandler (Employee.class); QueryRunner runner = új QueryRunner (); List workerList = runner.query (kapcsolat, "SELECT * FROM alkalmazott", beanListHandler); assertEquals (workerList.size (), 5); assertEquals (workerList.get (0) .getFirstName (), "John"); assertEquals (workerList.get (4) .getFirstName (), "keresztény"); }

Egyetlen értéket adó lekérdezésekhez használhatjuk a ScalarHandler:

@Test public void givenResultHandler_whenExecutingQuery_thenExpectedScalar () dobja a SQLException {ScalarHandler scalarHandler = új ScalarHandler (); QueryRunner runner = új QueryRunner (); Karakterlánc lekérdezés = "SELECT COUNT (*) FROM alkalmazott"; long count = futó.lekérdezés (kapcsolat, lekérdezés, scalarHandler); assertEquals (szám, 5); }

Megtanulni az összes ResultSerHandler megvalósítások, hivatkozhat a ResultSetHandler dokumentáció.

4.1. Egyedi kezelők

Létrehozhatunk egy egyedi kezelőt is, amelyhez tovább lehet adni QueryRunnerMódszereket, amikor jobban ellenőriznünk kell az eredmények objektumokká történő átalakítását.

Ez megtehető a ResultSetHandler interfész vagy a könyvtár által biztosított meglévő megvalósítások egyikének kiterjesztése.

Lássuk, hogyan néz ki a második megközelítés. Először adjunk hozzá egy másik mezőt a mezőnkhöz Munkavállaló osztály:

public class Employee {private List e-mailek; // ...}

Most hozzunk létre egy osztályt, amely kiterjeszti a BeanListHandler írja be és állítsa be az egyes alkalmazottak e-mail listáját:

public class EmployeeHandler kiterjeszti a BeanListHandler {private Connection kapcsolatot; public EmployeeHandler (Connection con) {szuper (Employee.class); ez.kapcsolat = kon; } @Override public List hand (ResultSet rs) dobja az SQLException {List alkalmazottak = szuper.handle (rs); QueryRunner runner = új QueryRunner (); BeanListHandler kezelő = new BeanListHandler (Email.class); Karakterlánc lekérdezés = "SELECT * FROM email WHERE workerid =?"; for (Munkavállalói alkalmazott: alkalmazottak) {E-mailek felsorolása = runner.query (kapcsolat, lekérdezés, kezelő, alkalmazott.getId ()); worker.setEmails (e-mailek); } visszatérő alkalmazottak; }}

Figyeljük meg, hogy a Kapcsolat objektumot a konstruktorban, hogy végre tudjuk hajtani a lekérdezéseket az e-mailek megszerzéséhez.

Végül teszteljük kódunkat, hátha minden a várt módon működik:

@Test public void givenResultHandler_whenExecutingQuery_thenEmailsSetted () dobja az SQLException {EmployeeHandler workerHandler = új EmployeeHandler (kapcsolat); QueryRunner runner = új QueryRunner (); Alkalmazottak listája = runner.query (kapcsolat, "SELECT * FROM alkalmazott", workerHandler); assertEquals (alkalmazottak.get (0) .getEmails (). méret (), 2); assertEquals (alkalmazottak.get (2) .getEmails (). méret (), 3); }

4.2. Egyéni soros processzorok

Példáinkban a munkavállaló táblázat egyezik a mezőnévvel Munkavállaló osztály (az illesztés kis- és nagybetűk nem érzékenyek). Ez azonban nem mindig így van - például amikor az oszlopnevek aláhúzással jelölik az összetett szavakat.

Ezekben a helyzetekben kihasználhatjuk a RowProcessor felület és megvalósításai az oszlopnevek leképezéséhez osztályaink megfelelő mezőihez.

Lássuk, hogyan néz ki ez. Először hozzunk létre egy másik táblázatot, és illesszünk be néhány rekordot:

CREATE TABLE worker_legacy (azonosító NEM NULL PRIMARY KEY auto_increment, first_name varchar (255), last_name varchar (255), fizetési dupla, bérleti_dátum date,); INSERT INTO alkalmazott_jog (utónév, vezetéknév, fizetés, bérelt_dátum) ÉRTÉKEK ('John', 'Doe', 10000.10, to_date ('01 -01-2001 ',' dd-mm-yyyy ')); // ...

Most módosítsuk EmployeeHandler osztály:

public class EmployeeHandler kiterjeszti a BeanListHandler {// ... public EmployeeHandler (Connection con) {super (Employee.class, new BasicRowProcessor (new BeanProcessor (getColumnsToFieldsMap ()))); // ...} public static Map getColumnsToFieldsMap () {Map columnsToFieldsMap = new HashMap (); columnsToFieldsMap.put ("FIRST_NAME", "keresztnév"); columnToFieldsMap.put ("LAST_NAME", "vezetékNév"); columnToFieldsMap.put ("HIRED_DATE", "hiredDate"); return oszlopokToFieldsMap; } // ...}

Figyeljük meg, hogy a Babprocesszor az oszlopok tényleges leképezését mezőkhöz, és csak azokhoz, amelyekkel foglalkozni kell.

Végül teszteljük, hogy minden rendben van-e:

@Test public void givenResultHandler_whenExecutingQuery_thenAllPropertiesSetted () dobja az SQLException {EmployeeHandler workerHandler = új EmployeeHandler (kapcsolat); QueryRunner runner = új QueryRunner (); Karakterlánc lekérdezés = "KIVÁLASZTÁS * FROM alkalmazott_joggal"; Az alkalmazottak listája = runner.query (kapcsolat, lekérdezés, workerHandler); assertEquals ((int) alkalmazottak.get (0) .getId (), 1); assertEquals (alkalmazottak.get (0) .getFirstName (), "John"); }

5. Rekordok beszúrása

A QueryRunner osztály két megközelítést kínál a rekordok adatbázisban történő létrehozására.

Az első a frissítés () metódust, és adja át az SQL utasítást és a csereparaméterek opcionális listáját. A metódus visszaadja a beillesztett rekordok számát:

@Test public void whenInserting_thenInserted () SQLException dobja {QueryRunner runner = new QueryRunner (); Karakterlánc insertSQL = "INSERT INTO alkalmazó (utónév, vezetéknév, fizetés, bérleti dátum)" + "ÉRTÉKEK (?,?,?,?)"; int numRowsInserted = runner.update (kapcsolat, insertSQL, "Leia", "Kane", 60000.60, új Dátum ()); assertEquals (numRowsInserted, 1); }

A második a beillesztés () módszer, amelyhez az SQL utasításon és a helyettesítő paramétereken túl a ResultSetHandler a keletkező automatikusan generált kulcsok átalakításához. A visszatérési érték lesz az, amit a kezelő visszaad:

@Test public void givenHandler_whenInserting_thenExpectedId () dobja az SQLException {ScalarHandler scalarHandler = új ScalarHandler (); QueryRunner runner = új QueryRunner (); Karakterlánc insertSQL = "INSERT INTO alkalmazó (utónév, vezetéknév, fizetés, bérleti dátum)" + "ÉRTÉKEK (?,?,?,?)"; int newId = runner.insert (kapcsolat, insertSQL, scalarHandler, "Jenny", "Medici", 60000.60, új dátum ()); assertEquals (newId, 6); }

6. Frissítés és törlés

A frissítés () módszere QueryRunner osztály az adatbázisunk rekordjainak módosítására és törlésére is használható.

Használata triviális. Íme egy példa az alkalmazottak fizetésének frissítésére:

@Test public void givenSalary_whenUpdating_thenUpdated () SQLException {dupla fizetés = 35000; QueryRunner runner = új QueryRunner (); Karakterlánc-frissítésSQL = "UPDATE alkalmazotti SET fizetés = fizetés * 1.1 WHERE fizetés <=?"; int numRowsUpdated = runner.update (kapcsolat, updateSQL, fizetés); assertEquals (numRowsUpdated, 3); }

És itt van még egy, hogy törölje a megadott azonosítóval rendelkező alkalmazottat:

@Test public void whenDeletingRecord_thenDeleted () SQLException dob {QueryRunner runner = new QueryRunner (); Karakterlánc deleteSQL = "TÖRLÉS AZ alkalmazottól HOL id =?"; int numRowsDeleted = runner.update (kapcsolat, deleteSQL, 3); assertEquals (numRowsDeleted, 1); }

7. Aszinkron műveletek

A DbUtils biztosítja a AsyncQueryRunner osztály a műveletek aszinkron végrehajtására. Az ebben az osztályban alkalmazott módszerek megfelelnek az QueryRunner osztály, kivéve, hogy visszatérnek a Jövő példa.

Íme egy példa az összes alkalmazott megszerzésére az adatbázisban, legfeljebb 10 másodpercig várva az eredmények eléréséhez:

@Test public void givenAsyncRunner_whenExecutingQuery_thenExpectedList () dobja a Kivételt {AsyncQueryRunner runner = új AsyncQueryRunner (Executors.newCachedThreadPool ()); EmployeeHandler workerHandler = új EmployeeHandler (kapcsolat); Karakterlánc lekérdezés = "SELECT * FROM alkalmazott"; Jövő jövő = runner.query (kapcsolat, lekérdezés, workerHandler); List workerList = future.get (10, TimeUnit.SECONDS); assertEquals (workerList.size (), 5); }

8. Következtetés

Ebben az oktatóanyagban az Apache Commons DbUtils könyvtár legfigyelemreméltóbb szolgáltatásait tártuk fel.

Lekérdeztük az adatokat, és átalakítottuk őket különböző objektumtípusokba, beillesztettük a létrehozott elsődleges kulcsok megszerzéséhez szükséges rekordokat, valamint egy adott kritérium alapján frissített és törölt adatokat. Mi is kihasználtuk a AsyncQueryRunner osztály aszinkron módon hajt végre lekérdezési műveletet.

És mint mindig, a cikk teljes forráskódja megtalálható a Github oldalon.