Rozdiel medzi výpisom a pripraveným vyhlásením

Java Top

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

1. Prehľad

V tomto výučbe sa pozrieme na rozdiely medzi JDBC Vyhlásenie a Pripravené vyhlásenie rozhrania. Nebudeme kryť Vyvolateľné vyhlásenie, rozhranie JDBC API, ktoré sa používa na vykonávanie uložených procedúr.

2. Rozhranie JDBC API

Oboje Vyhlásenie a Pripravené vyhlásenie možno použiť na vykonávanie dotazov SQL. Tieto rozhrania vyzerajú veľmi podobne. Vo vlastnostiach a výkone sa však navzájom výrazne líšia:

  • Vyhlásenie Používa sa na vykonávanie reťazcového SQL dotazy
  • Pripravené vyhlásenie Používa sa na vykonávanie parametrizovaných dotazov SQL

Byť schopný používať Vyhlásenie a Pripravené vyhlásenie v našich príkladoch vyhlásime h2 JDBC konektor ako závislosť v našom pom.xml spis:

 com.h2database h2 1.4.200 

Definujme entitu, ktorú budeme používať v tomto článku:

public class PersonEntity {private int id; súkromné ​​meno reťazca; // štandardní zakladatelia a obstarávatelia}

3. Vyhlásenie

Po prvé, Vyhlásenie rozhranie prijíma reťazce ako dotazy SQL. Teda kód sa stáva menej čitateľný keď zreťazíme reťazce SQL:

public void insert (PersonEntity personEntity) {String query = "INSERT INTO persons (id, name) VALUES (" + personEntity.getId () + ", '" + personEntity.getName () + "')"; Vyhlásenie vyhlásenie = connection.createStatement (); statement.executeUpdate (dopyt); }

Po druhé, je zraniteľný voči vloženiu SQL . Nasledujúce príklady ilustrujú túto slabinu.

V prvom riadku aktualizácia nastaví stĺpec „názov”Vo všetkých riadkoch do“hacker“, Keďže všetko po„ - “bude interpretované ako komentár v SQL a podmienky príkazu update budú ignorované. V druhom riadku vloženie zlyhá, pretože úvodzovka „názov”Stĺpec nebol uniknutý:

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

Po tretie, JDBC odovzdá dotaz s vloženými hodnotami do databázy. Preto neexistuje optimalizácia dotazov, a čo je najdôležitejšie, databázový stroj musí zabezpečiť všetky kontroly. Dotaz sa tiež v databáze a databáze nezobrazí rovnako zabráni to použitiu cache. Podobne je potrebné osobitne vykonať dávkové aktualizácie:

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

Po štvrté, the Vyhlásenie rozhranie je vhodné pre DDL dotazy ako CREATE, ALTER a DROP :

public void createTables () {String query = "vytvoriť tabuľku, ak neexistuje, OSOBY (ID INT, NÁZOV VARCHAR (45))"; connection.createStatement (). executeUpdate (dopyt); }

Nakoniec the Vyhlásenie rozhranie nemožno použiť na ukladanie a načítanie súborov a polí.

4. Pripravené vyhlásenie

Po prvé, Pripravené vyhlásenie rozširuje Vyhlásenie rozhranie. Má metódy na viazanie rôznych typov objektov, vrátane súborov a polí. Teda kód sa staneľahko pochopiteľné:

public void insert (PersonEntity personEntity) {String query = "INSERT INTO persons (id, name) VALUES (?,?)"; PreparedStatement readyStatement = connection.prepareStatement (dopyt); readyStatement.setInt (1, personEntity.getId ()); readyStatement.setString (2, personEntity.getName ()); readyStatement.executeUpdate (); }

Po druhé, chráni pred vložením SQL, uniknutím textu pre všetky poskytnuté hodnoty parametrov:

@Test void whenInsertAPersonWithQuoteInText_thenItNeverThrowsAnException () {assertDoesNotThrow (() -> dao.insert (new PersonEntity (1, "O'Brien"))); } @Test void whenAHackerUpdateAPerson_thenItUpdatesTheTargetedPerson () hodí SQLException {dao.insert (Arrays.asList (new PersonEntity (1, "john"), new PersonEntity (2, "skeet"))); dao.update (nová PersonEntity (1, "hacker '-")); Výsledok zoznamu = dao.getAll (); assertEquals (Arrays.asList (nový PersonEntity (1, "hacker '-"), nový PersonEntity (2, "skeet")), výsledok); }

Po tretie, Pripravené vyhlásenie používa predkompiláciu. Hneď ako databáza získa dotaz, pred predbežným zostavením dotazu skontroluje medzipamäť. V dôsledku toho ak nie je uložený v pamäti, databázový stroj ho uloží na ďalšie použitie.

Navyše, táto funkcia urýchľuje komunikáciu medzi databázou a JVM prostredníctvom binárneho protokolu iného ako SQL. To znamená, že v paketoch je menej dát, takže komunikácia medzi servermi prebieha rýchlejšie.

Po štvrté, Pripravené vyhlásenie poskytuje dávkové vykonávanie počas jedného databázového pripojenia. Uvidíme v akcii:

public void insert (List personEntities) throws SQLException {String query = "INSERT INTO persons (id, name) VALUES (?,?)"; PreparedStatement readyStatement = connection.prepareStatement (dopyt); pre (PersonEntity personEntity: personEntities) {readyStatement.setInt (1, personEntity.getId ()); readyStatement.setString (2, personEntity.getName ()); readyStatement.addBatch (); } readyStatement.executeBatch (); }

Ďalej Pripravené vyhlásenie poskytuje jednoduchý spôsob ukladania a načítania súborov pomocou BLOB a CLOB dátové typy. V rovnakom duchu pomáha ukladať zoznamy konverziou java.sql.Array na pole SQL.

A nakoniec Pripravené vyhlásenie implementuje metódy ako getMetadata () ktoré obsahujú informácie o vrátenom výsledku.

5. Záver

V tomto tutoriáli sme predstavili hlavné rozdiely medzi nimi Pripravené vyhlásenie a Vyhlásenie. Obe rozhrania ponúkajú metódy na vykonávanie dotazov SQL, ale je vhodnejšie ich použiť Vyhlásenie pre dotazy DDL a Pripravené vyhlásenie pre dotazy DML.

Ako obvykle sú všetky príklady kódov k dispozícii na GitHub.

Java dole

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

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