Rozdiel medzi výpisom a pripraveným vyhlásením
Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:
>> SKONTROLUJTE KURZ1. 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