Aller au menu - Aller au contenu

Icône Après la lecture : l'édition

Mise à jour : 17/06/2009
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-NC-SA
3 526 visites depuis 7 jours, dont 135 sur ce chapitre classé 45/786
Nous avons appris à utiliser des requêtes SQL avec des ResultSet afin de récupérer des informations provenant de la base.
Nous allons voir comment éditer nos tables en insertion, modification et suppression dans nos programmes Java !
Vous allez voir, c'est simplissime ! ! ^^
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Modifier des données

Je sais que beaucoup d'entre vous se sont dit, lors du chapitre précédent :
"t'es sympa, tu nous dis que les objets ResultSet peuvent modifier des données lors de parcours de résultats... et tu ne nous montres même pas ça !"

J'ai juste préféré séparer le côté lecture du côté lecture et modifications.
D'ailleurs, c'est par ça que nous allons commencer. Bien sûr, il faudra que l'objet Statement retourne un ResultSet permettant cela !

En fait, durant la lecture, vous pouvez utilisez des méthodes qui ressemblent à celle que je vous ai déjà montrée lors du parcours d'un résultat... Vous vous souvenez, les méthodes comme :
  • res.getAscii();
  • res.getBytes();
  • res.getInt();
  • res.getString();
  • ...


Sauf qu'ici, vous remplacerez getXXX(); par updateXXX(); . Ces méthodes de mise à jour des données prennent deux paramètres :
  • 1 : le nom de la colonne (String) ;
  • 2 : la valeur à mettre à la place de la valeur existante (dépend de la méthode utilisée) ;

Comment ça : dépend de la méthode utilisée ?

C'est simple :
  • updateFloat(String nomColonne, float value) : prend un float comme valeur ;
  • updateString(String nomColonne, String value) : prend une chaîne de caractères en paramètre ;
  • ...


Donc, changer la valeur d'un champ est très simple mais il faut, en plus des changements de valeurs, valider ces changements pour qu'ils soient effectifs, et ceci se fait grâce à la méthode updateRow() . De la même façon, vous pouvez annuler des changements avec la méthode cancelRowUpdates() .
Si vous avez à annuler des modifications, vous devrez le faire avant la méthode de validation, sinon, l'annulation sera ignorée !


Je vous propose de voir un petit exemple de mise à jour :

Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.sdz.resultset;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Modif {
	public static void main(String[] args) {
		try {

			//--------------------------------------------------------------------
			//TOUT CECI, VOUS CONNAISSEZ			
			Class.forName("org.postgresql.Driver");
			String url = "jdbc:postgresql://localhost:5432/Ecole";
			String user = "postgres";
			String passwd = "postgres";
			
			Connection conn = DriverManager.getConnection(url, user, passwd);
			//On autorise la mise à jour des données et la mise à jour de l'affichage
			Statement state = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
			
			//On va chercher une ligne dans la base de données
			String query = "SELECT prof_id, prof_nom, prof_prenom FROM professeur WHERE prof_nom = 'MAMOU'";			
			ResultSet res = state.executeQuery(query);
			//--------------------------------------------------------------------
			
			//On se positionne sur la première ligne de donnée
			res.first();
				
			//On affiche ce qu'on trouve
			System.out.println("NOM : " + res.getString("prof_nom") + " - PRENOM : " + res.getString("prof_prenom"));
			
			//On met à jour les champs
			res.updateString("prof_nom", "COURTEL");
			res.updateString("prof_prenom", "Angelo");
			//On valide
			res.updateRow();
			
			//Et voici les modifications
			System.out.println("*********************************");
			System.out.println("APRES MODIFICATION : ");
			System.out.println("\tNOM : " + res.getString("prof_nom") + " - PRENOM : " + res.getString("prof_prenom") + "\n");
			
			//On remet les infos du départ
			res.updateString("prof_nom", "MAMOU");
			res.updateString("prof_prenom", "Daniel");
			//On revalide
			res.updateRow();
			
			//Et voilà !
			System.out.println("*********************************");
			System.out.println("APRES REMODIFICATION : ");
			System.out.println("\tNOM : " + res.getString("prof_nom") + " - PRENOM : " + res.getString("prof_prenom") + "\n");

                        res.close();
                        state.close();
						
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


Et voici ce que j'obtiens :

Image utilisateur


Donc, le temps d'un instant, les données ont été modifiées dans la base de données, nous avons donc réussi notre pari ! :magicien:

Ôte-nous d'un doute, une bête requête SQL n'aurait pas pu faire l'affaire ?


Bien sûr que si ! :)
Mais au moins, vous avez vu comment modifier des lignes via l'objet ResultSet...
Nous allons voir comment exécuter les autres types de requêtes avec Java !

Statement, toujours plus fort

Vous savez depuis quelques temps déjà que ce sont les objets Statement qui sont chargés d'exécuter les instructions SQL.
Par conséquent, vous devez avoir deviné que les requêtes de type sront aussi exécutées par ces mêmes objets :
  • INSERT
  • UPDATE
  • DELETE
  • CREATE


Voici un code d'exemple :

Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.sdz.statement;

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 State {

	public static void main(String[] args) {
		
		try {			
			Class.forName("org.postgresql.Driver");
			String url = "jdbc:postgresql://localhost:5432/Ecole";
			String user = "postgres";
			String passwd = "postgres";
			
			Connection conn = DriverManager.getConnection(url, user, passwd);
			//On autorise la mise à jour des données et la mise à jour de l'affichage
			Statement state = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
			PreparedStatement prepare = conn.prepareStatement("UPDATE professeur set prof_prenom = ? WHERE prof_nom = 'MAMOU'");
			
			//On va chercher une ligne dans la base de données
			String query = "SELECT prof_nom, prof_prenom FROM professeur WHERE prof_nom = 'MAMOU'";			
			
			//On exécute la requête
			ResultSet res = state.executeQuery(query);
			res.first();
			//On affiche
			System.out.println("\n\tDONNEES D'ORIGINE : ");
			System.out.println("\t-------------------");
			System.out.println("\tNOM : " + res.getString("prof_nom") + " - PRENOM : " + res.getString("prof_prenom"));
			
			//On paramètre notre requête préparée
			prepare.setString(1, "Gérard");
			//On exécute
			prepare.executeUpdate();
			
			res = state.executeQuery(query);
			res.first();
			//On affiche à nouveau
			System.out.println("\n\t\t APRES MAJ : ");
			System.out.println("\t\t * NOM : " + res.getString("prof_nom") + " - PRENOM : " + res.getString("prof_prenom"));
						
			//On refait une mise à jour
			prepare.setString(1, "Daniel");
			prepare.executeUpdate();
			
			res = state.executeQuery(query);
			res.first();
			//on affiche une nouvelle fois
			System.out.println("\n\t\t REMISE A ZERO : ");
			System.out.println("\t\t * NOM : " + res.getString("prof_nom") + " - PRENOM : " + res.getString("prof_prenom"));

                        prepare.close();
                        res.close();
                        state.close();
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
	}
}


Ce qui me donne :

Image utilisateur


Ici, nous avons utilisé un PreparedStatement, histoire de faire compliqué dès le premier coup... ^^
Mais vous auriez pu tout aussi bien utiliser un Statement tout simple et invoquer la méthode executeUpdate(String query) .

Vous savez quoi ? Pour les autres types de requêtes, il suffit d'invoquer la même méthode que pour la mise à jour... En fait, celle-ci retourne un booléen qui permet de savoir si le traitement a réussi ou non. :)

Voici quelques exemples :

Code : Java
1
2
state.executeUpdate("INSERT INTO professeur (prof_nom, prof_prenom) VALUES('SALMON', 'Dylan')");
state.executeUpdate("DELETE FROM professeur WHERE prof_nom = 'MAMOU'");

C'est très simple à utiliser, vous ne pourrez pas dire le contraire... :-°
Cependant, je ne sais pas si vous savez ceci, mais certains moteurs SQL, comme PostgreSQL, vous proposent de gérer vos requêtes SQL (celles qui ont pour effet une modification de la base, pas celle de visualisation de données) avec ce qu'on appelle des transactions...

Gérer les transactions manuellement

Tu es bien gentil, mais qu'est-ce que c'est que ça ?

Bon, alors, par où vais-je commencer ?...
Lorsque vous insérez, modifiez ou supprimez des données dans PostgreSQL, il se passe un événement automatique : la validation des modifications par le moteur SQL !
C'est aussi simple que ça... Un petit schéma pour visualiser :

Image utilisateur


Lorsque vous exécutez une requête de type INSERT, CREATE, UPDATE ou DELETE, ces requêtes modifient les données présentes dans la base. Une fois exécutée, le moteur SQL valide directement ces modifications !

Par contre, vous pouvez avoir la main sur ce point :

Image utilisateur


Comme ceci, c'est vous qui avez le contrôle sur vos données !

Je ne vois pas l'intérêt de faire ça !

C'est simple : pour pouvoir contrôler l'intégrité de vos données !
Imaginez que vous devez faire deux requêtes, une modification et une insertion et que vous partez du principe que l'insertion dépend de la mise à jour ! Comment feriez-vous si de mauvaises données étaient mises à jour ? L'insertion qui en découle serait mauvaise... :(
Ceci, bien sûr, si le moteur SQL valide automatiquement les requêtes faites...
Oui, vu sous cet angle... Comment on gère ça, alors ?

On spécifie au moteur SQL de ne pas valider automatiquement. Ou plutôt de valider automatiquement les requêtes SQL avec une méthode qui prend un booléen en paramètre, mais qui ne concernera pas l'objet Statement, mais l'objet Connection :
Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;


public class Transact {

	public static void main(String[] args) {
		try {
			Class.forName("org.postgresql.Driver");
			
			String url = "jdbc:postgresql://localhost:5432/Ecole";
			String user = "postgres";
			String passwd = "batterie";
			
			Connection conn = DriverManager.getConnection(url, user, passwd);
			conn.setAutoCommit(false);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


Par contre, lorsque vous voulez que vos requêtes soient prises en compte, il faut utiliser la méthode conn.commit(); .
En mode setAutoCommit(false); , si vous ne validez pas vos requêtes, elles ne seront pas prises en compte !

Vous pouvez revenir à tout moment en mode validation automatique avec setAutoCommit(true);

Voici un exemple :

Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;


public class Transact {

	public static void main(String[] args) {
		try {
			Class.forName("org.postgresql.Driver");
			
			String url = "jdbc:postgresql://localhost:5432/Ecole";
			String user = "postgres";
			String passwd = "batterie";
			
			Connection conn = DriverManager.getConnection(url, user, passwd);
			conn.setAutoCommit(false);
			Statement state = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
			String query = "UPDATE professeur SET prof_prenom = 'Cyrille' WHERE prof_nom = 'MAMOU'";
			
			ResultSet result = state.executeQuery("SELECT * FROM professeur WHERE prof_nom = 'MAMOU'");
			result.first();
			System.out.println("NOM : " + result.getString("prof_nom") + " - PRENOM : " + result.getString("prof_prenom"));
			
			state.executeUpdate(query);
			
			result = state.executeQuery("SELECT * FROM professeur WHERE prof_nom = 'MAMOU'");
			result.first();
			System.out.println("NOM : " + result.getString("prof_nom") + " - PRENOM : " + result.getString("prof_prenom"));
			
                        result.close();
                        state.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


Vous pouvez exécuter le code autant de fois que vous voulez, vous aurez toujours :

Image utilisateur


Vous voyez : malgré la requête de mise à jour, celle-ci est inopérante ! Oh oui ! Vous pouvez voir les modifications durant le temps d'exécution du script, mais vu que vous n'avez pas validé les modifications, celles-ci sont annulées à la fin...
Pour que la mise à jour soit effective, il aurait fallu faire un conn.commit() avant la fin du script ! ^^

Bon, je crois qu'on en a assez vu pour ce chapitre... En route pour le QCM ! :pirate:

Q.C.M.

Avec un ResultSet acceptant la modification de valeur, quelle méthode utiliser pour modifier un champ de type int ?

En utilisant la mise à jour de valeurs avec un ResultSet, que ne faut-il pas oublier de faire après avoir fait les modifications ?
Quelle est la méthode à utiliser sur un objet Statement pour une requête modifiant la base de données ?
Comment faire en sorte de bloquer la validation automatique des requêtes SQL ?

Statistiques de réponses au QCM

Alors ? Je ne vous avais pas dit que ce chapitre allait être tout simple ?
Chose promise, chose due !

Maintenant, je vous propose de voir comment uniformiser un peu tout ça... C'est vrai qu'établir tout le temps la connexion est un peu fastidieux alors qu'une seule instance de celle-ci suffirait...
C'est ce que je vous propose de voir dans le chapitre qui suit. :)
Chapitre précédent Sommaire Chapitre suivant

Partager

1 commentaire pour "Après la lecture : l'édition"
Note moyenne : 3.34 / 4 (178 votes)
Pseudo Commentaire
Hors ligne Niko300 # Posté le 19/03/2010 à 22:03:15
Mario brosse les cours
Avatar

Ville : Gilly
Pays : Belgique

Merci pour ce superbe tuto, ça va me servir énormément pour mon projet Java :D

Image utilisateur
Image utilisateur
______________[Mes creas 3D] Niko300 - Membre [Utilitaires]
 

Voir tous les commentaires