36
Wir bauen uns eine Webapplikation! Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Embed Size (px)

Citation preview

Page 1: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wir bauen uns eine Webapplikation!

Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Page 2: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Unsere Webapplikation kann nach Schauspieler/innen suchen…

Page 3: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Unsere Webapplikation kann nach Schauspieler/inne suchen…

Page 4: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

… und allerlei Informationen zu einem Film anzeigen

Page 5: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Play Framework 2.0Strukturiert unsere Web-Applikation

Page 6: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das? Analogie Bibliotheken, Zeitschriftenverleih

Wer Mit wem Resultat

1. Kunde Schalter: Bibliothekarin Bestimmt, welcher Archivar die Zeitschrift holen geht

2. Schalter: Bibliothekarin

Archivar Kontrollübergabe

2.1 Archivar Zeitschriften Archiv Gewünschte Zeitschrift

2.2 Archivar Kopiergerät Kopien der gewünschten Seiten an Bibliothekarin übergeben

3 Schalter: Bibliothekarin Kunde Übergabe der kopierten Seiten an Kunde

Page 7: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das? Analogie Bibliotheken, Zeitschriftenverleih

Wer Mit wem Resultat

1. Kunde Schalter: Bibliothekarin Bestimmt, welcher Archivar die Zeitschrift holen geht

2. Schalter: Bibliothekarin

Archivar Kontrollübergabe

2.1 Archivar Zeitschriften Archiv Gewünschte Zeitschrift

2.2 Archivar Kopiergerät Kopien der gewünschten Seiten an Bibliothekarin übergeben

3 Schalter: Bibliothekarin Kunde Übergabe der kopierten Seiten an Kunde

Wir müssen für unsere Webapplikation programmieren: 1 – «Archivar», der die Kontrolle inne hat2 – «Archiv», die Anbindung an die Datenbank3 – «Kopiergerät», das sich um Darstellung kümmert

Page 8: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das? Analogie Bibliotheken, Zeitschriftenverleih

«Controller»Archivar

«Model»Zeitschriften

Archiv

«View»Kopiergerät

1 3

2 4

Page 9: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Client-Server Applikationen

Client

Der BrowserFirefoxChromeSafari

Internet Explorer…

Server

ApacheTomcatPlay

Microsoft IIS…

Internet

URLhttp://localhost:9000/?f=Redford

Die darzustellende WebseiteHTML

Page 10: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: Controller: RoutingDatei conf/routes

# URL Methode, die ausgeführt werden sollGET /controllers.Application.actors(f ?= "")GET /actors controllers.Application.actors(f ?= "")GET /actorcontrollers.Application.actor(id:Long)

GET /moviescontrollers.Application.movies(f ?= "")GET /moviecontrollers.Application.movie(id:Long)

Mit dieser Datei teilen wir dem Play Controller mit, wer die Anfrage einer URL beantworten soll.

Browser:

http://localhost:9000/?

f=Redford

Page 11: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ActionsKlasse controllers.Application

@Transactional(readOnly = true)public static Result actors(String name) { List<Actor> actors = Actor.findActorsByName(name); // 1 return ok(views.html.actors.render(actors)); // 2}

Mit dieser Methode definieren wir, wie die Anfrage beantwortet werden soll. Eine Controller-Methode geht typischerweise zweistufig vor.

1. Wir suchen die angeforderten Daten («Archiv»).

2. Wir stellen die gefundenen Daten dar («Kopiergerät»).

Play Server:

Aufruf von Application.

actors("Redford")

Page 12: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: Model

Application.actors:

Aufruf von Actor.findActor

sByName("Redfo

rd")

Klasse models.ActorDiese Klasse hat zwei Aufgaben.

1. Sie beschreibt die Tabelle «actors» in der MySQL-Datenbank.

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { @Id public Long actorid; // d.h. actorid ist Primärschlüssel public String name; public String sex; // …}

Page 13: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Java Persistence API

Meta-Informationen im Java-CodeDie sog. Annotationen wie @Entity beinhalten Informationen, die den Code beschreiben.

Das Java Persistence API (JPA) ordnet Java-Klassen Tabellen in relationalen Datenbanken zu:

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { @Id public Long actorid; // d.h. actorid ist Primärschlüssel public String name; // d.h. es gibt eine Spalte name in DB public String sex; // d.h. es gibt eine Spalte sex in DB // …}

Siehe auch de.wikipedia.org/wiki/Java_Persistence_API

Page 14: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ModelAufruf von

Actor.findActors

ByName("Redford")

Klasse models.ActorDiese Klasse hat zwei Aufgaben.

2. Sie hat Methoden, um Daten zu suchen:

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Page 15: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ModelfindActorsByName: Schritt für

Schritt

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Wir definieren Methode, die einen String als Input erhält und eine Liste von Actor-Objekten zurückliefert.

Page 16: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ModelfindActorsByName: Schritt für

Schritt

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Falls der Input “name” vorhanden und nicht-leer ist:

Page 17: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ModelfindActorsByName: Schritt für

Schritt

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Wir definieren Abfrage. Da wir die JPA-Umsetzung Hibernate verwenden, müssen wir die Hibernate Queery Language (HQL) verwenden. Siehe de.wikipedia.org/wiki/Hibernate_(Framework).

Page 18: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ModelfindActorsByName: Schritt für

Schritt

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Wir bereiten die Hibernate-Anfrage vor. Wir geben mit Actor.class an, dass wir als Resultat der Anfrage eine Liste von Actor-Objekten erwarten.

Page 19: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ModelfindActorsByName: Schritt für

Schritt

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Wir legen fest, dass Hibernate den Platzhalten «:name» durch den Wert ersetzen soll, der durch den Ausdruck "%" + name + "%" entsteht (in unserem Beispiel “%Redford%”.

Page 20: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: ModelfindActorsByName: Schritt für

Schritt

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Wir lassen Hibernate die Query ausführen. Unsere Methode liefert die Resultat-Liste von Actor-Objekten zurück, die uns Hibernate gibt.

Page 21: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: Model

findActorsByName: Schritt für Schritt

@Entity(name = "actors") // der Name der Tabellepublic class Actor implements Serializable { public static List<Actor> findActorsByName(String name) { if (name != null && !name.equals("")) { // Achtung, Abfrage ist HQL, nicht SQL! String hql = "SELECT a FROM actors a WHERE name LIKE :name"; TypedQuery<Actor> query = JPA.em().createQuery(hql, Actor.class); query = query.setParameter("name", "%" + name + "%"); return query.getResultList(); } return new ArrayList<Actor>(); }}

Falls der Input “name” nicht vorhanden oder leer ist: Liefere leere Liste von Actor-Objekten zurück.

Page 22: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

Application.actors:

Aufruf von views.html.acto

r.render(actors)

Template views/movie.scala.htmlDas Template gibt an, wie die Daten dargestellt werden.

Teil 1: Definition der View; Formular@(actors: List[Actor])

@main(title = "IMDB-Webapplikation: Suche nach Schauspielern") {

<h2>Schauspieler suchen</h2>

<form> <input type="text" name="f" value="@request.queryString.getOrElse("f", Array()).mkString"></form>

Page 23: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@(actors: List[Actor])

@main(title = "IMDB-Webapplikation: Suche nach Schauspielern") {

<h2>Schauspieler suchen</h2>

<form> <input type="text" name="f" value="@request.queryString.getOrElse("f", Array()).mkString"></form>

Hinter dem @-Zeichen kommt jeweils ein Scala-Ausdruck. In dieser Zeile definieren wir, dass diese View als Input die Variable «actors» erhält, die eine Liste von Actor-Objekten ist.

Page 24: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Scala

Scala

Page 25: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@(actors: List[Actor])

@main(title = "IMDB-Webapplikation: Suche nach Schauspielern") {

<h2>Schauspieler suchen</h2>

<form> <input type="text" name="f" value="@request.queryString.getOrElse("f", Array()).mkString"></form>

Hier rufen wir das Template main.scala.html auf. Das Template stellt das Gerüst einer Seite dar (Header, Menü, Footer). Wir übergeben diesem Template als Inhalt der Seite alles, was zwischen den geschweiften Klammern steht.

Page 26: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@(actors: List[Actor])

@main(title = "IMDB-Webapplikation: Suche nach Schauspielern") {

<h2>Schauspieler suchen</h2>

<form> <input type="text" name="f" value="@request.queryString.getOrElse("f", Array()).mkString"></form>

Hier definieren wir das Eingabe-Formular. «input» ist ein Eingabefeld vom Typ «text» und hat den Namen «f». Dieser Name ist wichtig: Der muss gleich sein wie in der Konfigurations-Datei routes.

Page 27: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

Template views/movie.scala.html

Teil 2: Darstellung der Daten

@if(!actors.isEmpty()) { <table> <tr><th>Name</th><th>Geschlecht</th></tr> @for(actor <- actors) { <tr> <td><a href="@routes.Application.actor(actor.actorid)"> @actor.name</a></td> <td>@actor.sex</td> </tr> } </table>}

}

Page 28: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@if(!actors.isEmpty()) { <table> <tr><th>Name</th><th>Geschlecht</th></tr> @for(actor <- actors) { <tr> <td><a href="@routes.Application.actor(actor.actorid)"> @actor.name</a></td> <td>@actor.sex</td> </tr> } </table>}

Falls die Liste von Actor-Objekten nicht leer ist (der Benutzer also eine erfolgreiche Suche durchgeführt hat):

Page 29: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@if(!actors.isEmpty()) { <table> <tr><th>Name</th><th>Geschlecht</th></tr> @for(actor <- actors) { <tr> <td><a href="@routes.Application.actor(actor.actorid)"> @actor.name</a></td> <td>@actor.sex</td> </tr> } </table>}

Dann zeige eine Tabelle an. Erste Zeile enthält die Spaltentitel.

Page 30: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@if(!actors.isEmpty()) { <table> <tr><th>Name</th><th>Geschlecht</th></tr> @for(actor <- actors) { <tr> <td><a href="@routes.Application.actor(actor.actorid)"> @actor.name</a></td> <td>@actor.sex</td> </tr> } </table>}

Fülle die Tabelle mit weiteren Zeilen: Erstelle eine Tabellenzeile für jedes Actor-Objekt in der Liste der “actors”.

Page 31: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@if(!actors.isEmpty()) { <table> <tr><th>Name</th><th>Geschlecht</th></tr> @for(actor <- actors) { <tr> <td><a href="@routes.Application.actor(actor.actorid)"> @actor.name</a></td> <td>@actor.sex</td> </tr> } </table>}

Zeige einen Link auf die Detailansicht von Schauspielern an. Wir können den Link von Play abfragen über routes.Application.actor – genauso, wie es in der Konfigurationsdatei routes definiert ist.

Page 32: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@if(!actors.isEmpty()) { <table> <tr><th>Name</th><th>Geschlecht</th></tr> @for(actor <- actors) { <tr> <td><a href="@routes.Application.actor(actor.actorid)"> @actor.name</a></td> <td>@actor.sex</td> </tr> } </table>}

Beschrifte den Link mit dem Namen des Schauspielers. Hier können wir einfach alle Felder der Klasse “Actor” für die Anzeige verwenden.

Page 33: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: View

movie.scala.html Schritt für Schritt

@if(!actors.isEmpty()) { <table> <tr><th>Name</th><th>Geschlecht</th></tr> @for(actor <- actors) { <tr> <td><a href="@routes.Application.actor(actor.actorid)"> @actor.name</a></td> <td>@actor.sex</td> </tr> } </table>}

Zeige in der nächsten Spalte das Geschlecht des Schauspielers / der Schauspielerin an. Hier können wir einfach alle Felder der Klasse “Actor” für die Anzeige verwenden.

Page 34: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das? Beispiel Aufruf von localhost:9000/

Wer Mit wem Resultat

1. Browser: localhost:9000

Play Server: Controller Action bestimmen, die für Anfrage zuständig ist

2. Play Server: Controller mit Konfiguration in routes

Unsere Controller-Action: Application.actors

Kontrollübergabe

2.1 Unsere Controller-Action: Application.actors

Unsere Model-Klasse: Actor.findActorsByName

Liste von Actor-Objekten, zwischengespeichert in Variable actors

2.2 Controller: Unsere Action: Application.actors

Unser View-Template: views. html.actors.render(actors)

Aufbereitete HTML-Seite mit Eingabeformular für Suche, mit Liste von Schauspielern, übergeben an Play Controller

3 Play Server: Controller Browser Übermittlung und Anzeige der aufbereiteten HTML-Seite

Page 35: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Play Server: Model-View-Controller

«Controller»Application.actors

«Model»Klasse Actor

«View»views/

movie.scala.html

1 3

2 4

Page 36: Play Framework, MySQL, JPA, HQL, HTML, jQuery, …

Wie funktioniert das?Struktur von Play Anwendungen

Das Play Framework basiert (wie viele andere Frameworks für Web-Applikationen) auf dem Design Pattern «Model, View, Controller» bzw. auf dem verwandten Design Pattern «Front Controller».

Siehe auch de.wikipedia.org/wiki/Model_View_Controller