2026-10-05
jdbc:h2:tcp://localhost/Gtfs_RMTT;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE avec le nom d’utilisateur sa et un mot de passe vide.Pour illustrer ce cours, nous allons utiliser une base de données qui représente des données de transport (des bus) au format GTFS (General Transit Feed Specification).
Nous utiliserons une extensions de postgresql pour les Systemes d’Information Géographique (SIG) PostGIS qui permet de stocker des données géographiques et de faire des requêtes spatiales.
Les données ouvertes du réseau de transport de la ville de Toulon sont conformes au format GTFS et seront utilisées pour illustrer les concepts de JDBC :
stops: Arrêts et stations
routes: Lignes de transport
trips: Trajets
stop_times: Horaires de passage
docker volume create shared-data
docker run --rm --volume shared-data:/shared-data \
alpine ash -c "mkdir -p /shared-data/gtfs && cd /shared-data/gtfs/ && wget -O gtfs-complet.zip --quiet https://s3.eu-west-1.amazonaws.com/files.orchestra.ratpdev.com/networks/rd-toulon/exports/gtfs-complet.zip && unzip -o *.zip && rm *.zip"shared-data
Archive: gtfs-complet.zip
inflating: agency.txt
inflating: stops.txt
inflating: routes.txt
inflating: trips.txt
inflating: stop_times.txt
inflating: calendar.txt
inflating: calendar_dates.txt
inflating: shapes.txt
inflating: feed_info.txt
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
is_valid_lang_code
is_timezone
calendar
processed 382 rows
calendar_dates
processed 6894 rows
service_days
agency
processed 1 rows
routes
processed 97 rows
trips
processed 11787 rows
frequencies
feed_info
processed 1 rows
shapes
processed 195972 rows
stops
processed 1987 rows
stop_times
processed 387239 rows
docker network ls|grep notebooknet > /dev/null || docker network create notebooknet
docker container ls|grep db > /dev/null && docker stop db
echo "--> Launch DBMS"
docker run --quiet --rm --name db -d \
--env POSTGRES_USER=${DB_USERNAME:-dba} \
--env POSTGRES_PASSWORD=${DB_PASSWORD:-secretsecret} \
--env POSTGRES_DB=${DB_NAME:-notebook-db} \
--volume dbhost-data:/var/lib/postgresql \
--volume shared-data:/shared-data \
--network=notebooknet \
-p 5432:5432 \
postgis/postgis:17-master
docker container exec \
--env PGPASSWORD=secretsecret \
db \
sh -c 'until pg_isready -U dba -d notebook-db; do echo "$(date) - waiting for database to start"; sleep 1; done'
db
--> Launch DBMS
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
e1aae55d9ea96f2a45d27f6046c70c99c1257698cf78e410ce57d295c9518bbc
/var/run/postgresql:5432 - no response
Tue 10 Dec 2024 07:00:07 AM UTC - waiting for database to start
/var/run/postgresql:5432 - no response
Tue 10 Dec 2024 07:00:08 AM UTC - waiting for database to start
/var/run/postgresql:5432 - no response
Tue 10 Dec 2024 07:00:10 AM UTC - waiting for database to start
/var/run/postgresql:5432 - accepting connections
--> Create DB
CREATE DATABASE
--> Populate DB
List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+-------
public | agency | table | dba
public | calendar | table | dba
public | calendar_dates | table | dba
public | feed_info | table | dba
public | frequencies | table | dba
public | routes | table | dba
public | shapes | table | dba
public | spatial_ref_sys | table | dba
public | stop_times | table | dba
public | stops | table | dba
public | trips | table | dba
(11 rows)
# Définition d'une requête SQL pour rechercher les arrêts "Campus"
read -r -d '' QUERY << EOM
SELECT
stop_id, -- Identifiant unique de l'arrêt
stop_name, -- Nom de l'arrêt
stop_loc -- Localisation de l'arrêt, Géométrie PostGIS (format natif)
FROM
stops
WHERE stop_name ILIKE '%Campus%'
LIMIT 3;
EOM
docker run --rm \
--env PGPASSWORD=secretsecret \
--network=notebooknet \
postgres \
psql -h db -U dba gtfs -c $QUERY; stop_id | stop_name | stop_loc
---------+----------------------------+----------------------------------------------------
GACAMN | Campus La Garde/La Valette | 0101000020E6100000F52B9D0FCF121840F7730AF2B3914540
GACAMS | Campus La Garde/La Valette | 0101000020E6100000A06F0B96EA1218401F82AAD1AB914540
HYLAGN | Agricampus | 0101000020E61000006555849B8C9A1840C37E4FAC538F4540
(3 rows)
# Requête SQL pour trouver les arrêts "Université" avec leurs coordonnées GPS
read -r -d '' QUERY << EOM
SELECT
stop_id, -- Identifiant unique de l'arrêt
stop_name, -- Nom de l'arrêt
ST_X(ST_Transform(stop_loc::geometry, 4326)) AS stop_latitude, -- Conversion des coordonnées en latitude (EPSG:4326 = standard GPS)
ST_Y(ST_Transform(stop_loc::geometry, 4326)) AS stop_longitude -- Conversion des coordonnées en longitude (EPSG:4326 = standard GPS)
FROM
stops
WHERE stop_id ILIKE 'GACAM%'
LIMIT 3;
EOM
docker run --rm \
--env PGPASSWORD=secretsecret \
--network=notebooknet \
postgres \
psql -h db -U dba gtfs -c $QUERY; stop_id | stop_name | stop_latitude | stop_longitude
---------+----------------------------+---------------+----------------
GACAMN | Campus La Garde/La Valette | 6.018368 | 43.138304
GACAMS | Campus La Garde/La Valette | 6.018473 | 43.138056
(2 rows)
# Requête SQL pour trouver les arrêts "Université" avec leurs coordonnées GPS
read -r -d '' QUERY << EOM
SELECT
route_id, -- Identifiant unique de la ligne
route_short_name, -- Nom court de la ligne
route_long_name -- Nom long de la ligne
FROM
routes
WHERE route_long_name ILIKE '%Tln%'
LIMIT 3;
EOM
docker run --rm \
--env PGPASSWORD=secretsecret \
--network=notebooknet \
postgres \
psql -h db -U dba gtfs -c $QUERY; route_id | route_short_name | route_long_name
----------+------------------+------------------------------
U | U | Tech.Mer/Pôle d'Act. Tln Est
0102 | 102 | Gare Rte Tln-Aéroport Hyères
0103 | 103 | Gare Rout. Tln-Moulin 1er
(3 rows)
# Requête pour trouver les 3 arrêts les plus proches de l'Université de Toulon
read -r -d '' QUERY << EOM
-- Recherche des arrêts par proximité géographique
SELECT
stop_id, -- Identifiant de l'arrêt
stop_name, -- Nom de l'arrêt
-- Calcul de la distance entre chaque arrêt et l'Université
ROUND(ST_Distance(
stop_loc::geography, -- Position de l'arrêt
ST_SetSRID( -- Définit le système de coordonnées
ST_MakePoint( -- Crée un point géographique
6.016499, -- Longitude Université
43.135440 -- Latitude Université
),
4326 -- En WGS84
)
)) AS distance,
-- Conversion des coordonnées en WGS84 (format GPS standard)
ST_X( -- Extrait la latitude
ST_Transform( -- Convertit les coordonnées
stop_loc::geometry, -- Position de l'arrêt
4326 -- Code EPSG pour WGS84 (standard GPS)
)
) AS LATITUDE,
ST_Y(ST_Transform(stop_loc::geometry, 4326)) AS LONGITUDE -- Idem pour longitude
FROM stops
ORDER BY distance
ASC -- Tri du plus proche au plus éloigné
LIMIT 5 -- Retourne les 5 plus proches
EOM
docker run --rm \
--env PGPASSWORD=secretsecret \
--network=notebooknet \
postgres \
psql -h db -U dba gtfs -c $QUERY; stop_id | stop_name | distance | latitude | longitude
---------+----------------------------+----------+----------+-----------
GAUNSS | Université Sud | 251 | 6.019189 | 43.134341
GAUNSN | Université Sud | 267 | 6.019715 | 43.134955
VACAMS | Campus | 304 | 6.014507 | 43.137753
GACAMS | Campus La Garde/La Valette | 332 | 6.018473 | 43.138056
GAPLAS | Planquette | 338 | 6.017341 | 43.132457
(5 rows)
# Store a query in the QUERY shell variable
read -r -d '' QUERY << EOM
SELECT
s.stop_id AS arret, -- Identifiant de l'arrêt
s.stop_name AS nom_arret, -- Nom de l'arrêt
r.route_short_name AS ligne, -- Numéro de ligne
r.route_long_name AS nom_ligne, -- Nom de la ligne
t.trip_headsign AS destination, -- Destination du voyage
st.departure_time AS depart -- Heure de départ
FROM
stop_times st
JOIN stops s ON st.stop_id = s.stop_id -- Liaison avec les arrêts
JOIN trips t ON st.trip_id = t.trip_id -- Liaison avec les voyages
JOIN routes r ON t.route_id = r.route_id -- Liaison avec les lignes
WHERE
st.stop_id = 'VACAMN'
AND r.route_short_name = 'U'
AND st.departure_time > (NOW()::time) -- Départ après l'heure actuelle
ORDER BY
st.departure_time
LIMIT 3;
EOM
docker run --rm \
--env PGPASSWORD=secretsecret \
--network=notebooknet \
postgres \
psql -h db -U dba gtfs -c $QUERY; arret | nom_arret | ligne | nom_ligne | destination | depart
--------+-----------+-------+------------------------------+----------------------+----------
VACAMN | Campus | U | Tech.Mer/Pôle d'Act. Tln Est | Technopole de la Mer | 07:05:00
VACAMN | Campus | U | Tech.Mer/Pôle d'Act. Tln Est | Technopole de la Mer | 07:10:00
VACAMN | Campus | U | Tech.Mer/Pôle d'Act. Tln Est | Technopole de la Mer | 07:10:00
(3 rows)
# Store a query in the QUERY shell variable
read -r -d '' QUERY << EOM
SELECT
r.route_short_name AS ligne, -- Numéro de ligne
st.arrival_time AS arrivee, -- Heure d'arrivée
st.departure_time AS depart -- Heure de départ
FROM stop_times st
JOIN stops s ON st.stop_id = s.stop_id -- Liaison avec les arrêts
JOIN trips t ON st.trip_id = t.trip_id -- Liaison avec les voyages
JOIN routes r ON t.route_id = r.route_id -- Liaison avec les lignes
WHERE st.stop_id = 'GAUNSS'
LIMIT 3
EOM
docker run --rm \
--env PGPASSWORD=secretsecret \
--network=notebooknet \
postgres \
psql -h db -U dba gtfs -c $QUERY; ligne | arrivee | depart
-------+----------+----------
129 | 06:33:00 | 06:33:00
129 | 07:03:00 | 07:03:00
129 | 07:54:00 | 07:54:00
(3 rows)
Définissons tout d’abord simplement une classe Java pour représenter l’une des entités de l’exemple, un arrêt de bus. Nous utiliserons un record Java (non mutable).
/**
* Représente un arrêt de transport public
*/
public record Stop(
String id, // Identifiant unique
String name, // Nom de l'arrêt
Double latitude, // Latitude
Double longitude, // Longitude
String locationType // arrêt, station
) {
public Stop {
if (id == null || name == null || latitude == null || longitude == null) {
throw new IllegalArgumentException("Required fields cannot be null");
}
}
}/**
* Représente une ligne de transport
*/
public record Route(
String id, // Identifiant unique
String shortName, // Numéro/Code court
String longName // Nom complet
) {
public Route {
if (id == null || shortName == null) {
throw new IllegalArgumentException("Required fields cannot be null");
}
}
}/**
* Représente un voyage sur une ligne
*/
public record Trip(
String id, // Identifiant unique
Route route, // ID de la ligne
String tripHeadsign, // Destination affichée
String tripShortName // Nom court du voyage
) {
public Trip {
if (id == null || route == null || tripHeadsign == null) {
throw new IllegalArgumentException("Required fields cannot be null");
}
}
}import java.time.LocalTime;
/**
* Représente un horaire de passage à un arrêt
*/
public record StopTime(
Trip trip, // ID du voyage
Stop stop, // ID de l'arrêt
LocalTime arrivalTime, // Heure d'arrivée
LocalTime departureTime, // Heure de départ
String stopHeadsign // Destination affichée à l'arrêt
) {
public StopTime {
// Validation des champs obligatoires
if (trip == null || stop == null ||
arrivalTime == null || departureTime == null) {
throw new IllegalArgumentException(
"trip, stop, times are required"
);
}
// Validation de la cohérence des heures
if (departureTime.isBefore(arrivalTime)) {
throw new IllegalArgumentException(
"Departure time cannot be before arrival time"
);
}
}
}StopTime[trip=Trip[id=U_1, route=Route[id=U, shortName=U, longName=Université], tripHeadsign=Université, tripShortName=U1], stop=Stop[id=TOCMAS, name=Champ de Mars, latitude=5.940372, longitude=43.121363, locationType=stop], arrivalTime=08:00, departureTime=08:05, stopHeadsign=Université]
import java.sql.Connection;
import java.sql.DriverManager;
System.out.println("%s connecting on %s.".formatted(DB_USERNAME,DB_URL));
final String query = """
SELECT stop_id,
stop_name,
ST_X(ST_Transform(stop_loc::geometry, 4326)) AS LATITUDE,
ST_Y(ST_Transform(stop_loc::geometry, 4326)) AS LONGITUDE,
location_type
FROM stops
ORDER BY ST_Distance(stop_loc::geometry, ST_SetSRID(ST_MakePoint(5.940207, 43.121145), 4326)) ASC
LIMIT 3""";
try(Connection connection = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);
Statement stmt = connection.createStatement();
) {
ResultSet rs = stmt.executeQuery(query);
long id=0;
while (rs.next())
System.out.println(new Stop(rs.getString("stop_id"),
rs.getString("stop_name"),
rs.getDouble("latitude"),
rs.getDouble("longitude"),
rs.getString("location_type")
));
} catch (SQLException e) {
e.printStackTrace();
} dba connecting on jdbc:postgresql://docker/gtfs.
Stop[id=TOCMAS, name=Champ de Mars, latitude=5.940372, longitude=43.121363, locationType=stop]
Stop[id=TOCMAN, name=Champ de Mars, latitude=5.940497, longitude=43.12208, locationType=stop]
Stop[id=TOPIXO, name=Pie X, latitude=5.941181, longitude=43.120398, locationType=stop]
DriverManager.getConnectionjdbc:mysql://localhost:3306/maBaseDeDonneesjdbc:postgresql://localhost:5432/maBaseDeDonneesjdbc:oracle:thin:@localhost:1521:maBaseDeDonneesjdbc:sqlserver://localhost:1433;databaseName=maBaseDeDonneesjdbc:sqlite:cheminDeLaBaseDeDonneesimport java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
final String DB_URL="jdbc:postgresql://docker/gtfs";
// Nom d'utilisateur et mot de passe de la base de données récupérés depuis les variables d'environnement
final String DB_USERNAME=Optional.of(System.getenv("DB_USERNAME")).orElseThrow(()->new IllegalArgumentException("DB_USERNAME is required"));
final String DB_PASSWORD=Optional.of(System.getenv("DB_PASSWORD")).orElseThrow(()->new IllegalArgumentException("DB_PASSWORD is required"));
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD)) {
// La connexion est établie, vous pouvez interagir avec la base de données ici
} catch (SQLException e) {
// Gestion des exceptions liées à la base de données
e.printStackTrace();
}Pour exécuter des requêtes SQL en Java, on utilise des instances de la classe Statement. Il existe trois types de Statement :
Tous sont créés à partir d’une Connection.
// Create a list to store Stop objects
List<Stop> stops = new ArrayList<>();
final String query = """
SELECT stop_id,
stop_name,
ST_X(ST_Transform(stop_loc::geometry, 4326)) AS LATITUDE,
ST_Y(ST_Transform(stop_loc::geometry, 4326)) AS LONGITUDE,
location_type
FROM stops
ORDER BY ST_Distance(stop_loc::geometry, ST_SetSRID(ST_MakePoint(5.940207, 43.121145), 4326)) ASC
LIMIT 3""";
try(Connection connection = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);
Statement stmt = connection.createStatement();
) {
ResultSet rs = stmt.executeQuery(query);
long id=0;
while (rs.next())
stops.add(new Stop(rs.getString("stop_id"),
rs.getString("stop_name"),
rs.getDouble("latitude"),
rs.getDouble("longitude"),
rs.getString("location_type")
));
} catch (SQLException e) {
e.printStackTrace();
}
stops.forEach(System.out::println); Stop[id=TOCMAS, name=Champ de Mars, latitude=5.940372, longitude=43.121363, locationType=stop]
Stop[id=TOCMAN, name=Champ de Mars, latitude=5.940497, longitude=43.12208, locationType=stop]
Stop[id=TOPIXO, name=Pie X, latitude=5.941181, longitude=43.120398, locationType=stop]
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
Statement statement = connection.createStatement()) {
// SQL query to insert data into the 'agency' table
String sql = """
INSERT INTO agency(agency_id, agency_name, agency_url, agency_timezone,
agency_lang, agency_phone, agency_fare_url, agency_email)
VALUES(3, 'Neverland', 'http://nowhere.fr', 'Europe/Paris',
'fr', '555-555-555', 'http://nowhere.fr/fare', 'neverland@nowhere.org')""";
// Execute the query and get the number of changes
int numberOfChanges = statement.executeUpdate(sql);
// Print the result
System.out.println("Nombre de changements: " + numberOfChanges);
} catch (SQLException e) {
e.printStackTrace();
}Nombre de changements: 1
//|error: true
String wrongQuery = " SELECT * FROM Employee" ;
try (Connection connection = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(wrongQuery)) {
} catch (SQLException e) {
//Erreur lors de la requête
log.severe(e.getMessage());
}try (Connection connection = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(wrongQuery)) {
} catch (SQLException e) {
//Erreur lors de la requête
log.severe(e.getMessage());
}
using incubating module(s): jdk.incubator.vector
log.severe(e.getMessage());
cannot find symbol
symbol: variable log
ResultSet resultSet = statement.executeQuery(wrongQuery)) {
auto-closeable resource resultSet is never referenced in body of corresponding try statement
Types).getXXX() et setXXX().CHAR et VARCHAR : getString().LONGVARCHAR : getAsciiStream() ou getCharacterStream().BINARY et VARBINARY : getBytes().REAL : getFloat(), DOUBLE et FLOAT : getDouble().DECIMAL et NUMERIC : getBigDecimal().DATE (utilisez getDate()), TIME (utilisez getTime()), TIMESTAMP (utilisez getTimestamp()).conn.setAutoCommit(false).conn.commit() pour valider la transaction.conn.rollback().// Déclaration de la requête SQL
String sql = """
SELECT stop_id,
stop_name,
ST_X(ST_Transform(stop_loc::geometry, 4326)) AS LATITUDE,
ST_Y(ST_Transform(stop_loc::geometry, 4326)) AS LONGITUDE,
location_type
FROM stops
WHERE stop_id = ?
ORDER BY ST_Distance(stop_loc::geometry, ST_SetSRID(ST_MakePoint(5.940207, 43.121145), 4326)) ASC
LIMIT 3""";
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
PreparedStatement pstmt = connection.prepareStatement(sql)) {
// Tableau contenant les identifiants à rechercher
String[] ids = {"TOCMAS", "TOCMAN", "TOPIXO"};
for (String id : ids) {
// Remplacer le paramètre de la requête par l'identifiant actuel
pstmt.setString(1, id);
// Exécution de la requête
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
// Création et affichage d'un objet Stop avec les données récupérées
System.out.println(new Stop(rs.getString("stop_id"),
rs.getString("stop_name"),
rs.getDouble("latitude"),
rs.getDouble("longitude"),
rs.getString("location_type")));
}
}
}
} catch (SQLException e) {
// Gestion des exceptions liées à la connexion ou à la requête
e.printStackTrace();
}Stop[id=TOCMAS, name=Champ de Mars, latitude=5.940372, longitude=43.121363, locationType=stop]
Stop[id=TOCMAN, name=Champ de Mars, latitude=5.940497, longitude=43.12208, locationType=stop]
Stop[id=TOPIXO, name=Pie X, latitude=5.941181, longitude=43.120398, locationType=stop]
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD)) {
// Création de la table account
String createAccountTableSql = "CREATE TABLE account (" +
"id SERIAL PRIMARY KEY," +
"name VARCHAR(100) NOT NULL," +
"balance DEC(15,2) NOT NULL)";
try (Statement statement = connection.createStatement()) {
statement.executeUpdate(createAccountTableSql);
}
// Création des comptes pour Alice et Bob avec une requête préparée
String createAccountSql = "INSERT INTO account(name, balance) VALUES(?, ?);";
try (PreparedStatement pstmt = connection.prepareStatement(createAccountSql)) {
pstmt.setString(1, "Bob");
pstmt.setInt(2, 1000);
pstmt.executeUpdate();
pstmt.setString(1, "Alice");
pstmt.setInt(2, 1000);
pstmt.executeUpdate();
}
// Préparation de la requête pour mettre à jour le solde des comptes
String updateAccountSql = "UPDATE account SET balance = balance + ? WHERE id = ?";
try (PreparedStatement pstmtIncreaseAccount = connection.prepareStatement(updateAccountSql)) {
// Sauvegarde de l'état auto-commit
boolean autoCommit = connection.getAutoCommit();
try {
connection.setAutoCommit(false); // Désactivation de l'auto-commit pour la transaction
// Retirer 500€ du compte de Bob
pstmtIncreaseAccount.setInt(1, -500);
pstmtIncreaseAccount.setInt(2, 1); // ID de Bob
pstmtIncreaseAccount.executeUpdate();
// Ajouter 500€ au compte d'Alice
pstmtIncreaseAccount.setInt(1, 500);
pstmtIncreaseAccount.setInt(2, 2); // ID d'Alice
pstmtIncreaseAccount.executeUpdate();
connection.commit(); // Valider la transaction
} catch (SQLException exc) {
connection.rollback(); // Annuler la transaction en cas de problème
throw exc; // Relancer l'exception pour gestion ultérieure
} finally {
connection.setAutoCommit(autoCommit); // Rétablir l'état auto-commit
}
}
// Suppression de la table account
try (Statement statement = connection.createStatement()) {
statement.executeUpdate("DROP TABLE account");
}
} catch (SQLException e) {
e.printStackTrace(); // Gestion des exceptions SQL
}Les procédures stockées sont des sous-programmes stockés dans la base de données qui peuvent être exécutés par un appel direct. Elles permettent d’encapsuler des opérations complexes et de les réutiliser facilement.
Avec JDBC CallableStatement permet d’appeler une procédure stockée directement sur le SGBD.
-- Création d'une procédure stockée pour transférer de l'argent entre comptes
CREATE OR REPLACE PROCEDURE transfer_funds(
from_account INT,
to_account INT,
amount DECIMAL
) AS $$
BEGIN
UPDATE account SET balance = balance - amount WHERE id = from_account;
UPDATE account SET balance = balance + amount WHERE id = to_account;
END;
$$ LANGUAGE plpgsql;// Connexion à la base de données
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD)) {
// Préparation de l'appel à la procédure stockée
String callProcedureSql = "{CALL transfer_funds(?, ?, ?)}";
try (CallableStatement callableStatement = connection.prepareCall(callProcedureSql)) {
// Définition des paramètres de la procédure
callableStatement.setInt(1, 1); // ID du compte source
callableStatement.setInt(2, 2); // ID du compte destination
callableStatement.setBigDecimal(3, new BigDecimal("500.00")); // Montant à transférer
// Exécution de la procédure stockée
callableStatement.execute();
}
} catch (SQLException e) {
e.printStackTrace(); // Gestion des exceptions SQL
}E. Bruno - Accès aux bases de données relationnelles en Java (JDBC)