forked from fabienfelix/formation-programmation-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcours-javaee.ad
More file actions
1002 lines (681 loc) · 22.8 KB
/
cours-javaee.ad
File metadata and controls
1002 lines (681 loc) · 22.8 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
= Java EE
:author: Arnaud Tournier
:email: ltearno@gmail.com
:backend: revealjs
:deckjs_theme: neon
:revealjs_theme: beige
:revealjs_history: true
:imagesdir: images-javaee
:source-highlighter: highlightjs
////
:revealjs_transition: zoom
Java EE
2016 - LTE Consulting
:source-highlighter: pygments
////
== Java EE
**Définition**, serveur d'application.
Plateforme Java Enterprise Edition, sur ensemble de la plateforme standard.
Facilite le développement et le déploiement d'applications web distribuées exécutées au sein des serveurs d'application.
=== Quelques implémentations
JavaEE est une norme, il faut choisir l'implémentation : Tomcat, JBoss, Glassfish, ...
Application divisées en couches, souvent trois (presentation, business, data).
En pratique on a des pages htmls + servlets + jsp en frontal et ejb dans les couches internes (métier, processus et données).
=== Structure d'une application Java EE
```
/
|- fichiers publiques **.html**, **.jsp**, **.css**, **.js**, ...
|- WEB-INF/ (_cachés à l'utilisateur_)
|- classes
|- fichiers **.class**
|- lib
|- fichiers **.jar**
|- **web.xml** : C'est un fichier de configuration de l'application
```
== Développement avec Eclipse
Installation de Tomcat, déclaration dans Eclipse, création d'un projet Dynamic Web Application et du serveur dans Eclipse.
Démarrage d'une application avec un fichier index.html dedans.
== HTTP
Rappels HTTP, requête, méthode (GET, POST), headers, cookies.
== Servlet
Une classe qui traite les requêtes HTTP.
=== Mise en place
Une servlet est une simple classe Java...
- Elle hérite de `javax.servlet.http.HttpServlet`,
- On implémente une des méthodes choisies `doGet`, `doPost` (l'implémentation par défaut renvoie une page 404).
- On indique au serveur quels sont l(es) URL(s) traitées par la servlet. Ceci se fait dans le fichier `web.xml` ou par annotation.
=== HttpServletRequest
Représente la requête
Paramètres, cookies
Attributs...
=== HttpServletResponse
Représente la réponse.
=== Cycle de vie
Le cycle de vie est géré par le serveur d'application (_d'où son nom_).
Celui-ci _crée_ et _détruit_ des instances de la classe.
=== Exemple
[source]
----
class MaServlet extends HttpServlet
{
protected void doGet( HttpServletRequest r, HttpServletResponse re )
{
re.setContentType( "text/html; charset=utf8" );
re.getWriter().print( "Hello world !" );
}
}
----
== JSP
=== Définition
L'écriture de la vue (en HTML) est _pénible_ dans un fichier Java. Les `JSP` permet au contraire d'écrire en HTML et d'injecter du Java.
=== Fonctionnement
Vous écrivez des fichiers `.jsp`.
Ces fichiers sont compilés vers des servlets Java.
La servlet est accessible à l'URL correspondant au nom du fichier JSP (sauf quand il est dans `WEB-INF`).
Les variables `request`, `response` sont accessibles.
=== Exercice
Faire une page de login.
NOTE: Mettre `<%@ page pageEncoding="UTF-8" %>` pour utf8.
Poser du code : `<% ... %>`
Faire un echo : `<%= ... %>`
Commentaires : `<%-- ... --%>`
Directive : `<%@ page import="package.class"%>`, ...
=== Délégation 1
Délégation à partir d'une servlet :
[source]
----
void doGet( HttpServletRequest request, HttpServletResponse response )
{
this.getServletContext()
.getRequestDispatcher( "/WEB-INF/test.jsp" )
.forward( request, response );
}
----
=== Délégation 2
Transmission d'information. Dans la servlet :
[source,language="java"]
----
request.setAttribute( "test", message );
----
Dans la JSP, on écrira :
[source,language="jsp"]
----
<% String attribut = (String) request.getAttribute("test"); out.println( attribut );%>
----
=== Formulaires
L'envoi de données au moment de la requête se fait grâce aux formulaires HTML.
Les valeurs des formulaires sont récupérées grâce à la méthode `getParameter( String name )` de la classe `HttpServletRequest`.
=== Méthode GET et POST
=== Pattern MVC
Le meilleur : peu de Java dans la JSP et peu de HTML dans le Java.
On arrive naturellement au pattern _MVC_ ou apparentés.
=== Les opérations CRUD
En exercice, implémenter sur un type de données :
- l'affichage (**D**isplay),
- la création de nouveaux éléments (**C**reate),
- la suppression d'éléments (**R**emove),
- la modification d'éléments (**U**pdate).
=== Les JSTL
Il est possible d'étendre le _vocabulaire_ des balises utilisables dans un ficher JSP.
Cette fonctionnalité est fournie par les _tag lib_ JSTL.
https://openclassrooms.com/courses/creez-votre-application-web-avec-java-ee/objectifs-et-configuration[OpenClassRooms]
=== Importation d'une tag lib
_Au préalable, il faut avoir le jar `jstl-1.2.jar` dans le projet_.
Import dans une JSP : `<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>`, ceci définit le _namespace_ XML `c`.
=== JSTL Exemple 1
Ceci est l'équivalent de la directive `<%@ include file="..." %>` :
[source]
----
<jsp:include page="<%= jspPageName %>" />
----
=== JSTL Exemple 2
Nous souhaitons réécrire le code suivant :
[source,language="jsp"]
----
<%
List<Integer> list = (ArrayList<Integer>) request.getAttribute( "tirage" );
for( int i = 0; i < list.size(); i++ ) {
out.println( list.get( i ) );
}
%>
----
=== JSTL Exemple 2
Voici l'équivalent avec la JSTL :
[source,language="jsp"]
----
<c:forEach var="i" begin="0" end="7" step="1"> <1>
<tr>
<td><c:out value="${i}"/></td> <2>
<td><c:out value="${i * i * i}"/></td>
</tr>
</c:forEach>
----
<1> le noeud `forEach` crée une variable EL `i`.
<2> la variable `i` est utilisée dans des expressions EL.
=== Expression Language
https://openclassrooms.com/courses/creez-votre-application-web-avec-java-ee/la-technologie-jsp-2-2[OpenClassRooms].
Quelques éléments du langage :
- `${ expression }` : _expression_ va être interprêtée...
- `${ true && true }` : ...
- `${ 10 mod 4 }` : ...
- `${ requestScope['nom'] }` : request.getAttribute( "nom" )
- `${ sessionScope['nom'] }` : session.getAttribute( "nom" )
- `${ param['id'] }` : request.getParameter( "id" )
=== EL exemple
[source]
----
<%
List<String> legumes = new ArrayList<String>();
legumes.add( ... );
request.setAttribute( "legumes" , legumes );
%>
${ legumes.get(1) }
${ legumes[1] }
${ legumes["1"] }
----
=== Scope
JSP définit quatre _scopes_ (portées ou cycles de vie) pour les objets :
`application`, `session`, `request` et `page`.
Ceux-ci sont implémentés grâce aux attributs de requête, de session, et de contexte applicatif.
=== Scope
|===
|Portée | Servlet | JSP
|*application*
|`getServletContext()`
|`applicationScope[]`
|*session*
|`request.getSession()`
|`sessionScope[]`
|*request*
|`request`
|`requestScope[]`
|*page*
|-
|`pageScope[]`
|===
== JavaBean
Une convention pour exprimer la notion de _propriété_. En écriture et/ou lecture.
Exemple, la propriété `Longueur` :
[source,language="java"]
----
int getLongueur() { ... }
void setLongueur( int valeur ) { ... }
----
Il peut y avoir une notion d'abonnement (pattern _Observer_).
== JSF
=== Introduction
C'est un framework MVC pour simplifier l'écriture d'interface graphiques Web.
Fonctionne au dessus de l'api Servlet. Stable et utilisable depuis la version 2.0 en 2009.
=== FacesServlet
Une seule servlet prend en charge toutes les requêtes et maintient l'état de la vue de _chaque_ client.
`javax.faces.webapp.FacesServlet`
=== Facelet
La programmation des vues repose sur _Facelet_, description XML des composants de la vue.
Fichiers `*.xhtml`
=== Controlleur
La programmation des actions (_controlleur_) s'écrit dans des _Java Beans_.
`@ManagedBean`, `@RequestScoped`, `@ViewScoped`, `@SessionScoped`, `@ApplicationScoped`, `@CustomScope` et `@NoneScoped`...
=== Modèle
Les données attachées aux échanges HTTP sont stockées dans des _Java Beans_ attachés aux différents scopes.
=== Avantage
Facilite la gestion conversationnelle grâce au modèle par composant.
Gère par ex. état des vues, maj des modèles, invocation des actions métiers, génération de la réponse, évènements, validation, internationnalisation...
=== Contrepartie
On ne maîtrise pas vraiment le HTML généré car la génération de celui-ci est encapsulée dans le code des composants.
=== Structure d'une application JSF
- Vue : Facelet (un fichier *xhtml*),
- Modèle : entité JPA ou JavaBean,
- Controlleur : des `@ManagedBean`s
Configuration en plus de `web.xml` dans `faces-config.xml`.
=== Les fichiers Facelet
Ce ne sont que des fichiers XHTML (HTML conforme au XML). On utilise les extensions : **.jsf** ou **.xhtml** ou **.faces**.
Références des balises JSF : http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/[ici], http://www.jsftoolbox.com/documentation/help/12-TagReference/index.jsf[ici] et sur http://stackoverflow.com/tags/jsf/info[stack overflow].
=== Exemple
[source,language="xml"]
----
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Bienvenue</title>
<h:outputStylesheet library="default" name="cartes.css"></h:outputStylesheet>
</h:head>
<h:body>
<h:form>
<h:inputText value="#{utilisateur.nom}" />
<h:commandButton value="Valider" action="bienvenue" />
</h:form>
</h:body>
</html>
----
=== Expression Language pour JSF
L'évolution technique d'expression language fait que pour JSF, on utilise la syntaxe du type :
#{inscrireBean.utilisateur.motDePasse}
On voit donc que `$` est remplacé par `#`. Ceci correspond au fait que l'expression language pour JSF permet d'appeler des *setters* sur les java beans, ce qui n'est pas permis avec `$`.
Depuis Java EE 6, expression language a été unifié et il est maintenant possible d'utiliser `#` dans les JSP.
=== Les 6 étapes du traitement d'une requête (1/2)
- **Restauration de la vue** : si c'est un premier accès JSP crée une donnée de vue (l'arbre des composants) dans `FacesContext`. Sinon JSF recharge simplement les données de la vue.
- **Application des paramètres** de la requête : JSF fait automatiquement le lien entre les paramètres présents dans la requête et les champs du modèle à modifier.
- **Validation des données** : si la validation échoue, on passe directement à la dernière étape.
=== Les 6 étapes du traitement d'une requête (2/2)
- **Mise à jour du modèle** : si la validation s'est bien déroulée, cette étape consiste à mettre à jour les données du modèle avec les données validées.
- **Appel au code métier** de l'application : les actions déclarées dans les formulaires sont exécutées, sous la forme d'appels aux méthodes des Beans.
- **Rendu de la réponse** : l'arbre des composants est appelé afin de générer le HTML résultat. Il est mémorisé pour la prochaine _Restauration de vue_.
=== Configuration
Dans `web.xml` on ajoute :
[source,language="xml"]
----
<context-param>
<!-- autres noms possibles : STATE_SAVING_METHOD, INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL ... -->
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
----
=== Tutoriel
https://openclassrooms.com/courses/creez-votre-application-web-avec-java-ee/premiers-pas-avec-jsf
=== Gestion de formulaires
https://openclassrooms.com/courses/creez-votre-application-web-avec-java-ee/la-gestion-d-un-formulaire-avec-jsf
== JPA
=== Systèmes de gestion de base de données relationnelles
Un outil pour :
- **structurer**,
- **stocker**,
- **interroger**,
- et garantir l'**intégrité** des données.
=== Service
Le SGBD est un processus actif sur une machine. Il ouvre des ports de communication.
Et les applications s'y connectent.
=== Table
Nous stockons les **enregistrements** dans des **tables** possédant une ou plusieurs *colonnes* :
[cols=2, options="header"]
|===
|Nom
|Prénom
|Tournier
|Arnaud
|Dupont
|Jean
|Serres
|Mélanie
|Dupont
|Jean
|===
=== Clé
Les enregistrements sont repérés de façon sûre grâce aux **identifiants** aussi appelés **clés primaire (PK)**.
Chaque identifiant est **unique**.
[cols=3, options="header"]
|===
|ID
|Nom
|Prénom
|1
|Tournier
|Arnaud
|3
|Dupont
|Jean
|7
|Serres
|Mélanie
|4
|Dupont
|Jean
|===
=== Clé étrangère
Pour relier les enregistrements entre eux, on utilise les **clés étrangères** :
[cols=4, options="header"]
|===
|ID
|Entreprise_ID
|Nom
|Prénom
|1
|44
|Tournier
|Arnaud
|3
|5
|Dupont
|Jean
|4
|44
|Serres
|Mélanie
|===
=== DDL
Langage permettant de définir la structure des données dans la base de données.
[source,language="sql"]
----
CREATE TABLE IF NOT EXISTS `personne` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nom` text COLLATE utf8_bin NOT NULL,
`prenom` varchar(50) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;
----
=== SQL
Langage permettant d'interroger, de créer, supprimer et manipuler les données, en fonction de la structure définie.
Quelques exemples...
=== Insert
Insérer un enregistrement dans une table :
[source,language="sql"]
----
INSERT INTO `personne` (`nom`, `prenom`) VALUES ('Tournier', 'Arnaud');
----
Dans cette table, l'identifiant est généré automatiquement...
=== Update
Mise à jour d'un ou des enregistrements :
[source,language="sql"]
----
UPDATE `personne` SET `nom`="Toto", `prenom`="Titi" WHERE id=1;
----
=== Delete
[source,language="sql"]
----
DELETE FROM `personne` WHERE nom LIKE "To%";
----
=== Select
L'opération la plus utilisée : pour consulter la base de données
[source,language="sql"]
----
SELECT * FROM `personne` WHERE prenom LIKE "a%";
----
=== Jointure
Il est possible de _combiner_ des tables en faisant un select :
[source,language="sql"]
----
SELECT * FROM `personne` p LEFT JOIN `entreprise` e ON p.entreprise_id=e.id;
SELECT p.id, p.nom, e.nom, e.adresse FROM `personne` p LEFT JOIN `entreprise` e ON p.entreprise_id=e.id;
----
=== Transactions
On souhaite pouvoir exécuter une suite d'instruction de manière **atomique** et **cohérente** (voir les propriétés _ACID_).
[source,language="sql"]
----
START TRANSACTION;
COMMIT; // on valide ou...
ROLLBACK; // on annule
----
_Interblocage ?_
=== Bien plus...
Le langage SQL est extrêmement riche, nous avons à peine gratté la surface...
Voici un http://sql.sh/[cours et tutoriel] pour aller plus loin.
=== Quelques serveurs SQL
De nombreuses implémentations existent, avec parfois quelques variantes dans le _dialecte_ SQL : MySQL, MariaDB, Oracle, PostgreSQL, Microsoft SQL Server, SQLite, ...
=== Important !
- Un SGBD peut gérer plusieurs _bases de données_,
- Une base de données peut contenir plusieurs _tables_,
- Une table possède plusieurs _colonnes_.
- Les enregistrements sont repérés par leur _clé primaire_,
- On référence un enregistrement à partir d'un autre avec une _clé étrangère_.
- SQL garantit la cohérence des données avec les _transactions_.
=== Accès depuis un programme Java
L'accès le plus bas niveau avec Java se fait à travers le _driver JDBC_ adapté au serveur auquel on se connecte.
=== Charger le driver adapté
La classe doit être présente dans le _classpath_...
[source,language="java"]
----
try
{
Class.forName( "com.mysql.jdbc.Driver" );
}
catch( ClassNotFoundException e )
{
...
}
----
=== Se connecter au serveur SQL
Il faut connaître l'URL de connexion...
[source,language="java"]
----
try
{
Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/cartes", "root", "password" );
}
catch( SQLException e )
{
...
}
----
=== Exécuter des requêtes
Exemple de `SELECT` :
[source,language="java"]
----
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery( "SELECT id, nom, couleur from carte" ); <1>
while( rs.next() )
{
String id = rs.getString( "id" );
String nom = rs.getString( "nom" );
String couleur = rs.getString( "couleur" );
System.out.printf( "%s %s %s\n", id, nom, couleur );
}
----
<1> Il existe aussi `execute()` et `executeUpdate()`
=== Les transactions
Les instructions de transactions sont accessibles directement en Java :
[source,language="java"]
----
// on désactive l'auto-commit
conn.setAutoCommit( false );
// on joue la transaction...
Statement statement = conn.createStatement();
// ...
// on valide la transaction
conn.commit();
// on aurait pu l'annuler avec 'conn.rollback()'
----
=== Plus de JDBC
Pour aller plus loin avec JDBC, consulez la https://docs.oracle.com/javase/tutorial/jdbc/basics/[documentation officielle].
=== ORM
L'écriture du code SQL et DDL est fastidieuse et répétitive. Les _ORM_s sont une sur-couche qui permettent un accès au SGBD plus conforme à la vision objet.
L'ORM prend en charge la communication avec le SGBD et fourni à l'application une _API_ de plus haut niveau.
=== JPA
- Java Persistence API,
- https://jcp.org/en/jsr/detail?id=317[JSR 317],
- _Entity manager_ et _Entités_,
- langage _JPQL_...
- package `javax.persistence`.
=== Fournisseurs
Plusieurs implémentations : Hibernate, Toplink, DataNucleus, ...
=== @Entity
- Classe dont l'état est sauvegardé dans une _table_.
- Chaque instance correspond à un _enregistrement_.
- Les attributs correspondent aux colonnes.
- Les relations sont exprimées avec des annotations (ou xml).
=== @Id
Dénote l'attribut utilisé comme clé primaire.
On précise la stratégie de génération des identifiants.
=== Exemple
[source,language="java"]
----
@Entity
public class Utilisateur implements Serializable
{
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Integer id;
@NotNull
private String nom;
// méthodes, getters, setters
}
----
=== Entity Manager
Une instance de la classe `EntityManager` fait le lien entre les données de la base et les objets _entités_.
Opérations essentielles : `persist`, `merge`, `remove`, `find`, `createQuery`...
Objets détachés...
=== Persist
[source,language="java"]
----
public void add( Utilisateur utilisateur )
{
em.persist( utilisateur );
}
----
=== Merge
[source,language="java"]
----
public Utilisateur save( Utilisateur utilisateur )
{
return em.merge( utilisateur );
}
----
=== Find
[source,language="java"]
----
public Utilisateur findById( int id )
{
return em.find( Utilisateur.class, id );
}
----
=== Remove
[source,language="java"]
----
public void delete( Utilisateur utilisateur )
{
em.remove( utilisateur );
}
----
=== JPQL
Langage inspiré par SQL qui est pensé avec le paradigme objet.
=== Create Query
[source,language="java"]
----
public Utilisateur findByLogin( String login, String motDePasse )
{
Query query = em.createQuery( "from Utilisateur u where u.login=:login and u.motDePasse=:motDePasse" );
query.setParameter( "login", login );
query.setParameter( "motDePasse", motDePasse );
Utilisateur u = (Utilisateur) query.getSingleResult();
return u;
}
----
=== Create Query
[source,language="java"]
----
public List<Utilisateur> getUtilisateurs()
{
Query query = em.createQuery( "from Utilisateur" );
List<Utilisateur> result = (List<Utilisateur>) query.getResultList();
return result;
}
----
=== Criteria API
Il y a aussi une http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html[API] pour éviter le _JPQL_ et construire les requêtes programmatiquement.
=== Requêtes nommées
=== Relations
JPA gère les relations entre enregistrements et donc entre entités.
http://docs.oracle.com/javaee/7/tutorial/persistence-intro001.htm#BNBQA[voir ce site]
=== @OneToOne
=== @OneToMany
=== @ManyToOne
=== @ManyToMany
=== Utilisation standalone
Il est possible d'utiliser JPA indépendamment d'un serveur d'application Java EE.
=== Dans une application JavaEE
JPA est totalement intégré au fonctionnement d'une application Java EE.
Plusieurs éléments de configuration sont nécessaires...
=== Sources de données
Les _Data source_ sont configurées dans le serveur d'application. On y précise le _driver_, l'_url de connexion_ et les information d'_authentification_.
Chaque implémentation se configure différemment.
=== Fichier persistence
`META-INF/persistence.xml`
[source,language="xml"]
----
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="Cartes" transaction-type="JTA"> <1>
<jta-data-source>CartesDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
</properties>
</persistence-unit>
</persistence>
----
<1> Type de transaction JTA
=== EJB
- **Composants** logiciels (métier) de base de Java EE.
- Naturellement **distribué**.
- Evoluent dans un milieu **transactionnel**.
=== Plusieurs types
- `@Local` ou `@Remote`,
- `@Stateful` ou `@Stateless`,
- EJB Message.
- Enregistré dans JNDI.
=== Création d'un EJB
Soit une interface (`@Remote` ou `@Local`) et une classe, soit depuis EJB 3 une seule classe :
[source,language="java"]
----
// un EJB de session sans état
@Stateless
public class MonEJB {
// par exemple :
@PostConstruct
void onInit() {
}
}
----
=== Injection de dépendances
Le serveur d'application peut injecter des composants en utilisant les annotations :
- `@EJB` : un autre EJB,
- `@Resource` : une resource JNDI (EntityManager, UserTransaction, SessionContext, ...),
=== Exemple
[source,language="java"]
----
@Stateless( mappedName = "MarinService" )
public class MarinServiceImpl implements MarinService {
@Resource
private UserTransaction transaction;
@Resource( mappedName = "jdbc/CartesDS" )
private DataSource dataSource;
@PersistenceContext( unitName = "CartesDS" )
private EntityManager em;
// ...
}
----
=== Injection de l'unité de persistence
Au sein d'un _EJB_, on peut injecter une instance de l'`EntityManager` :
[source,language="java"]
----
@Stateless
public class ProduitDao
{
@PersistenceContext( name = "SiteDeVente" )
EntityManager em;
// ...
// utilisation de l'EntityManager
}
----
=== Injection du DAO
Au sein d'une servlet ou d'un _Managed Bean_, il est possible d'injecter une instance de l'EJB :
[source,language="java"]
----
@ManagedBean
@ViewScoped
public class ProduitsBean implements Serializable
{
@EJB
ProduitDao produitDao;
// ...
// utilisation du DAO
}
----
=== Gestion de la transaction
Les méthodes EJB s'exécutent dans un contexte _transactionnel_. Une transaction est (toujours) ouverte (automatiquement).
Le comportement est modifiable avec `@TransactionAttribute`.
Si une exception surgit hors de la méthode, la transaction est abandonnée (_rollback_).
=== Pattern DAO
DAO:: Data Access Object ayant la responsabilité de fournir les données.
C'est lui qui accède à l'`EntityManager`.
=== Organisation en couches