Projet

Général

Profil

Propel crud » Historique » Version 6

Anonyme, 03/01/2009 11:35
Corrections orthographiques. @TODO : traduire le passage <--TRAD TRAD-->

1 6
_Ceci est une traduction libre de la page officielle de la documentation de Propel "/ICI":http://propel.phpdb.org/trac/wiki/Users/Documentation/1.3/BasicCRUD_
2 1
3 3
 = Opérations de base : C.R.U.D. (create, read, update, delete) = 
4 1
5 3
 Ce guide tente de montrer comment effectuer les opérations de base sur la base de données en utilisant Propel.
6 1
7 3
 Les exemples qui suivent supposent que vous avez déjà installé et paramétré Propel. 
8 1
9
 == CREATE == 
10
11 3
 Pour ajouter de nouvelles données dans la base, il faut instancier un des objets générés par Propel et ensuite appeler la méthode setChamp() appropriée. Propel générera le SQL qui va bien pour faire l'insertion. 
12 1
13
 === Simple INSERT ===
14
15
 Dans sa forme la plus simple, on crée un nouveau tuple de cette façon : 
16
17
18 6
<pre>
19 1
# php 
20
 / * Initialiser Propel, etc * / 
21
22 3
 $user = new Utilisateur(); 
23
 $user->setPrenom("Thomas"); 
24
 $user->setNom("Belliard"); 
25
 $user->save();
26 6
</pre>
27 1
 
28
Propel va traduire ces lignes de code par :
29
30 6
<pre>
31 1
#! sql 
32 3
 INSERT INTO utilisateurs (prenom, nom) VALUES ('Thomas', 'Belliard');
33 6
</pre>
34 1
35
36 2
 === Gérer les insertions connexes === 
37 1
38 5
 De plus, Propel sait si un objet a été sauvegardé ou pas. Donc on peut créer plusieurs tuples de plusieurs tables différents et tout sauvegarder une seule fois :
39 1
40 6
<pre>
41 1
 #! php 
42
 / * Initialiser Propel, etc * / 
43
44 3
 // 1) Créer un Auteur
45 1
46 3
 include_once 'librairie/Author.php'; 
47 1
48 3
 $author = new Author(); 
49
 $author->setFirstName("Leo"); 
50
 $author->setLastName("Tolstoï"); 
51
 // Note: ce tuple n'est pas encore dans la base
52 1
53 3
 // 2) Créer un Editeur
54 1
55 3
 include_once 'librairie/Publisher.php'; 
56 1
57 3
 $pub = new Editeur(); 
58
 $pub->setName("Viking Press"); 
59
 // Note: ce tuple n'est pas encore dans la base 
60 1
61 3
 // 3) Créer un livre
62 1
63 3
 include_once 'librairie/Book.php'; 
64 1
65 3
 $livre = new livre(); 
66
 $livre->setTitle("Guerre et Paix"); 
67
 $livre->setIsbn("0140444173"); 
68
 $livre->setPublisher($pub); 
69
 $livre->setAuthor($author); 
70
 $livre->save();
71
 // enregistre l'ensemble des 3 objets dans la base avec les dépendances (clés étrangères) qui vont bien ! 
72 6
</pre>
73 1
74 6
 Parce que Propel sait si un objet a été enregistré ou non, il est capable avec save() d'analyser tous les objets avant de les ajouter en gérant les relations à l'objet livre. (Plus d'info à ce sujet sur le site de Propel : "Relationships":http://propel.phpdb.org/trac/wiki/Users/Documentation/1.3/Relationships traduit "ici":http://projects.sylogix.org/gepi/wiki/propel_relations) .
75 1
76
 == RETRIEVE ==
77 2
78 6
 Récupérer des objets de la base de données, également dénommés _objets_hydratant, comme quand on effectue une requête SELECT pour peupler toutes les propriétés de l'objet peut se faire à l'aide des méthodes statiques PEER pour vérifier si ces enregistrements existent dans la table. Ces classes PEER ne contiennent que des méthodes statiques qui permettent d'effectuer des opérations sur la table.
79 1
Il existe plusieurs méthodes pour vous aider à choisir un seul ou plusieurs objets de la base de données. 
80 2
81 1
 === Récupération par la clé primaire === 
82 2
83 6
 La façon la plus simple pour récupérer un objet (ligne) de la base de données, est d'utiliser la méthode _retrieveByPK()_. Comme d'habitude, il faut fournir la valeur de la clé primaire en argument à cette méthode.
84 1
85 3
 ==== La clé primaire est sur une seul colonne ==== 
86 2
87 6
 Habituellement, votre table aura une seule clé primaire, ce qui signifie que la méthode _retrieveByPK()_ accepte un seul paramètre. 
88 2
89 6
<pre>
90 1
 #! php 
91
92 6
 $firstBook = [[BookPeer]]::retrieveByPK(1); 
93 3
 // $firstBook est maintenant un objet livre, ou NULL si aucune correspondance n'a été trouvée. 
94 6
</pre>
95 2
96 3
 ==== La clé primaire est sur plusieurs colonnes ==== 
97 1
98 6
 Dans certains cas, votre clé primaire est composée de plusieurs colonnes. Dans ce cas, _retrieveByPK()_ acceptera plusieurs paramètres, un pour chaque colonne de clé primaire. 
99 1
100 5
 Par exemple, si nous avions un tableau, avec une clé primaire à plusieurs colonnes, définie comme ceci: 
101 6
<pre>
102 2
 #! xml 
103 1
    <table name="multicolpk_example" phpName="MultiColPKExample"> 
104
       <column name="id1" type="INTEGER" primaryKey="true"/> 
105
       <column name="id2" type="INTEGER" primaryKey="true"/> 
106
       <! - Les autres colonnes ... -> 
107
    </ table> 
108 6
</pre>
109 1
110 6
 ... alors votre méthode _retrieveByPK()_ serait invoquée comme ceci: 
111 1
112 6
<pre>
113 2
 #! php 
114 1
115 6
 $myObject = [[MultiColPKExamplePeer]]::retrieveByPK(1,2); 
116
</pre>
117 1
118 3
 ==== Obtenir plusieurs objets par PK ==== 
119 2
120 6
 Vous pouvez également sélectionner plusieurs objets en fonction de leurs clés primaires, en appelant la méthode générée _retrieveByPKs()_ qui prend en paramètre un tableau de clés primaires: 
121 1
122 6
<pre>
123 1
 #! php 
124
125 6
 $selectedBooks = [[BookPeer]]::retrieveByPKs(array(1,2,3,4,5,6,7));
126 2
 // $SelectedBooks est un tableau d'objets
127 6
</pre>
128 1
129 6
 _Il est à noter que ceci ne fonctionne que pour les tables avec une seule colonne de clés primaires._ 
130 1
131 2
 === Interrogation de la base de données === 
132
133 6
 Pour sélectionner plusieurs lignes par d'autres critères que la clé primaire, nous avons deux choix:
134 1
135 6
 1) d'utiliser la classe Criteria, ou
136
137
 2) d'écrire du SQL personnalisé.
138
139
 La classe _Criteria_ offre une approche relativement simple à la construction d'une requête. C'est le meilleur choix pour construire des requêtes simples dans la base, mais pour une requête très complexe, il peut s'avérer plus efficace (et moins douloureux) de simplement utiliser une requête SQL personnalisée pour peupler (hydrate) votre objet Propel. 
140
141 1
 ==== Critères simples ==== 
142
143
 Voici quelques exemples de critères simples être utilisé pour renvoyer plusieurs objets. 
144
145 6
 *Exemple 1:* Trouver tous les auteurs dont le prénom est Thomas, mais dont le nom n'est pas Belliard. 
146 1
147 6
<pre>
148 1
 #! php 
149
150
 $c = new Criteria(); 
151
 $c->add(UtilisateurPeer::prenom, "Thomas"); 
152
 $c->add(UtilisateurPeer::nom, "Belliard", Criteria::NOT_EQUAL); 
153 3
154 6
 $users = [[UtilisateurPeer]]::doSelect($c); 
155 2
 // $users contient un tableau de tous les utilisateurs qui répondent à la requête 
156 3
 // {Trad} --> On voit ici toute l'utilité d'utiliser un IDE pour coder avec l'autocomplétion.
157 6
</pre>
158 3
159 2
 ... on obtient les mêmes résultats qu'avec la requête SQL suivante: 
160 6
<pre>
161 2
 #! sql 
162 3
 SELECT * FROM utilisateurs WHERE utilisateurs.prenom = 'Thomas' AND utilisateurs.nom <> 'Belliard';
163 1
164 6
</pre>
165 1
166 6
 *Exemple 2:* Trouver tous les auteurs dont le nom est Tolstoy, Dostoevsky, ou Bakhtin
167 1
168 6
<pre>
169 1
 #! php 
170
171
$c = new Criteria();
172
$c->add(AuthorPeer::LAST_NAME, array("Tolstoy", "Dostoevsky", "Bakhtin"), Criteria::IN);
173
174 6
$authors = [[AuthorPeer]]::doSelect($c);
175 2
176 1
 // $authors contient un tableau des objets auteurs
177 6
</pre>
178 1
179 2
 ... on obtient les mêmes résultats qu'avec la requête SQL suivante: 
180 6
<pre>
181 5
 #! sql 
182 2
 SELECT * FROM author WHERE author.LAST_NAME IN ('Tolstoy', 'Dostoevsky', 'Bakhtin');
183 1
 
184 6
</pre>
185 2
186
187 3
188 1
189 6
h3. Utiliser des critères complexes
190 1
191
192 6
 Quand vous avez besoin d'exprimer des relations logiques (ET, OU, etc) dans la clause where de la requête, vous devez combiner manuellement chaque objet Criteria() ensemble. Ces clauses sont ensuite ajouter à la requête par la méthode _Criteria->add()_.
193
194
 *Exemple 1:* Trouver tous les auteurs dont le prénom est "Leo" et le nom est "Tolstoy", "Dostoevsky", "Bakhtin". 
195
196
<pre>
197 1
 #! php
198
199 3
$c = new Criteria();
200 1
$cton1 = $c->getNewCriterion(AuthorPeer::FIRST_NAME, "Leo");
201
$cton2 = $c->getNewCriterion(AuthorPeer::LAST_NAME,  array("Tolstoy", "Dostoevsky", "Bakhtin"), Criteria::IN);
202
 
203 3
// On combine toutes ces clauses...
204 1
$cton1->addOr($cton2);
205 3
 
206 1
// ...qu'on ajoute au critère (sic), à la requête quoi ;)
207 3
$c->add($cton1);
208
209 1
 
210 6
</pre>
211 1
212 3
 ... résultats dans la requête SQL comme: 
213 6
<pre>
214 1
 #! sql 
215 3
 SELECT ... FROM author WHERE (author.FIRST_NAME = 'Leo' OR author.LAST_NAME IN ('Tolstoy', 'Dostoevsky', 'Bakhtin'));
216 6
</pre>
217 1
218 5
219 6
 Il y a aussi des_Criteria_raccourcis si vous souhaitez effectuer une requête avec les relations logiques entre les clauses de référence sur _la même colonne_. 
220 1
221 6
 *Exemple 2:* Trouver tous les auteurs dont le prénom est «Leo» ou «Karl» 
222 1
223 5
 Utiliser la classe Criteria(), cela ressemble à: 
224 6
<pre>
225 1
 #! php 
226 4
227
$c = new Criteria();
228 1
$cton1 = $c->getNewCriterion(AuthorPeer::FIRST_NAME, "Leo");
229 4
$cton2 = $c->getNewCriterion(AuthorPeer::FIRST_NAME, "Karl");
230 1
 
231 4
// on les combine
232 1
$cton1->addOr($cton2);
233
 
234 4
// ...et on les ajoute aux critères de la requêtes
235 1
$c->add($cton1);
236 6
</pre>
237 4
238 6
 _Criteria_ propose un raccourci pour cela : 
239
<pre>
240 1
 #! php 
241 4
242
$c = new Criteria();
243 1
$c->add(AuthorPeer::FIRST_NAME, "Leo");
244 4
$c->addOr(AuthorPeer::FIRST_NAME, "Karl");
245
246 6
</pre>
247 5
248 6
*ATTENTION*
249 1
 Il est important de noter que cette méthode a un certain nombre de limites - surtout qu'ils ne fonctionnent que pour les relations avec une seule colonne. D'après l'auteur de cette classe, il est conseillé de ne pas utiliser ces méthodes lorsque vous avez besoin d'exprimer des clauses particulières car elles masquent les réelles relations qui existent entre les objets Criteria et peuvent donc s'avérer difficiles à débugguer. (Ces méthodes vont probablement changer ou disparaître dans Propel 2). 
250
251
 === Utiliser du SQL personnalisé ===
252 5
253 6
 Propel est conçu pour travailler avec vous plutôt que contre vous. Dans de nombreux cas, la rédaction d'une requête complexe en utilisant les _Criteria_ finit par faire désordre et difficile à comprendre ou à maintenir un niveau des requêtes SQL. A certains moments, si la requête est complexe, il vaut mieux la coder en dur ({TRAD} d'autant que dans Gepi, on utilise que [[MySql]]).
254 1
255
<--TRAD reste à traduire vraiment (et à comprendre aussi)
256 6
 Ainsi, avec seulement un peu plus de travail, vous pouvez également obtenir des objets de votre base de données en utilisant SQL. Utiliser SQL pour interroger la base de données nous introduit à la populateObjects généré_()_méthode dans notre classes Peer - qui est appelé dans les coulisses par la doSelect_()_méthode. Cette méthode attend d'être adopté une créole_!_Objet [[ResultSet]], indexé numériquement (c'est-à-dire qui a été créé à l'aide! ResultSet:: FETCHMODE_NUM option_à executeQuery ()_).
257
258 1
TRAD-->
259
260 6
 *Exemple 1:* Utilisez des sous-sélections pour peupler la base de données 
261 1
262 6
<pre>
263 1
 #! php 
264
265 4
$con = Propel::getConnection(DATABASE_NAME);
266 1
267
$sql = "SELECT books.* FROM books WHERE NOT EXISTS (SELECT id FROM review WHERE book_id = book.id)";  
268
$stmt = $con->prepare($sql);
269
$stmt->execute();
270
271 6
$books = [[BookPeer]]::populateObjects($stmt);
272 4
 
273 6
</pre>
274 1
275 4
 Des choses importantes à retenir lorsque vous utilisez du SQL personnalisé pour remplir Propel: 
276 1
   *! ResultSet colonne doit être indexé numériquement 
277
   *! ResultSet doit contenir toutes les colonnes de l'objet 
278 6
   *! ResultSet doit avoir les colonnes _dans le même ordre_, telles qu'elles sont définies dans le (((schema.xml))) fichier 
279 1
280 4
 == METTRE À JOUR (update) == 
281 1
282
 Mise à jour de la base de données comporte essentiellement des lignes de récupérer des objets, de modifier le contenu, puis les enregistrer. Dans la pratique, pour Propel, il s'agit d'une combinaison de ce que nous avons déjà vu dans le récupérer et créer des sections. 
283
284 6
<pre>
285 1
 #! php 
286
287 4
// 1) On récupère un objet par sa clé primaire
288 1
289 4
$cours = edtCourPeer::retrieveByPK(1);
290 1
291 4
// 2) On met à jour les valeurs et on sauvegarde
292 1
293 4
$cours->setDuree(4);
294
$cours->save();
295 1
296 6
</pre>
297 4
298 1
 Il n'y a vraiment pas grand-chose de bien plus que cela. Bien sûr, vous pouvez également mettre à jour les relations d'une manière similaire à ce qui a déjà été démontré dans la section CREATE. 
299
300 6
<pre>
301 1
 #! php 
302
303 4
/* initialize Propel, etc. */
304 1
305 4
// 1) On récupère un auteur
306 6
$author = [[AuthorPeer]]::retrieveByPK(1);
307 1
308 4
// 2) On récupère un livre
309 6
$book = [[BookPeer]]::retrieveByPK(1);
310 1
311 4
// 3) Et on attribut ce livre à cet auteur
312 1
313 4
$book->setAuthor($author);
314
$book->save();
315 1
316 6
</pre>
317 1
318 4
319 6
h2. DELETE 
320
321
322 4
 Suppression d'objets peut être accompli en utilisant les classes Peer ou l'objet classes. 
323 1
324 4
 === En utilisant Peer ===
325 1
326 6
 Vous pouvez utiliser les méthodes générées _doDelete()_ de la classe Peer pour supprimer des enregistrements dans la table. Vous pouvez passer à cette méthode une clé primaire, une instance de l'objet, ou même un objet _Criteria_ (mais ce n'est pas très utile, puisque vous ne pouvez supprimer que par la clé primaire). 
327 1
328 6
 *Exemple 1:* Supprimer à l'aide de la clé primaire 
329 4
330 6
<pre>
331 4
 #! php
332 6
 [[EdtCoursPeer]]::doDelete(1);
333 1
 // et la ligne de la table edt_cours dont id_cours = 1 est effacée. 
334 6
</pre>
335 4
336 6
 *Exemple 2:* Supprimer à l'aide de l'objet instancié 
337 1
338 6
<pre>
339 1
 #! php 
340
341 6
$book = [[BookPeer]]::retrieveByPK(1);
342
[[BookPeer]]::doDelete($book);
343 4
344 6
</pre>
345 4
346 1
 === En utilisant directement les objets ===
347 4
348 6
 Par souci de cohérence avec d'autres C.R.U.D. opérations, vous pouvez également supprimer la ligne d'une base de données à l'aide de la classe d'objets. Certaines personnes préfèrent le faire de cette façon, l'instanciation d'un objet, puis appeler la méthode _delete()_. D'autres estiment que cela est "bizarre", car alors vous êtes à gauche avec un objet qui ne fait point à la ligne une base de données. Quel que soit - vous êtes libre de choisir:) 
349 4
350 6
<pre>
351 4
 #! php 
352 6
 $student = [[ElevePeer]]::retrieveByPK(1); 
353 5
 $student->delete(); 
354 6
 // (Et maintenant vous devez vous rappeler que vous ne pouvez plus utiliser cet élève car il n'existe plus).
355 5
356 6
L'autre intérêt est que on peut ajouter une méthode publique [[EleveDelete]]() dans laquelle on pourra vérifier tous les enregistrements liés à cet utilisateur.
357
</pre>
358
359
"A la page suivante, vous trouverez des explications sur les relations da la bdd":http://projects.sylogix.org/gepi/wiki/propel_relations.