Különbség a kimutatás és az elkészített állítás között

Java Top

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

1. Áttekintés

Ebben az oktatóanyagban megvizsgáljuk a JDBC közötti különbségeket Nyilatkozat és PreparedStatement interfészek. Nem fogunk fedezni CallableStatement, egy JDBC API interfész, amelyet a tárolt eljárások végrehajtására használnak.

2. JDBC API interfész

Mindkét Nyilatkozat és PreparedStatement SQL lekérdezések végrehajtására használható. Ezek az interfészek nagyon hasonlóak. Tulajdonságai és teljesítménye azonban jelentősen eltér egymástól:

  • Nyilatkozat Karakterlánc-alapú SQL végrehajtására szolgál lekérdezések
  • PreparedStatement Paraméterezett SQL lekérdezések végrehajtására szolgál

Ahhoz, hogy használni tudja Nyilatkozat és PreparedStatement példáinkban kijelentjük a h2 JDBC csatlakozó, mint függőség a mi pom.xml fájl:

 com.h2adatbázis h2 1.4.2004 

Határozzunk meg egy entitást, amelyet a cikkben használunk:

public class PersonEntity {private int id; privát karakterlánc neve; // szabványos beállítók és szerelők}

3. Nyilatkozat

Először is a Nyilatkozat interfész elfogadja a karakterláncokat SQL lekérdezésekként. Így, a kód kevésbé lesz olvasható amikor összefűzzük az SQL karakterláncokat:

public void insert (PersonEntity personEntity) {String query = "INSERT INTO persons (id, name) VALUES (" + personEntity.getId () + "," "+ personEntity.getName () +" ') "; Statement utasítás = connection.createStatement (); utasítás.executeUpdate (lekérdezés); }

Másodszor, kiszolgáltatott az SQL injekcióval szemben . A következő példák ezt a gyengeséget szemléltetik.

Az első sorban a frissítés a “név”Minden sorban a„hackerA „, mivel a„ - ”után bármit értelmezünk kommentként az SQL-ben, és a frissítési utasítás feltételeit figyelmen kívül hagyjuk. A második sorban a beszúrás nem fog sikerülni, mert a „név”Oszlopot nem sikerült megúszni:

dao.update (új PersonEntity (1, "hacker '-")); dao.insert (új PersonEntity (1, "O'Brien"))

Harmadszor, A JDBC továbbítja a lekérdezést inline értékekkel az adatbázisba. Ezért nincs lekérdezés optimalizálás, és ami a legfontosabb, az adatbázis-motornak biztosítania kell az összes ellenőrzést. Ezenkívül a lekérdezés nem ugyanazként jelenik meg az adatbázisban és megakadályozza a gyorsítótár használatát. Hasonlóképpen, a kötegelt frissítéseket külön kell végrehajtani:

public void insert (List personEntities) {for (PersonEntity personEntity: personEntities) {insert (personEntity); }}

Negyedszer: a Nyilatkozat interfész alkalmas olyan DDL lekérdezésekre, mint a CREATE, ALTER és a DROP :

public void createTables () {String query = "táblázat létrehozása, ha még nem létezik PERSONS (ID INT, VARCHAR NÉV (45))"; connection.createStatement (). executeUpdate (lekérdezés); }

Végül, a Nyilatkozat Az interfész nem használható fájlok és tömbök tárolására és visszakeresésére.

4. PreparedStatement

Először is a PreparedStatement kiterjeszti a Nyilatkozat felület. Módszerei vannak a különböző objektumtípusok megkötésére, beleértve a fájlokat és tömböket. Ennélfogva, a kód leszkönnyen érthető:

public void insert (PersonEntity personEntity) {String query = "INSERT INTO persons (id, név) ÉRTÉKEK (?,?)"; PreparedStatement parengtaStatement = connection.prepareStatement (lekérdezés); készítettStatement.setInt (1, personEntity.getId ()); sagatavStatement.setString (2, personEntity.getName ()); PreparStatement.executeUpdate (); }

Másodszor, véd az SQL injekciótól, kikerülve az összes megadott paraméterérték szövegét:

@Test void whenInsertAPersonWithQuoteInText_thenItNeverThrowsAnException () {assertDoesNotThrow (() -> dao.insert (new PersonEntity (1, "O'Brien"))); } @Test void whenAHackerUpdateAPerson_thenItUpdatesTheTargetedPerson () SQLException {dao.insert (Arrays.asList (new PersonEntity (1, "john"), new PersonEntity (2, "skeet"))) dob; dao.update (új PersonEntity (1, "hacker '-")); Lista eredménye = dao.getAll (); assertEquals (Arrays.asList (új PersonEntity (1, "hacker '-"), új PersonEntity (2, "skeet")), eredmény); }

Harmadszor, a PreparedStatement előzetes összeállítást használ. Amint az adatbázis lekérdezést kap, ellenőrzi a gyorsítótárat, mielőtt előre lefordítaná a lekérdezést. Következésképpen, ha nincs gyorsítótárban, akkor az adatbázis-motor elmenti a következő használatra.

Ráadásul, ez a szolgáltatás felgyorsítja az adatbázis és a JVM közötti kommunikációt nem SQL bináris protokollon keresztül. Vagyis kevesebb adat van a csomagokban, így a kommunikáció a szerverek között gyorsabban megy.

Negyedszer, a PreparedStatement kötegelt végrehajtást biztosít egyetlen adatbázis-kapcsolat során. Lássuk ezt működés közben:

public void insert (List personEntities) dobja az SQLException {String lekérdezés = "INSERT INTO személyek (id, név) ÉRTÉKEK (?,?)"; PreparedStatement paruošStatement = connection.prepareStatement (lekérdezés); for (PersonEntity personEntity: personEntities) {sagatavStatement.setInt (1, personEntity.getId ()); sagatavStatement.setString (2, personEntity.getName ()); készítettStatement.addBatch (); } sagatavStatement.executeBatch (); }

Ezután a PreparedStatement egyszerű módot kínál a fájlok tárolására és letöltésére a használatával FOLT és CLOB adattípusok. Ugyanebben az értelemben segít átalakítani a listákat java.sql.Array SQL tömbre.

Végül a PreparedStatement olyan módszereket valósít meg, mint getMetadata () amelyek információkat tartalmaznak a visszaküldött eredményről.

5. Következtetés

Ebben az oktatóanyagban bemutattuk a fő különbségeket PreparedStatement és Nyilatkozat. Mindkét felület kínál módszereket az SQL lekérdezések végrehajtására, de alkalmasabb a használatára Nyilatkozat DDL lekérdezésekhez és PreparedStatement DML lekérdezésekhez.

Szokás szerint az összes kódpélda elérhető a GitHubon.

Java alsó

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