update personne
set age = age + 1
where nom = 'Jeanne'
import java.sql.*;
public class ModernJdbcExample {
private static final String DB_URL = "jdbc:oracle:thin:@oracle-db:1521/MYPDB";
private static final String USER = "PH";
private static final String PASS = "MySuperPassword2024";
public static void main(String[] args) {
var sql = "UPDATE personne SET age = age + 1 WHERE nom = ?";
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, "Jeanne");
int updatedRows = stmt.executeUpdate();
System.out.printf("Updated %d rows%n", updatedRows);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
getConnection
:jdbc:oracle:drivertype:user/password@database
tnsnames.ora
host:port:sid
, SQL*Net// A l'ancienne
Connection c = DriverManager.getConnection(url);
// Version moderne avec DataSource
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:orcl");
config.setUsername("user");
config.setPassword("password");
config.setMaximumPoolSize(10);
return new HikariDataSource(config);
}
// Utilisation
try (Connection conn = dataSource.getConnection()) {
// Utilisation de la connexion
}
getConnection
(Connection : interface)conn.setAutoCommit(false);
conn.commit();
conn.rollback();
finally
.try (Connection conn = DriverManager.getConnection(url, user, pass)) {
conn.setAutoCommit(false);
try (PreparedStatement stmt1 = conn.prepareStatement(
"INSERT INTO commandes (id, client) VALUES (?, ?)");
PreparedStatement stmt2 = conn.prepareStatement(
"INSERT INTO details (commande_id, produit, quantite) VALUES (?, ?, ?)")) {
stmt1.setInt(1, 101);
stmt1.setString(2, "Client A");
stmt1.executeUpdate();
stmt2.setInt(1, 101);
stmt2.setString(2, "Produit X");
stmt2.setInt(3, 5);
stmt2.executeUpdate();
conn.commit();
} catch (SQLException e) {
conn.rollback(); // Annule toutes les opérations
e.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
}
rollback()
rétablit l'état initial.commit()
ou rollback()
.try-with-resources
pour fermer les connexions.setAutoCommit
uniquement quand nécessaire.void close() throws SQLException
try-with-resources
pour fermer les
connexions (ou utiliser du pooling de connexions).
select
: récupération du résultat (curseur)select
Statement createStatement() throws SQLException
PreparedStatement
même pour les
requêtes non paramétrées afin de maintenir une base de code cohérente et d'éviter les
risques de sécurité potentiels.
int executeUpdate(String sql) throws SQLException
insert
, update
,
delete
sql
: sans le point-virgule de SQL*Plustry-with-resources
pour fermer automatiquement les
connexions.
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement stmt = conn.prepareStatement(...)) {
// Travail avec la base
} catch (SQLException e) {
e.printStackTrace();
}
PreparedStatement
pour éviter les injections SQL.PreparedStatement
pour les ordres SQL (paramétrés
ou non)
Class.forName()
depuis JDBC 4.0+jdbc:oracle:thin:@localhost:1521/ORCL
jdbc:postgresql://localhost:5432/mabase
jdbc:mysql://localhost:3306/mabase
SQLException
:
throws SQLException
si pas géréetry {
... appel JDBC ...
} catch (SQLException e) {
... e ...
}
catch (Exception)
Statement s = c.createStatement();
ResultSet rset =
s.executeQuery(
"select dest, jour from train " +
"where client = 'Cassavetes' order by dest");
rset.next();
System.out.println("Cassavetes va à " + rset.getString(1) +
" le jour " + rset.getInt("JOUR"));
rset.close();
s.close();
var sql = """
SELECT dest, jour
FROM train
WHERE client = 'Cassavetes'
ORDER BY dest""";
try (var conn = dataSource.getConnection();
var stmt = conn.prepareStatement(sql);
var rs = stmt.executeQuery()) {
if (rs.next()) {
log.info("Cassavetes va à {} le jour {}",
rs.getString("dest"),
rs.getInt("jour"));
}
} catch (SQLException e) {
log.error("Query failed", e);
throw new DatabaseException("Failed to fetch train journey", e);
}
close()
ou lors de la fermeture de l'ordreStatement
ou PreparedStatement
en fonction du besoin.
executeQuery
.ResultSet
, représentant les résultats de la requête.next()
.ResultSet
et le Statement
pour libérer les ressources.
// A l'ancienne
ResultSet rset = stmt.executeQuery(
"SELECT nom FROM personne");
while (rset.next()) {
System.out.println(rset.getString("nom"));
}
rset.close();
stmt.close();
// Modern JDBC Query
String sql = "SELECT nom FROM personne";
try (var conn = dataSource.getConnection();
var stmt = conn.prepareStatement(sql);
var rs = stmt.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("nom"));
}
}
PreparedStatement stmt = conn.prepareStatement(
"UPDATE personne SET age = age + 1 WHERE nom = ?");
stmt.setString(1, "Jeanne");
stmt.executeUpdate();
public void incrementAge(String nom) {
String sql = "UPDATE personne SET age = age + 1 WHERE nom = ?";
try (Connection conn = dataSource.getConnection()) {
conn.setAutoCommit(false);
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, nom);
int updatedRows = stmt.executeUpdate();
if (updatedRows == 0) {
throw new EntityNotFoundException("Personne non trouvée : " + nom);
}
conn.commit();
logger.debug("Âge incrémenté pour : {}", nom);
} catch (Exception e) {
conn.rollback();
throw new DatabaseException("Erreur lors de la mise à jour de l'âge", e);
}
}
}
Statement s = c.createStatement();
ResultSet rset =
s.executeQuery(
"select dest, jour from train " +
"where client = 'Cassavetes' order by dest");
rset.next();
System.out.println("Cassavetes va à " + rset.getString(1) +
" le jour " + rset.getInt("JOUR"));
if (rset.next())
System.out.println("Cassavetes va à " + rset.getString(1) +
" le jour " + rset.getInt("JOUR"));
rset.close();
s.close();
var sql = """
SELECT dest, jour
FROM train
WHERE client = 'Cassavetes'
ORDER BY dest""";
try (var conn = dataSource.getConnection();
var stmt = conn.prepareStatement(sql);
var rs = stmt.executeQuery()) {
if (rs.next()) {
log.info("Cassavetes va à {} le jour {}",
rs.getString("dest"),
rs.getInt("jour"));
if (rs.next()) {
log.info("Cassavetes va à {} le jour {}",
rs.getString("dest"),
rs.getInt("jour"));
}
}
} catch (SQLException e) {
log.error("Query failed", e);
throw new DatabaseException("Failed to fetch train journeys", e);
}
Statement s = c.createStatement();
ResultSet rset = s.executeQuery(...);
while (rset.next()) {
System.out.println(rset.getString(1));
}
rset.close();
s.close();
var sql = "SELECT dest FROM train WHERE client = 'Cassavetes'";
try (var conn = dataSource.getConnection();
var stmt = conn.prepareStatement(sql);
var rs = stmt.executeQuery()) {
while (rs.next()) {
log.info("Destination: {}", rs.getString("dest"));
}
} catch (SQLException e) {
log.error("Query failed", e);
throw new DatabaseException("Failed to fetch destinations", e);
}
select
: récupération du résultat (curseur)Catégories :
Déroulement :
where
paramétré par le nom de la personnePreparedStatement stmt = conn.prepareStatement(
"update personne set age = age+1 where nom = ?");
stmt.setString(1, "Jeanne");
stmt.executeUpdate();
Connection
:PreparedStatement prepareStatement(String sql) throws SQLException
setXXX
executeUpdate
si SQL non requêteexecuteQuery
si SQL requêteExemple avec Statement
:
String[] p = {"Jeanne", "Jules"};
Statement stmt = conn.createStatement();
for (int i = 0; i < p.length; i++) {
stmt.executeUpdate(
"""update personne set
age = age+1 where nom = '"""
+ p[i] + "'");
}
Exemple avec PreparedStatement
:
PreparedStatement stmt = conn.prepareStatement(
"""update personne set age = age+1
where nom = ?""");
for (int i = 0; i < p.length; i++) {
stmt.setString(1, p[i]);
stmt.executeUpdate();
}
anniversaire(n varchar)
n
String n = "Jeanne";
CallableStatement stmt = conn.prepareCall("{call anniversaire(?)}");
stmt.setString(1, "Jeanne"); // comme PreparedStatement
stmt.executeUpdate(); // comme PreparedStatement
CallableStatement
hérite de PreparedStatement
public void celebrerAnniversaire(String nom) {
String sql = "{call anniversaire(?, ?)}";
try (Connection conn = dataSource.getConnection();
CallableStatement stmt = conn.prepareCall(sql)) {
stmt.setString(1, nom);
stmt.registerOutParameter(2, Types.INTEGER); // Nouveau âge
stmt.execute();
int nouvelAge = stmt.getInt(2);
logger.info("Anniversaire célébré pour {} - Nouvel âge : {}", nom, nouvelAge);
} catch (SQLException e) {
throw new DatabaseException("Erreur lors de la célébration d'anniversaire", e);
}
}
CREATE PROCEDURE totalVentes(produit_id IN NUMBER, total OUT NUMBER) AS
BEGIN
SELECT SUM(quantite) INTO total FROM ventes WHERE produit = produit_id;
END;
CallableStatement cstmt = conn.prepareCall("{ call totalVentes(?, ?) }");
cstmt.setInt(1, 101); // produit_id
cstmt.registerOutParameter(2, Types.INTEGER); // total
cstmt.execute();
System.out.println("Total des ventes : " + cstmt.getInt(2));
Après exécution :
registerOutParameters
: déclare le type du paramètregetXXX
Exemple d'appel de la fonction âge
:
CallableStatement stmt = conn.prepareCall("{? = call age(?)}");
stmt.setString(2, "Jeanne");
stmt.registerOutParameter(1, Types.INTEGER);
stmt.execute();
System.out.println(stmt.getInt(1));
Statement
PreparedStatement
CallableStatement
String
commit
et rollback
oracle.jdbc.OracleTypes
CallableStatement cstmt = conn.prepareCall("{ ? = call f() }");
...registerOutParameters(1, OracleType.CURSOR)...execute...
ResultSet rset = (ResultSet) cstmt.getObject(1);
// Parcours normal de rset
// Interface DAO
public interface PersonneDAO {
void insert(Personne personne);
Personne findById(int id);
List findAll();
void update(Personne personne);
void delete(int id);
}
// Implémentation
public class PersonneDAOImpl implements PersonneDAO {
private Connection connection;
public PersonneDAOImpl(Connection connection) {
this.connection = connection;
}
@Override
public void insert(Personne personne) {
try (PreparedStatement stmt = connection.prepareStatement(
"INSERT INTO personne (nom, age) VALUES (?, ?)")) {
stmt.setString(1, personne.getNom());
stmt.setInt(2, personne.getAge());
stmt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// Autres méthodes CRUD...
}
public void insertPersonnes(List personnes) {
String sql = "INSERT INTO personne (nom, age, email) VALUES (?, ?, ?)";
try (Connection conn = dataSource.getConnection()) {
conn.setAutoCommit(false);
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
for (Personne p : personnes) {
stmt.setString(1, p.getNom());
stmt.setInt(2, p.getAge());
stmt.setString(3, p.getEmail());
stmt.addBatch();
}
stmt.executeBatch();
conn.commit();
logger.info("{} personnes insérées avec succès", personnes.size());
} catch (Exception e) {
conn.rollback();
throw new DatabaseException("Erreur lors de l'insertion batch", e);
}
}
}
public class DatabaseFactory {
private static final String URL = "jdbc:oracle:thin:@localhost:1521:orcl";
private static final String USER = "user";
private static final String PASSWORD = "password";
private static DatabaseFactory instance;
private DatabaseFactory() {}
public static DatabaseFactory getInstance() {
if (instance == null) {
instance = new DatabaseFactory();
}
return instance;
}
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
public class SimpleConnectionPool {
private List connectionPool;
private List usedConnections = new ArrayList<>();
private static final int INITIAL_POOL_SIZE = 10;
public SimpleConnectionPool(String url, String user, String password) {
connectionPool = new ArrayList<>(INITIAL_POOL_SIZE);
for (int i = 0; i < INITIAL_POOL_SIZE; i++) {
connectionPool.add(createConnection(url, user, password));
}
}
public Connection getConnection() {
if (connectionPool.isEmpty()) {
throw new RuntimeException("Pas de connexions disponibles");
}
Connection connection = connectionPool.remove(connectionPool.size() - 1);
usedConnections.add(connection);
return connection;
}
public void releaseConnection(Connection connection) {
usedConnections.remove(connection);
connectionPool.add(connection);
}
}
// Bon exemple
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(SQL);
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
// Traitement
}
} catch (SQLException e) {
logger.error("Erreur DB", e);
throw new DatabaseException("Erreur lors de la requête", e);
}
// Mauvais exemple - Vulnérable aux injections SQL
String sql = "SELECT * FROM users WHERE username = '" + username + "'";
// Bon exemple
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, username);
// Exemple de batch update
PreparedStatement stmt = conn.prepareStatement(
"INSERT INTO users (name, email) VALUES (?, ?)");
for (User user : users) {
stmt.setString(1, user.getName());
stmt.setString(2, user.getEmail());
stmt.addBatch();
}
stmt.executeBatch();
String sql = "SELECT dest, jour FROM train WHERE client = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, "Cassavetes");
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
String destination = rs.getString("dest");
int jour = rs.getInt("jour");
logger.info("{} va à {} le jour {}", "Cassavetes", destination, jour);
}
}
} catch (SQLException e) {
throw new DatabaseException("Erreur lors de la recherche du trajet", e);
}
public class DatabaseException extends RuntimeException {
public DatabaseException(String message, Throwable cause) {
super(message, cause);
}
}
try {
// Code d'accès à la base
} catch (SQLException e) {
logger.error("Erreur d'accès à la base", e);
throw new DatabaseException("Opération échouée", e);
}
# database.properties
db.url=jdbc:oracle:thin:@localhost:1521:orcl
db.user=${DB_USER}
db.password=${DB_PASSWORD}
db.pool.size=10
db.pool.timeout=30000