Gyakorlati alapok III.
SQL (adatbázis)
JDBC-kapcsolódás és lekérdezés több osztállyal
A jelen fejezetben a nagyjából "szabványos", azaz az objektumorientált kódot tanulmányozhatjuk. Kisebb-nagyobb eltérések lehetnek, de a kódfunkciók lényegüket tekintve ilyen módon szétosztottak. A nyilvánvalóan objektumorientált alapokon nyugvó JDBC egyik fontos jellemzője, hogy a kódfunkciók külön-külön osztályt fognak kapni. Mindehhez hangsúlyozottan nem tartozik hozzá a felhasználói felület, illetve tágabb összefüggésben a kód egyszerűsége miatt nem felel meg az MVC-modell követelményeinek sem. Tehát a fejezet kódja egy, az objektumorientált irányelveknek megfelelő, kódszervezettségi szempontból azonban csak középszinten álló alkotás.
Emlékezzünk vissza az eddigi kódfunkciókra, kódrutinokra:
-
connection - kapcsolódás az adatbázishoz,
-
statement - SQL-utasítás aktiválása,
-
resultSet - az eredménytömb menedzselése.
Ehhez fog még jönni +1 osztály, amely 1 táblát fog reprezentálni. Ez egyébként alapelvárás, azaz minden táblának kötelezően külön osztállyal kell rendelkeznie.
Mindebből következően 4 db osztályunk fog keletkezni:
-
Main.java - a benne lévő main() kevés, de annál fontosabb függvényhívást tartalmaz, hiszen konrétan ez indítja be az osztályok futtatását,
-
ConnectionFactory.java - ez az osztály felel az adatbázishoz való kapcsolódásért és a kapcsolódás során fellépő hibákért (a kivételkezelést lehetett volna még külön osztályba tenni, a jelen kódban ettől most eltekintettem),
-
Auto_csop.java - a már megismert auto_csop tábla Java-osztálybeli reprezentációja. Az objektumorientált alapelveknek megfelelően belső adatai kívülről nem láthatók (private), azok csakis getter-setter függvényeken keresztül érhetők el.
-
DAO_Auto_csop.java - (DAO - Data Access Object) egy tervezési mintának konkrét osztály-implementációja. A DAO lényege, hogy teljességel szétválasztja az üzleti logikát (az adatok keletkezését, valamint feldolgozását) az adatok tárolásának logikájától. (Gondoljunk bele, hogy mennyire logikus lépés ez, hiszen lehet a 2 architektúra akár különböző földrészeken is.) Ehhez a DAO az összes lehetséges adatelérési és adatmanipulációs műveletet tartalmazza, az üzleti logikát képviselő komponensek viszont kizárólag csakis a rájuk jellemző műveleteket hajtják végre. Mindezen funkciószétosztás azért kiemelten előnyös, mert bármilyen adatbázis-szerveroldali változás esetén csakis a DAO-komponenseket kell módosítani, az üzleti logika változatlan maradhat. Legegyszerűbb (és egyúttal a jelen) esetben egy DAO-osztály egyetlen adattáblával tartja a kapcsolatot és végez rajta műveleteket. Ezek általánosságban lehetnek:
-
új rekord felvitele,
-
összes rekord lekérdezése,
-
keresési műveletek,
-
szűrések,
-
sőt: adatbázis-kapcsolatra vonatkozó műveletek.
-
Nézzük meg a módosított Java-kódot:
Main.java
public class Main {
public static void main(String[] args) {
System.out.println("Kezdes OK!");
DAO_Auto_csop dao_Auto_csop = new DAO_Auto_csop();
dao_Auto_csop.getData();
}
}
ConnectionFactory.java
import java.sql.*;
public class ConnectionFactory {
public static final String URL =
"jdbc:mysql://localhost/auto";
public static final String USER = "root";
public static final String PASSWORD = "";
private static Connection connection = null;
public static Connection getConnection(){
if (connection == null) {
try {
connection =
DriverManager.getConnection(URL, USER, PASSWORD);
} catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
throw new
RuntimeException("Error connecting to the database", ex);
}
}
return connection;
}
}
Auto_csop.java
public class Auto_csop {
private String auto_csop_nev;
private Integer km_dij;
private Integer napi_dij;
public Auto_csop() {}
public Auto_csop(String auto_csop_nev, Integer km_dij, Integer napi_dij) {
this.auto_csop_nev = auto_csop_nev;
this.km_dij = km_dij;
this.napi_dij = napi_dij;
}
public String getAuto_csop_nev() {
return auto_csop_nev;
}
public void setAuto_csop_nev(String auto_csop_nev) {
this.auto_csop_nev = auto_csop_nev;
}
public Integer getKm_dij() {
return km_dij;
}
public void setKm_dij(Integer km_dij) {
this.km_dij = km_dij;
}
public Integer getNapi_dij() {
return napi_dij;
}
public void setNapi_dij(Integer napi_dij) {
this.napi_dij = napi_dij;
}
}
DAO_Auto_csop.java
import java.sql.*;
public class DAO_Auto_csop {
public void getData() {
Connection connection = ConnectionFactory.getConnection();
System.out.println("Connection OK!");
try {
Statement statement =
connection.createStatement();
System.out.println("Statement OK!");
ResultSet resultSet =
statement.executeQuery("SELECT * FROM auto_csop");
System.out.println("Query
starting!");
while(resultSet.next()){
Auto_csop
auto_csop = new Auto_csop();
auto_csop.setAuto_csop_nev(resultSet.getString("auto_csop_nev"));
auto_csop.setKm_dij(resultSet.getInt("km_dij"));
auto_csop.setNapi_dij(resultSet.getInt("napi_dij"));
System.out.print("Autokategoria: " + auto_csop.getAuto_csop_nev()
+ " - Km dij: " + auto_csop.getKm_dij() + " - Napi dij: " +
auto_csop.getNapi_dij());
System.out.println();
}
resultSet.close();
statement.close();
connection.close();
System.out.println("\nViszlat!");
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
Végeredmény:
Kezdes OK!
Connection OK!
Statement OK!
Query starting!
Autokategoria: NORMAL - Km dij: 80 - Napi dij: 5000
Autokategoria: EXTRA - Km dij: 120 - Napi dij: 7500
Autokategoria: LUXUS - Km dij: 300 - Napi dij: 15000
Viszlat!