Insertion données java dans Mysql [Résolu]

Signaler
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021
-
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021
-
Bonjour,

Je code en java sous et Eclipse et utilise Mysql(serveur version 5.7.24) . Souhaitant envoyer des données vers ma BD.

J'ai fait la requête suivante afin d'insérer des données dans ma base de données :

String reqclient = ("insert into 'Client' ('numeroCartefidelite', nom, 'prenom', 'mail', 'codePostal', 'nbPointfidelite')
values("' +numeroCartefidelite+ "' , '" +nom+ "','" +prenom+ "','" +mail+ "' , '" +codePostal+ "' , '" +nbPointfidelite+ "');");


Après compilation j'ai l'erreur suivante :

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
String literal is not properly closed by a double-quote


Merci d'avance àtous ceux qui pourraient me dépanner.

5 réponses

Messages postés
32276
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
3 mai 2021
3 448
Bonjour
Tu as mal écrit ta requête.... Et mal concaténé ta string...
Messages postés
32276
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
3 mai 2021
3 448
String reqclient = "insert into Client (numeroCartefidelite, nom, prenom, mail, codePostal, nbPointfidelite) values('" +numeroCartefidelite+ "' , '" +nom+ "','" +prenom+ "','" +mail+ "' , '" +codePostal+ "' , '" +nbPointfidelite+ "')";
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021
>
Messages postés
32276
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
3 mai 2021

Bonjour,
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.
Messages postés
32276
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
3 mai 2021
3 448 >
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

Déjà... tu n'as clairement pas comparé le code que je t'ai donné avec le tien .... tu ajoutes un peu trop de "quotes" ....

Ensuite, regarde la réponse de Kx ... l'utilisation de requêtes préparées est bien meilleure ...
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021
>
Messages postés
32276
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
3 mai 2021

Oui j'ai bien vu les côtes en trop et corrigées: ça ne marche juste pas.

J'ai vu sa réponse, elle sera mieux pour moi je pense effectivement.

Encore merci de votre aide.
Messages postés
16324
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 mai 2021
2 825
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 :
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);
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

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:
 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
Messages postés
16324
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 mai 2021
2 825 >
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

"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.
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

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
Messages postés
16324
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 mai 2021
2 825 >
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

"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.
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

Le message : The method prepareStatement(String) is undefined for the type Bd

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
Messages postés
16324
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 mai 2021
2 825
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.
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

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  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.
Messages postés
16324
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 mai 2021
2 825
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 :
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.
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021
>
Messages postés
16324
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 mai 2021

OK, j'avoue c'est vraiment plus clair votre procédé.

Merci infinement...
Messages postés
9
Date d'inscription
vendredi 19 mars 2021
Statut
Membre
Dernière intervention
20 mars 2021

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...