Julien Maitrehenry - Docker, ça mange quoi au printemps
1 2-3-grails
1. À VOS MARQUES...
1, 2, 3
GRAILS!
Des applications pour le web vite, facile, et “fun”
2. Grails
Un “framework” pour developer des applications pour le web
Déploiment vers JVM AJAX/xml/JSON
ORM
i18n: internationalisation
Groovy Une fois, c’est assez
TDD/Mocks/Stubs
DRY: Don’t repeat yourself
Sitemesh
Contrôleurs
Inversion du contrôle/injection de dépendances
(IoC/DI: Inversion of control/dependency injection)
Plugins Conventions/configuration
GSP Taglibs
3. Groovy
•Compilé
•Dynamique
•Exécuté sur JVM
•Lambdas et closures
•Strings dynamiques - GStrings
•Syntaxe aisée:
- ; pas nécessaires ne sont pas requis
- manipulations de listes
- manipulations de “beans”/propriétés
- méthodes sur les listes: ex: l.each {}
4. $ grails create-project
> waq-o-theque
$ cd waq-o-theque
$ ls
application.properties
grails-app
lib
scripts
src
test
web-app
12. $ grails run-app
Welcome to Grails 1.3.6 - http://
grails.org/
Licensed under Apache Standard
License 2.0
Grails home is set to: /Developer/
STS-2.5.1/grails-1.3.6
[...]
Running Grails application..
Server running. Browse to http://
localhost:8080/waq-o-theque
21. // environment specific settings
environments {
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-
drop','update'
url = "jdbc:mysql://localhost:3306/waqotheque_dev”
show_sql = true
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/waqotheque_test"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/waqotheque"
}
}
}
22. sql> show tables;
-------------------------+
Tables_in_waqotheque_dev |
-------------------------+
bien |
-------------------------+
row in set (0.00 sec)
sql> desc bien;
------------+--------------+------+-----+---------+----------------+
Field | Type | Null | Key | Default | Extra |
------------+--------------+------+-----+---------+----------------+
id | bigint(20) | NO | PRI | NULL | auto_increment |
version | bigint(20) | NO | | NULL | |
description | varchar(255) | YES | | NULL | |
nom | varchar(255) | NO | UNI | NULL | |
class | varchar(255) | NO | | NULL | |
genre | varchar(255) | YES | | NULL | |
interprete | varchar(255) | YES | | NULL | |
auteur | varchar(255) | YES | | NULL | |
------------+--------------+------+-----+---------+----------------+
rows in set (0.00 sec)
23.
24. mysql> select id, version, description from bien;
+----+---------+--------------------------------------------------+
| id | version | description |
+----+---------+--------------------------------------------------+
| 1 | 0 | Un bon vieux livre... |
| 2 | 0 | Un roman... |
| 3 | 0 | L'influence de la musique sur notre comportement |
| 4 | 0 | NULL |
+----+---------+--------------------------------------------------+
4 rows in set (0.00 sec)
mysql> select id, nom, class from bien;
+----+-----------------------+-------------------------------------+
| id | nom | class |
+----+-----------------------+-------------------------------------+
| 1 | Martine ? l'?cole | com.nancydeschenes.waqotheque.Livre |
| 2 | Au Bonheur des Ogres | com.nancydeschenes.waqotheque.Livre |
| 3 | De la note au cerveau | com.nancydeschenes.waqotheque.Livre |
| 4 | Les portes de Qu?bec | com.nancydeschenes.waqotheque.Livre |
+----+-----------------------+-------------------------------------+
4 rows in set (0.01 sec)
25. mysql> select id, interprete, genre, auteur from bien;
+----+-------------+---------+----------------------------------+
| id | interprete | genre | auteur |
+----+-------------+---------+----------------------------------+
| 1 | NULL | NULL | Gilbert Delahaye, Marcel Marlier |
| 2 | NULL | NULL | Daniel Pennac |
| 3 | NULL | NULL | Daniel J. Levitin |
| 4 | NULL | NULL | Jean-Pierre Charland |
+----+-------------+---------+----------------------------------+
6 rows in set (0.00 sec)
29. mysql> select id, version, description from bien;
+----+---------+--------------------------------------------------+
| id | version | description |
+----+---------+--------------------------------------------------+
| 1 | 0 | Un bon vieux livre... |
| 2 | 0 | Un roman... |
| 3 | 0 | L'influence de la musique sur notre comportement |
| 4 | 0 | NULL |
| 5 | 0 | L'histore d'un ogre |
| 6 | 0 | Album of the year |
+----+---------+--------------------------------------------------+
6 rows in set (0.00 sec)
mysql> select id, nom, class from bien;
+----+-----------------------+-------------------------------------+
| id | nom | class |
+----+-----------------------+-------------------------------------+
| 1 | Martine ? l'?cole | com.nancydeschenes.waqotheque.Livre |
| 2 | Au Bonheur des Ogres | com.nancydeschenes.waqotheque.Livre |
| 3 | De la note au cerveau | com.nancydeschenes.waqotheque.Livre |
| 4 | Les portes de Qu?bec | com.nancydeschenes.waqotheque.Livre |
| 5 | Shrek | com.nancydeschenes.waqotheque.DVD |
| 6 | The Suburbs | com.nancydeschenes.waqotheque.CD |
+----+-----------------------+-------------------------------------+
6 rows in set (0.01 sec)
39. Internationalisation
Langue de départ
grails-app/conf/spring/resources.groovy
// Place your Spring DSL code here
import org.springframework.web.servlet.i18n.SessionLocaleResolver
beans = {
localeResolver(SessionLocaleResolver) {
defaultLocale= Locale.FRENCH
Locale.setDefault (Locale.FRENCH)
}
}
Charset/encoding
grails-app/conf/config.groovy
grails.views.gsp.encoding = "UTF-8"
grails.converters.encoding = "UTF-8"
waq-o-theque v0.02
40. ORM: de l’oject à la BD
Object Relation Mapping
•Pour les objets du domaine
•Le schéma est créé par l’application ou en utilisant une BD
existante
•Le datatype est deviné à partir de la définition des classes
•monObject.save()
•MaClasse.get(id)
•MaClasse.findAll()
•Livre.findAllByAuthor(“Sartre”)
•Relations entre object
- 1..1
- 1..[0,1]
- 1..[0,n]
- n..1
- n..n (avec “join table” ou “join object”)
44. ORM: Contraintes
Contraintes
Personne.groovy
static constraints = {
prenom(blank:false, nullable: false)
nom(blank:true, nullable:true)
fiabilite(blank:true, nullable:true, min:0, max:5)
}
messages_fr.properties
default.invalid.max.size.message=La propriété
[{0}] de la classe [{1}] avec la valeur [{2}]
est supérieure à la valeur maximum [{3}]
default.invalid.min.size.message=La propriété
[{0}] de la classe [{1}] avec la valeur [{2}]
est inférieure à la valeur minimum [{3}]
45.
46. Bien.groovy
static constraints = {
nom(blank: false, nullable:false, unique:true)
description(nullable:true)
}
messages_fr.properties
default.not.unique.message=La propriété [{0}]
de la classe [{1}] avec la valeur [{2}]
doit être unique
DVD.nom.unique=Vous avez déjà enregistré un
bien appelé {2}.
67. ConseilPretsService.groovy
package com.nancydeschenes.waqotheque
class ConseilPretsService {
static transactional = false
def beneficeDuDoute = 40;
def devraitPreter(Personne aQui, Bien quoi) {
// A formule pourait utiliser le bien, mais
// pour l'instant, allons-y avec l'emprunteur seulement
devraitPreter(aQui)
}
def devraitPreter(Personne aQui) {
// Formule super compliquée... ou pas!
// 0..5 -> 0..100, puis on applique le bénéfice du doute
return aQui.fiabilite * 20 > beneficeDuDoute
}
}