4. diel - Databázy v Java JDBC - INSERT, UPDATE, DELETE a COUNT
V minulom dieli nášho seriálu tutoriálov o databázach v Jave sme pomocou JDBC naprogramovali jednoduchý slovníček a naučili sme sa brániť útoku SQL Injection. Dnes budeme s JDBC pokračovať.
Vkladanie, mazanie a editácia hodnôt
Základné databázové operácie sa často označujú skratkou CRUD. Jedná sa o operácie Create (vytvoriť), Read (čítať), Update (aktualizovať), Delete (odstrániť). Minule sme si ukázali operáciu Read. Už vieme, že dáta z databázy čítame príkazom SELECT az Java kolekcie ResultSet.
Insert
Výzva užívateľa na zadanie slovíčka anglicky a česky. Nové slovíčko vložíme do databázy.
Scanner scanner = new Scanner(System.in, "Windows-1250"); System.out.println("Zadej nové slovíčko anglicky:"); String anglicky = scanner.nextLine(); System.out.println("Zadej nové slovíčko česky:"); String cesky = scanner.nextLine(); try (Connection spojeni = DriverManager.getConnection("jdbc:mysql://localhost/slovnicek_db?user=root&password="); PreparedStatement dotaz = spojeni.prepareStatement("INSERT INTO slovo (anglicky, cesky) VALUES (?, ?)");) { dotaz.setString(1, anglicky); dotaz.setString(2, cesky); int radku = dotaz.executeUpdate(); System.out.println(radku); } catch (SQLException ex) { System.out.println("Chyba při komunikaci s databází"); }
SQL dotaz pre vloženie nového riadku do tabuľky začína príkazom INSERT INTO, nasleduje názov tabuľky. V zátvorkách vypíšeme názvy stĺpcov, do ktorých vkladáme hodnoty. Za klauzule VALUES vypíšeme opäť do zátvorky hodnoty. Nemalo by vás prekvapiť, že použijeme opäť parametre.
Otázka spustíme metódou executeUpdate (). Tá sa používa v prípade, keď meníme dáta v databáze. Metóda vracia počet ovplyvnených riadkov, pre overenie, že vloženie prebehlo, si musí byť výpis do konzoly.
ExecuteUpdate () vrátila hodnotu 1. Môžeme spustiť pôvodný kód našej aplikácie, ktorý vypisoval všetky slovíčka alebo k zobrazenie dát použiť NetBeans. Vidíme, že klávesnica je novo medzi slovíčkami:
Dele
Prejdime k mazanie záznamov. Oproti vkladanie nie je v podstate žiadny rozdiel, len som chcel, aby sme si pre úplnosť ukázali všetky otázky z CRUD.
Scanner scanner = new Scanner(System.in, "Windows-1250"); System.out.println("Zadej anglické slovíčko, které chceš vymazat:"); String anglicky = scanner.nextLine(); try (Connection spojeni = DriverManager.getConnection("jdbc:mysql://localhost/slovnicek_db?user=root&password="); PreparedStatement dotaz = spojeni.prepareStatement("DELETE FROM slovo WHERE anglicky=?");) { dotaz.setString(1, anglicky); int radku = dotaz.executeUpdate(); System.out.println(radku); } catch (SQLException ex) { System.out.println("Chyba při komunikaci s databází"); }
Java kód sa vôbec nezmenil. SQL dotaz začína DELETE FROM a pokračuje názvom tabuľky. Nasleduje podmienka WHERE, ktorú už dobre poznáme. Nikdy na podmienku v príkaze DELETE nezabudnite, inak dôjde k vymazaniu všetkých záznamov v tabuľke! Aplikáciu opäť vyskúšajme:
Skontrolujte si, že klávesnica medzi slovíčkami už naozaj nie je. Môžeme skúsiť aj zadať neexistujúce slovíčko k vymazaniu, počet ovplyvnených riadkov bude 0.
Update
Naši štvoricu otázok zakončíme príkazom UPDATE, ktorý vyvolá zmenu. Naučme aplikácii meniť český preklad nejakého anglického slova:
Scanner scanner = new Scanner(System.in, "Windows-1250"); System.out.println("Zadej anglické slovíčko, u kterého chceš upravit překlad:"); String anglicky = scanner.nextLine(); System.out.println("Zadej nový překlad:"); String cesky = scanner.nextLine(); try (Connection spojeni = DriverManager.getConnection("jdbc:mysql://localhost/slovnicek_db?user=root&password="); PreparedStatement dotaz = spojeni.prepareStatement("UPDATE slovo SET cesky=? WHERE anglicky=?");) { dotaz.setString(1, cesky); dotaz.setString(2, anglicky); int radku = dotaz.executeUpdate(); System.out.println(radku); } catch (SQLException ex) { System.out.println("Chyba při komunikaci s databází"); }
Java kód je opäť nezmenený (iba sme pridali parameter). SQL dotaz začína UPDATE, nasleduje názov tabuľky a ďalej klauzula SET. Po nej názov stĺpca, znamienko rovnosti a nová hodnota. Ak by sme potrebovali updatovať viac stĺpcov, zapíšeme to napr. Takto:
UPDATE slovo SET cesky=?, anglicky=? WHERE id=?
Rovnako ako u DELETE nikdy nesmieme zabudnúť na kaluzuli WHERE, inak sa updatuje všetky riadky v tabuľke.
Aplikáciu opäť vyskúšajme:
Skontrolujte si, že sa preklad zmenil.
Počet riadkov
Často nás v našich aplikáciách bude zaujímať počet riadkov v tabuľke. Slúži na to SQL klauzula COUNT. Ukážme si, ako sa používa:
try (Connection spojeni = DriverManager.getConnection("jdbc:mysql://localhost/slovnicek_db?user=root&password="); PreparedStatement dotaz = spojeni.prepareStatement("SELECT COUNT(*) FROM slovo");) { ResultSet vysledek = dotaz.executeQuery(); vysledek.next(); System.out.println(vysledek.getInt(1)); } catch (SQLException ex) { System.out.println("Chyba při komunikaci s databází"); }
K opýtaní na počet riadkov použijeme príkaz SELECT. Klauzula COUNT nám vráti tzv. Agregovanú hodnotu. Agregovaná znamená, že je získaná z viacerých stĺpcov. Takéto hodnoty sú napr. Počet, súčet a priemer. Hviezdička v zátvorke označuje, že nás zaujímajú všetky stĺpce. Ak by sme namiesto nej uviedli názov stĺpca, počítali by sa len tie riadky, kde je tento stĺpec vyplnený (nie je v ňom hodnota NULL). Samozrejme by sme mohli dodať klauzulu WHERE a spočítať len tie riadky, ktoré spĺňajú nejakú podmienku (napr. Anglické slovo začína na A).
Výsledok jednoducho uložíme do ResultSet, metódou next () sa presunieme na prvý riadok a vypíšeme prvý stĺpec.
výsledok:
Bez znalosti klauzula COUNT by vás možno napadlo napísať takýto kód:
// Tento kód je neefektivní try (Connection spojeni = DriverManager.getConnection("jdbc:mysql://localhost/slovnicek_db?user=root&password="); PreparedStatement dotaz = spojeni.prepareStatement("SELECT * FROM slovo");) { ResultSet vysledek = dotaz.executeQuery(); vysledek.last(); System.out.println(vysledek.getRow()); } catch (SQLException ex) { System.out.println("Chyba při komunikaci s databází"); }
Z databázy vyberieme všetky slovíčka, ktoré sa prenesú do našej aplikácie. Metódou last () sa v ResultSet presunieme na posledný riadok a potom vrátime jeho číslo. Nutne dostaneme počet riadkov v tabuľke.
Vrátený výsledok je síce rovnaký, takže by sa mohlo zdať, že je všetko v poriadku. Ale ono nie je. Prenos dát zaberie nejaký čas a tiež je potrebné ich mať v pamäti. Nakoniec len riadky spočítame a dáta ani nepoužijeme. Predstavte si, že je v slovníčku milión slovíčok. To naozaj nie je efektívne riešenie.
Ešte sme nespomenuli použitie spätných úvodzoviek v dotazoch. Ak názov nejakého stĺpca koliduje s kľúčovým slovom z SQL (napr. Sa stĺpec volá where), dáme ho do spätných úvodzoviek. Píšu sa tou klávesou pod escape. Často sa Seta s konvencií, kde sa takto označujú všetky názvy:
UPDATE `slovo` SET `cesky`=?, `anglicky`=? WHERE `id`=?
Dnešný projekt je so zdrojovými kódmi ako vždy v prílohe k stiahnutiu.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 287x (17.35 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java