Insertion données java dans Mysql
Résolu/Fermé
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
-
19 mars 2021 à 01:14
Shielded Messages postés 20 Date d'inscription vendredi 19 mars 2021 Statut Membre Dernière intervention 3 mars 2023 - 20 mars 2021 à 14:19
Shielded Messages postés 20 Date d'inscription vendredi 19 mars 2021 Statut Membre Dernière intervention 3 mars 2023 - 20 mars 2021 à 14:19
A voir également:
- Insertion données java dans Mysql
- Waptrick java football - Télécharger - Jeux vidéo
- Jeux java itel football - Télécharger - Jeux vidéo
- Java apk - Télécharger - Langages
- Insertion liste déroulante excel - Guide
- Insertion sommaire word - Guide
5 réponses
jordane45
Messages postés
38454
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
22 mars 2025
4 740
19 mars 2021 à 06:53
19 mars 2021 à 06:53
Bonjour
Tu as mal écrit ta requête.... Et mal concaténé ta string...
Tu as mal écrit ta requête.... Et mal concaténé ta string...
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
19 mars 2021 à 08:43
19 mars 2021 à 08:43
Bonjour,
Il ne faut jamais faire de concaténation de String pour écrire une requête SQL.
Dans le cas général ça fera ce que tu voudras :
Mais si le nom contient une apostrophe par exemple, ça va faire n'importe quoi :
Cela pourrait même permettre de l'injection SQL, une faille de sécurité qui permettrait de mettre du code SQL dans l'un de tes String et qui viendrait se concaténer à ta requête pour exécuter une toute autre requête.
Exemple avec ce nom :
Ce qui donnerait cette requête, qui va détruire ta base de données :
Pour corriger ça en Java c'est très simple en utilisant des PreparedStatement. Ta requête est écrite avec des paramètres "?" qui seront remplacés par des setString (ou équivalent selon le type des données).
Il ne faut jamais faire de concaténation de String pour écrire une requête SQL.
Dans le cas général ça fera ce que tu voudras :
insert into Client (numeroCartefidelite, nom, prenom, mail, codePostal, nbPointfidelite) values('numeroCartefidelite', 'nom', 'prenom', 'mail', 'codePostal', 'nbPointfidelite');
Mais si le nom contient une apostrophe par exemple, ça va faire n'importe quoi :
insert into Client (numeroCartefidelite, nom, prenom, mail, codePostal, nbPointfidelite) values('numeroCartefidelite', 'Giscard d'Estaing', 'Valéry', 'mail', 'codePostal', 'nbPointfidelite');
Cela pourrait même permettre de l'injection SQL, une faille de sécurité qui permettrait de mettre du code SQL dans l'un de tes String et qui viendrait se concaténer à ta requête pour exécuter une toute autre requête.
Exemple avec ce nom :
"','','',''); drop Client; -- "
Ce qui donnerait cette requête, qui va détruire ta base de données :
insert into Client (numeroCartefidelite, nom, prenom, mail, codePostal, nbPointfidelite) values('numeroCartefidelite', '','','',''); drop Client; -- ', 'prenom', 'mail', 'codePostal', 'nbPointfidelite');
Pour corriger ça en Java c'est très simple en utilisant des PreparedStatement. Ta requête est écrite avec des paramètres "?" qui seront remplacés par des setString (ou équivalent selon le type des données).
PreparedStatement pstmt = con.prepareStatement("insert into Client (numeroCartefidelite, nom, prenom, mail, codePostal, nbPointfidelite) values(?,?,?,?,?,?)"); pstmt.setString(1, numeroCartefidelite); pstmt.setString(2, nom); pstmt.setString(3, prenom); pstmt.setString(4, mail); pstmt.setString(5, codePostal); pstmt.setString(6, nbPointfidelite);
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
1
Modifié le 20 mars 2021 à 12:51
Modifié le 20 mars 2021 à 12:51
Bonjour,
J'ai beaucoup aimé vos explications, je vous en remercie.
Le code que vous avez présenté comme solution insère directement une ligne client dans la bd.
En fait, moi je voudrais encapsuler ça dans une méthode que je pourrai appelez pour chaque instance de Client que je vais créer. Ci-dessous ce que je tente vain:
Erreur signalé : con cannot be resolved
J'ai beaucoup aimé vos explications, je vous en remercie.
Le code que vous avez présenté comme solution insère directement une ligne client dans la bd.
En fait, moi je voudrais encapsuler ça dans une méthode que je pourrai appelez pour chaque instance de Client que je vais créer. Ci-dessous ce que je tente vain:
public void ajouterClient(){ Bd connexion1 = new Bd(); try { String reqclient = "insert into Client (numeroCartefidelite , nom, prenom, mail, codePostal, nbPointfidelite) values(?, ?, ?, ?, ?, ?)"; PreparedStatement prepare = con.prepareStatement(reqclient); prepare.setInt(1, 123); prepare.setString(2, "Test"); prepare.setString(3, "prenom"); prepare.setString(4, "test@test.fr"); prepare.setInt(5, 78140); prepare.setInt(6, 10); prepare.executeUpdate(); System.out.println("insertion fait"); connexion1.fermerconnexion(); } catch (SQLException e) { System.out.println("la connexion a la bd a echoue"); e.printStackTrace(); }
Erreur signalé : con cannot be resolved
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
>
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
19 mars 2021 à 18:17
19 mars 2021 à 18:17
"con cannot be resolved"
Parce que dans mon exemple j'ai considéré que tu avais une Connection con, mais ce n'est pas le cas, toi tu as une Bd connexion1, il va donc falloir récupérer ta connexion à partir de cet objet.
Parce que dans mon exemple j'ai considéré que tu avais une Connection con, mais ce n'est pas le cas, toi tu as une Bd connexion1, il va donc falloir récupérer ta connexion à partir de cet objet.
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
1
19 mars 2021 à 21:33
19 mars 2021 à 21:33
Oui j'ai essayé mais on souligne le prepareStatemenen rouge :
PreparedStatement prepare = connexion1.prepareStatement(reqclient);
Code écrit dans la classe BD pour être ensuite appelé (méthode ajoutClient) dans la classe client
PreparedStatement prepare = connexion1.prepareStatement(reqclient);
Code écrit dans la classe BD pour être ensuite appelé (méthode ajoutClient) dans la classe client
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
>
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
19 mars 2021 à 23:13
19 mars 2021 à 23:13
"on souligne le prepareStatemenen rouge"
Avec quel message ?
Remarque : la classe Bd n'est pas de Java, je ne peux pas deviner comment elle fonctionne sans son code.
Avec quel message ?
Remarque : la classe Bd n'est pas de Java, je ne peux pas deviner comment elle fonctionne sans son code.
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
1
Modifié le 20 mars 2021 à 12:51
Modifié le 20 mars 2021 à 12:51
Le message : The method prepareStatement(String) is undefined for the type Bd
CODE DE LA CLASSE CLIENT: AU LIEU DE Bd
L'idée étant d'appeler la methode ajouterClient() lors de la creation d'une instance dans le main
CODE DE LA CLASSE CLIENT: AU LIEU DE Bd
package memo; import java.sql.PreparedStatement; import java.sql.SQLException; public class Client { private String nom, prenom, mail; private int numeroCartefidelite, codePostal, nbPointfidelite; public Client(int numFidelite, String nom, String prenom, String mail, int cp, int pointFidelite) { this.nom = nom; this.prenom = prenom; this.mail = mail; this.numeroCartefidelite = numFidelite; this.codePostal = cp; this.nbPointfidelite = pointFidelite; } public void ajouterClient(){ Bd connexion1 = new Bd(); try { String reqclient = "insert into Client (numeroCartefidelite , nom, prenom, mail, codePostal, nbPointfidelite) values(?, ?, ?, ?, ?, ?)"; PreparedStatement prepare = connexion1.prepareStatement(reqclient); prepare.setInt(1, 123); prepare.setString(2, "Test"); prepare.setString(3, "prenom"); prepare.setString(4, "test@test.fr"); prepare.setInt(5, 78140); prepare.setInt(6, 10); prepare.executeUpdate(); System.out.println("insertion faite"); connexion1.fermerconnexion(); } catch (SQLException e) { System.out.println("la connexion a la bd a echoue"); e.printStackTrace(); } } }
L'idée étant d'appeler la methode ajouterClient() lors de la creation d'une instance dans le main
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
20 mars 2021 à 10:59
20 mars 2021 à 10:59
Tu fais connexion1.prepareStatement alors que la classe Bd n'a pas de méthode prepareStatement.
Mais je ne peux pas t'aider sans savoir ce que fait ou non la classe Bd... Elle doit forcément manipuler une Connection d'une manière ou d'une autre et c'est là où tu dois te brancher car c'est la classe Connection qui définit la méthode prepareStatement.
Mais je ne peux pas t'aider sans savoir ce que fait ou non la classe Bd... Elle doit forcément manipuler une Connection d'une manière ou d'une autre et c'est là où tu dois te brancher car c'est la classe Connection qui définit la méthode prepareStatement.
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
1
Modifié le 20 mars 2021 à 12:51
Modifié le 20 mars 2021 à 12:51
package memo;
C'est le contenu de la classe Bd.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Bd{ private Statement stmt; public static Connection con; static ResultSet resultat; private static Statement state; private static ResultSet results = null; private static String url = "jdbc:mysql://localhost:3306/commerce?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC"; private static String username = "root"; private static String pwd = "root"; public void Connecter(){ try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { System.out.println("echec !"); } try { con = DriverManager.getConnection(url, username, pwd); System.out.println(con); } catch (SQLException e) { System.out.println("la connexion à la bd a echoue"); e.printStackTrace(); } } public int prepareStatement(String string) { int j = 0; String reqclient = ("insert into Client (numeroCartefidelite , nom, prenom, mail, codePostal, nbPointfidelite) values(?, ?, ?, ?, ?, ?, ?)"); try{ PreparedStatement prepare = con.prepareStatement(reqclient); } catch (SQLException e) { j = 1; e.printStackTrace(); } return j; } }
C'est le contenu de la classe Bd.
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
20 mars 2021 à 13:48
20 mars 2021 à 13:48
La classe Bd est bizarrement écrite, en particulier le mélange de variables static et de méthodes non static.
De plus, de devrait être une classe purement technique, il ne faut pas y mettre les requêtes du Client.
Ceci devrait suffire :
Quant aux requêtes en elles même, tu les écris dans une classe à part, par exemple ClientDao :
Exemple :
Remarque : avec JDBC 4.0 (sorti en 2006 avec Java 6) l'instruction Class.forName n'est plus utile pour charger un driver, ils sont censés être chargés automatiquement.
De plus, de devrait être une classe purement technique, il ne faut pas y mettre les requêtes du Client.
Ceci devrait suffire :
import java.sql.*; public class Bd { private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; private static final String URL = "jdbc:mysql://localhost:3306/commerce?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC"; private static final String USER = "root"; private static final String PASSWORD = "root"; public static Connection getConnection() throws SQLException { try { Class.forName(DRIVER); return DriverManager.getConnection(URL, USER, PASSWORD); } catch (Exception e) { throw new SQLException("Erreur getConnection", e); } } }
Quant aux requêtes en elles même, tu les écris dans une classe à part, par exemple ClientDao :
import java.sql.*; public class ClientDao { private static final String TABLE_CLIENT = "client"; private static final String COLUMN_NUMERO_CARTE_FIDELITE = "numeroCartefidelite"; private static final String COLUMN_NOM = "nom"; private static final String COLUMN_PRENOM = "prenom"; private static final String COLUMN_MAIL = "mail"; private static final String COLUMN_CODE_POSTAL = "codePostal"; private static final String COLUMN_NB_POINTS_FIDELITE = "nbPointfidelite"; public static void ajouterClient(Client client) throws SQLException { String sql = String.format("INSERT INTO %s (%s, %s, %s, %s, %s, %s) VALUES (?, ?, ?, ?, ?, ?)", TABLE_CLIENT, COLUMN_NUMERO_CARTE_FIDELITE, COLUMN_NOM, COLUMN_PRENOM, COLUMN_MAIL, COLUMN_CODE_POSTAL, COLUMN_NB_POINTS_FIDELITE); try (Connection con = Bd.getConnection(); PreparedStatement pstmt = con.prepareStatement(sql)) { pstmt.setInt(1, client.getNumeroCarteFidelite()); pstmt.setString(2, client.getNom()); pstmt.setString(3, client.getPrenom()); pstmt.setString(4, client.getMail()); pstmt.setInt(5, client.getCodePostal()); pstmt.setInt(6, client.getNbPointsFidelite()); pstmt.executeUpdate(); } catch (Exception e) { throw new SQLException("Erreur ajouterClient : " + client, e); } } }
Exemple :
public class Test { public static void main(String[] args) throws Exception { ClientDao.ajouterClient(new Client(123, "Test", "prenom", "test@test.fr", 78140, 10)); } }
Remarque : avec JDBC 4.0 (sorti en 2006 avec Java 6) l'instruction Class.forName n'est plus utile pour charger un driver, ils sont censés être chargés automatiquement.
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
1
>
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
20 mars 2021 à 14:19
20 mars 2021 à 14:19
OK, j'avoue c'est vraiment plus clair votre procédé.
Merci infinement...
Merci infinement...
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Shielded
Messages postés
20
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
3 mars 2023
1
20 mars 2021 à 13:06
20 mars 2021 à 13:06
Mon problème est reglé : il fallait prendre Connection pour type de retour de la methode Connecter() dans Bd.
package memo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Bd{
private Statement stmt;
public static Connection con;
static ResultSet resultat;
private static Statement state;
private static ResultSet results = null;
private static String url = "jdbc:mysql://localhost:3306/commerce?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC";
private static String username = "root";
private static String pwd = "root";
public Connection Connecter(){
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("echec !");
}
try {
con = DriverManager.getConnection(url, username, pwd);
System.out.println(con);
} catch (SQLException e) {
System.out.println("la connexion à la bd a echoue");
e.printStackTrace();
}
return con;
}
}
Enfin la classe Client:
public class Client {
private String nom, prenom, mail;
private int numeroCartefidelite, codePostal, nbPointfidelite;
public Client(int numFidelite, String nom, String prenom, String mail, int cp, int pointFidelite) {
this.nom = nom;
this.prenom = prenom;
this.mail = mail;
this.numeroCartefidelite = numFidelite;
this.codePostal = cp;
this.nbPointfidelite = pointFidelite;
}
public void ajouterClient(){
Bd connexion1 = new Bd();
Connection con = connexion1.Connecter();
try {
String reqclient = "insert into Client (numeroCartefidelite , nom, prenom, mail, codePostal, nbPointfidelite) values(?, ?, ?, ?, ?, ?)";
PreparedStatement prepare = con.prepareStatement(reqclient);
prepare.setInt(1, this.codePostal);
prepare.setString(2, this.nom);
prepare.setString(3, this.prenom);
prepare.setString(4, this.mail);
prepare.setInt(5, this.codePostal);
prepare.setInt(6, this.nbPointfidelite);
prepare.executeUpdate();
System.out.println("insertion faite");
connexion1.fermerconnexion();
} catch (SQLException e) {
System.out.println("la connexion a la bd a echoue");
e.printStackTrace();
}
}
}
Merci encore une fois...
package memo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Bd{
private Statement stmt;
public static Connection con;
static ResultSet resultat;
private static Statement state;
private static ResultSet results = null;
private static String url = "jdbc:mysql://localhost:3306/commerce?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC";
private static String username = "root";
private static String pwd = "root";
public Connection Connecter(){
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("echec !");
}
try {
con = DriverManager.getConnection(url, username, pwd);
System.out.println(con);
} catch (SQLException e) {
System.out.println("la connexion à la bd a echoue");
e.printStackTrace();
}
return con;
}
}
Enfin la classe Client:
public class Client {
private String nom, prenom, mail;
private int numeroCartefidelite, codePostal, nbPointfidelite;
public Client(int numFidelite, String nom, String prenom, String mail, int cp, int pointFidelite) {
this.nom = nom;
this.prenom = prenom;
this.mail = mail;
this.numeroCartefidelite = numFidelite;
this.codePostal = cp;
this.nbPointfidelite = pointFidelite;
}
public void ajouterClient(){
Bd connexion1 = new Bd();
Connection con = connexion1.Connecter();
try {
String reqclient = "insert into Client (numeroCartefidelite , nom, prenom, mail, codePostal, nbPointfidelite) values(?, ?, ?, ?, ?, ?)";
PreparedStatement prepare = con.prepareStatement(reqclient);
prepare.setInt(1, this.codePostal);
prepare.setString(2, this.nom);
prepare.setString(3, this.prenom);
prepare.setString(4, this.mail);
prepare.setInt(5, this.codePostal);
prepare.setInt(6, this.nbPointfidelite);
prepare.executeUpdate();
System.out.println("insertion faite");
connexion1.fermerconnexion();
} catch (SQLException e) {
System.out.println("la connexion a la bd a echoue");
e.printStackTrace();
}
}
}
Merci encore une fois...
19 mars 2021 à 07:19
19 mars 2021 à 09:23
Merci de votre réponse. J'avais déjà fait comme vous dites mais l'erreur apparaît. J'ai repris et c'est pareil:
String reqclient = "insert into Client (numeroCartefidelite , nom, prenom, mail, codePostal, nbPointfidelite)
values('" +numeroCartefidelite+ "' ' , ' '" +nom+ "' , '" +prenom+ "' , '" +mail+ "' , '" +codePostal+ "' , '" +nbPointfidelite+ "')";
Par contre si j'essaie avec des données comme ci-dessous ça marche :
String reqclient = "INSERT INTO `Client` (`numeroCartefidelite`, `nom`, `prenom`, `mail`, `codePostal`, `nbPointfidelite`) VALUES ('0', 'AA', 'bb', 'aa@bb.com', '79100', '0')";
Mais l'objectif c'est de faire une requête preparée qui sera modifiée avec l'appel de la méthode ajouterClient qui l'encapsule.
19 mars 2021 à 09:51
Ensuite, regarde la réponse de Kx ... l'utilisation de requêtes préparées est bien meilleure ...
19 mars 2021 à 09:55
J'ai vu sa réponse, elle sera mieux pour moi je pense effectivement.
Encore merci de votre aide.