Gyakorlati alapok III.
SQL (adatbázis)
Alapszintű JDBC-kapcsolódás, lekérdezés és beszúrás
Ismételjük meg az előző fejezetben ismertetett rutinfolyamatot:
-
az adatbázis-meghajtó betöltése - ezt a rutint nevezik driver regisztrációnak is,
-
az adatbázis-kapcsolat kiépítése (Connection),
-
az SQL-művelet végrehajtásához szükséges Statement példány létrehozása, amelyek lehetnek:
-
Statement (statikus utasítás),
-
PreparedStatement (dinamikusan paraméterezett utasítás),
-
CallableStatement (tárolt eljáráshívás),
-
-
az SQL-művelet eredményének feldolgozása (ez az utasítások jellegéből adódóan sokféle lehet, sokszor ResultSet objektummal van feldolgozva),
-
a létrehozott objektum lezárása, ezek lehetnek:
-
ResultSet,
Statement, -
Connection.
-
Most pedig nézzük meg kissé részletesebben:
1.
A letöltött és a projektbe előzőleg becsatlakoztatott meghajtót a következő kóddal aktiváljuk (driver regisztráció):
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
Class.forName(JDBC_DRIVER);
2.
Az adatbázis felé a kapcsolatot (Connection) statikusan deklarált változók és protokollazonosítók segítségével építjük ki:
static final String DataBase_URL =
"jdbc:mysql://localhost/auto";
static final String USER = "root";
static final String PASSWORD = "";
Connection connection = null;
connection = DriverManager.getConnection(DataBase_URL,USER,PASSWORD);
Fontos kiemelnünk a következőket:
jdbc:mysql://localhost/auto
...amelyben:
-
jdbc - főprotokoll,
-
mysql - alprotokoll,
-
localhost - az adatbázis helye,
-
auto - az adatbázis neve.
Az alprotokoll azonosítója más is lehet, hiszen a Java képes egyszerre többféle adatbázis-kezelőt is menedzselni. Például Derby-típusú adatbázisok esetén (ha minden más ugyanaz):
jdbc:derby://localhost/auto
A fenti hivatkozás a következő változatokkal is működőképes (és emlékezzünk vissza: a 3306 a MySQL-szolgáltatás portszáma):
-
jdbc:mysql://localhost:3306/auto
-
jdbc:mysql://127.0.0.1/auto
-
jdbc:mysql://127.0.0.1:3306/auto
3.
Az adatbázis-lekérdezéseket mindig egy Statement objektumon keresztül hajtjuk végre. Itt lép be először egy konkrét SQL-utasítás:
Statement statement = null;
statement = connection.createStatement();
Ez már említett módon háromféleképpen történhet:
-
Statement (statikus utasítás),
-
PreparedStatement (dinamikusan paraméterezett utasítás),
-
CallableStatement (tárolt eljáráshívás).
A Statement osztály által biztosított metódusok a következő jellegű SQL-kommunikációt teszik lehetővé:
-
adatmanipuláció - executeUpdate() - például UPDATE, DELETE,
-
adatdefiníció - executeUpdate() - például CREATE, DROP,
-
lekérdezés - executeQuery() - például SELECT.
Nézzük meg a fenti 2 metódus további részleteit:
-
int executeUpdate(String sql) - egy int típusú egész számot ad vissza, amely az adatmanipulációban érintett rekordok száma,
-
ResultSet executeQuery(String sql) - egy eredménytömböt ad vissza, amely a lekérdezés rekordjait tartalmazza.
4.
Ismételjük meg a lekérdezésekre vonatkozó fenti megállapításainkat:
ResultSet executeQuery(String sql) - egy eredménytömböt ad vissza, amely a lekérdezés rekordjait tartalmazza.
Műveltető Java-kódja:
String sqlString;
sqlString = "...SQL...";
ResultSet resultSet = statement.executeQuery(sqlString);
while(resultSet.next()){...}
Az eredménytömbben a rekordok közti pozícionálást, mozgást egy belső kurzor biztosítja, amelyiket metódusokon keresztül tudunk irányítani:
-
kezdetben a kurzor az 1. rekord elé mutat,
-
next() - szekvenciálisan lép előre a rekordokban, ha már ilyen nincs, false értéket ad vissza,
-
previous() - az előző rekordra lép, ha ilyen nincs, false értéket ad vissza,
-
last() - ha nem üres az eredménytömb, az utolsó rekordra lép, másképp false értéket ad vissza,
-
first() - ha nem üres az eredménytömb, az első rekordra lép, másképp false értéket ad vissza.
5.
A JDBC-kapcsolatban létrehozott objektumokat szabályosan be is kell zárnunk:
-
resultSet.close();
-
statement.close();
-
connection.close();
Ha mindent jól kódoltunk és a szerveroldalon is megfelelő volt az auto nevű adatbázis, abban az auto_csop tábla létrehozása, valamint rekordokkal való feltöltése (A phpMyAdmin című fejezet), akkor a végeredmény hibamentes csatlakozás és lekérdezés lesz...
Kapcsolodas az adatbazishoz...
Statement letesitese...
Autokategoria: NORMAL - Km dij: 80 - Napi dij: 5000
Autokategoria: EXTRA - Km dij: 120 - Napi dij: 7500
Autokategoria: LUXUS - Km dij: 300 - Napi dij: 15000
..amely lényegét tekintve megegyezik előzetes terveinkkel:
AUTO_CSOP
auto_csop_nev |
km_dij |
napi_dij |
NORMAL |
80 |
5000 |
EXTRA |
120 |
7500 |
LUXUS |
300 |
15000 |
Az alábbi bevezető Java-kódban először az executeQuery() függvényt, mint a lekérdezések legfontosabb rutinját használjuk fel. Nézzük meg a fenti rutinfolyamatok összeillesztett kódját:
import java.sql.*;
public class Main {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DataBase_URL =
"jdbc:mysql://localhost/auto";
static final String USER = "root";
static final String PASSWORD = "";
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try{
Class.forName(JDBC_DRIVER);
System.out.println("Kapcsolodas az
adatbazishoz...");
connection =
DriverManager.getConnection(DataBase_URL,USER,PASSWORD);
System.out.println("Statement
letesitese...");
statement =
connection.createStatement();
String sqlString;
sqlString = "SELECT auto_csop_nev,
km_dij, napi_dij FROM auto_csop";
ResultSet resultSet =
statement.executeQuery(sqlString);
System.out.println();
while(resultSet.next()){
String
auto_csop_nev = resultSet.getString("auto_csop_nev");
int km_dij =
resultSet.getInt("km_dij");
int napi_dij
= resultSet.getInt("napi_dij");
System.out.print("Autokategoria: " +
auto_csop_nev + " - Km dij: " + km_dij + " - Napi dij: " + napi_dij);
System.out.println();
}
resultSet.close();
statement.close();
connection.close();
}catch(SQLException se){
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(statement
!= null)
statement.close();
}catch(SQLException se2){
}
try{
if(connection != null)
connection.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("\nViszlat!");
}
}
Végeredmény:
Kapcsolodas az adatbazishoz...
Statement letesitese...
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!
Tapasztalatabbak észrevehetik a Java-kódok közti egyedüli SQL-kódot:
SELECT auto_csop_nev, km_dij, napi_dij FROM auto_csop
Bár az SQL-nyelvet és alapjellemzőit csak a következő fejezetben fogjuk ismertetni, ám ennek ellenére próbáljunk meg még 1 kódot összeállítani, amely a másik, az adatdefiníciós-adatmanipulációs executeUpdate() függvényfajtára épül. Ezen rutin segítségével inzertáljunk még 1 sort az auto_csop táblába. Ennek szabványos SQL-utasítása a következő:
INSERT INTO auto_csop VALUES ('BEYOND','500','20000')
Mivel kíváncsiak vagyunk az inzertálás végeredményére, az executeQuery() függvényt és kódkörnyezeteit újból felhasználjuk, illetve ennek során újrahasznosítjuk az SQL-utasításokat tároló sqlString nevű szövegobjektumot is:
import java.sql.*;
public class Main {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DataBase_URL =
"jdbc:mysql://localhost/auto";
static final String USER = "root";
static final String PASSWORD = "";
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try{
Class.forName(JDBC_DRIVER);
System.out.println("Kapcsolodas az
adatbazishoz...");
connection =
DriverManager.getConnection(DataBase_URL,USER,PASSWORD);
System.out.println("Statement
letesitese...");
statement =
connection.createStatement();
String sqlString;
sqlString = "INSERT INTO auto_csop
VALUES ('BEYOND','500','20000')";
statement.executeUpdate(sqlString);
sqlString = "SELECT auto_csop_nev,
km_dij, napi_dij FROM auto_csop";
ResultSet resultSet =
statement.executeQuery(sqlString);
System.out.println();
while(resultSet.next()){
String
auto_csop_nev = resultSet.getString("auto_csop_nev");
int km_dij =
resultSet.getInt("km_dij");
int napi_dij
= resultSet.getInt("napi_dij");
System.out.print("Autokategoria: " +
auto_csop_nev + " - Km dij: " + km_dij + " - Napi dij: " + napi_dij);
System.out.println();
}
resultSet.close();
statement.close();
connection.close();
}catch(SQLException se){
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(statement
!= null)
statement.close();
}catch(SQLException se2){
}
try{
if(connection != null)
connection.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("\nViszlat!");
}
}
Végeredmény:
Kapcsolodas az adatbazishoz...
Statement letesitese...
Autokategoria: NORMAL - Km dij: 80 - Napi dij: 5000
Autokategoria: EXTRA - Km dij: 120 - Napi dij: 7500
Autokategoria: LUXUS - Km dij: 300 - Napi dij: 15000
Autokategoria: BEYOND - Km dij: 500 - Napi dij: 20000
Viszlat!
Az inzertálás sikeres volt, azonban van itt egy probléma. Ha még egyszer futtatjuk a kódot, az inzertálás újból megtörténik...
Autokategoria: NORMAL - Km dij: 80 - Napi dij: 5000
Autokategoria: EXTRA - Km dij: 120 - Napi dij: 7500
Autokategoria: LUXUS - Km dij: 300 - Napi dij: 15000
Autokategoria: BEYOND - Km dij: 500 - Napi dij: 20000
Autokategoria: BEYOND - Km dij: 500 - Napi dij: 20000
...és így tovább:
Autokategoria: NORMAL - Km dij: 80 - Napi dij: 5000
Autokategoria: EXTRA - Km dij: 120 - Napi dij: 7500
Autokategoria: LUXUS - Km dij: 300 - Napi dij: 15000
Autokategoria: BEYOND - Km dij: 500 - Napi dij: 20000
Autokategoria: BEYOND - Km dij: 500 - Napi dij: 20000
Autokategoria: BEYOND - Km dij: 500 - Napi dij: 20000
Autokategoria: BEYOND - Km dij: 500 - Napi dij: 20000
A nem kívánatos többszörös bejegyzések törölhetők a következő SQL-utasítással:
DELETE FROM auto_csop WHERE auto_csop_nev = 'BEYOND'
A felmerült problémával azonban most nem foglalkozunk tovább, mert ez a tábla speciális jellegéből adódik és feladatunk elsősorban a JDBC és az SQL alapszintű megértése. E célból lapozzunk tehát a következő fejezethez.