tagline

Werbung
Unsere Webapplikation erweitern
Um mit Play zu arbeiten:
1. Starten Sie zunächst den MySQL-Server. Führen Sie dazu auf dem USB-Stick mysql_start.cmd aus.
2. Sie brauchen eine Windows-Kommandozeile: Starten Sie auf dem USB Stick „get
getget-readyready-toto-play.cmd“.
play.cmd
3. Wechseln Sie in das Verzeichnis mit der Play Applikation: cd workspace/play_imdbworkspace/play_imdb-database.
database cd steht
Dabei für „change directory“, Verzeichnis wechseln.
4. Starten Sie nun den Play Server: play run.
run
5. Laden Sie im Browser die Seite http://localhost:9000.
http://localhost:9000
6. Jetzt können Sie in Eclipse die Aufgaben lösen.
7. Mit Ctrl-D können Sie Play stoppen.
Weitere Hinweise zu Play:
•
Wenn Sie eine neue View hinzufügen (eine HTML-Datei im Verzeichnis app/views), müssen Sie diese
View durch Play kompilieren lassen, damit sie auch in Eclipse sichtbar wird. Führen Sie dazu den
Befehl play eclipsify aus. Machen Sie anschliessend in Eclipse auf Ihrem Projekt via Rechts-Klick auf
Projektnamen ein Refresh. Jetzt sieht auch Eclipse die neue View.
Aufgabe 1 : Nach Filmen suchen
Die Suche nach Schauspieler/innen funktioniert bereits vollständig. Bei der Suche nach Filmen fehlt noch
die Abfrage auf der Datenbank in der Klasse Movie. Die View hingegen in movies.scala.html ist bereits
programmiert, und die notwendigen Konfigurationen in conf/routes sind bereits vorhanden.
1
Wir betrachten dazu im Detail, wie die Suche nach Schauspieler/innen implementiert ist;
ist; implementieren
Sie anschliessend
anschliessend die Suche nach Filmen
Filmen analog:
analog:
In der Klasse models.Actor ist die Methode findActorsByName zuständig für die Suche nach
Schauspieler/innen:
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 + "%");
List<Actor> actors = query.getResultList();
return actors;
}
return new ArrayList<Actor>();
}
Zuerst prüft die Methode, ob der Parameter name gesetzt ist (if (name != null …).
1. Wir müssen eine
eine HQLHQL-Abfrage definieren
definieren:
en: Die Hibernate Query Language HQL ist an SQL angelehnt, ist
aber leicht anders; Details siehe
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html. Wir müssen mit HQL
arbeiten, damit uns Play einige Arbeiten abnehmen kann (mehr dazu in der folgenden Aufgabe).
Die Abfrage sucht auf der Tabelle actors (FROM
FROM actors a)
a nach allen Einträgen, wo name dem
Suchmuster entspricht, das wir als Platzhalter :name angeben (WHERE
WHERE name LIKE :name
:name).
name Wir
selektieren alle Spalten (SELECT
SELECT a – nicht SELECT * wie in SQL).
2. Wir bereiten eine Abfrage in Java vor,
vor eine sogenannte TypedQuery<Actor>.
TypedQuery<Actor> Damit weiss Play, dass wir
als Resultat unserer Suche Actor-Objekte erwarten.
3. Wir müssen noch den Wert des Platzhalters
Platzhalters :name definieren. Dazu setzen wir auf der vorbereiteten
Abfrage query den Parameter "name" auf "%" + name + "%".
"%"
4. Anschliessend führen wir die Abfrage aus (query.getResultList()
query.getResultList())
query.getResultList() und erhalten eine Liste von ActorObjekten (List<Actor>
List<Actor> actors).
return actors).
actors Diese Liste gibt unsere Methode zurück (return
actors
Falls der Parameter name nicht gesetzt ist, gibt unsere Methode eine leere Liste von Actor-Objekten zurück
(re
return
return new ArrayList<Actor>();).
ArrayList<Actor>();
1. Implementieren Sie analog die Methode findMoviesByTitle in der Klasse Movie. Im Moment gibt diese
Methode immer nur eine leere Liste von Filmen zurück.
2. Letzte Teilaufgabe: Erklären Sie sich selbst in eigenen Worten, wie die Methode findMoviesByTitle
funktioniert.
funktioniert. Es kommt dabei nicht auf die genaue Schreibweise der Java-Befehle an, sondern auf die
Schritte, die notwendig sind, damit eine Abfrage nach Filmen möglich ist.
2
Aufgabe 2 : Zitate zu einem Film anzeigen
Erweitern Sie die Ansicht zu einem Film, so dass auch Zitate angezeigt werden:
Wir betrachten dazu im Detail, wie die Taglines implementiert sind; implementieren Sie anschliessend die
Zitate analog:
1. Zuerst müssen wir das DatenbankDatenbank-Modell in Java definieren, damit Play weiss, welche Daten es aus
der Datenbank laden muss.
Die Tabelle taglines in der Datenbank enthält die Taglines der Filme. Das Datenmodell der IMDBDatenbank ist an dieser Stelle etwas speziell: Zu jedem Film gibt es genau einen Datensatz in der
Tabelle taglines; dieser Datensatz enthält alle Taglines zu einem Film, pro Tagline eine Zeile. In Heidi
SQL betrachtet sieht die Tabelle taglines wie folgt aus:
In Java sieht die Klasse models.Taglines
models.Taglines wie folgt aus:
@Entity(name = "taglines")
public class Tagline implements Serializable {
private static final long serialVersionUID = 1L;
@Id
public Long movieid;
public String taglinetext;
@OneToOne
@JoinColumn(name = "movieid")
public Movie movie;
}
Wichtig sind hier die Annotationen: @Entity gibt den Namen der Tabelle in der Datenbank an. @Id
bedeutet, dieses Feld ist der Primärschlüssel. Und für uns hier am wichtigsten: @OneToOne definiert,
dass es eine 1:1 Beziehung zwischen Movies und Taglines gibt. Mit @JoinColumn wird angegeben, wie
in der Tabelle Taglines das Feld heisst, das als Fremdschlüssel auf die Tabelle Movies verweist.
Zudem müssen wir die Datenbank-Spalte angeben, welche eigentlichen Tagline-Texte enthält: Dazu
definieren wir einfach das Feld „taglinetext
taglinetext“
taglinetext vom Typ String.
3
2. Zusätzlich muss in der Klasse models.Movie auf die Klasse Tagline verwiesen werden, damit zu einem
Film die Taglines angegeben werden können:
@Entity(name = "movies")
public class Movie implements Serializable {
// ...
@OneToOne
@JoinColumn(name = "movieid")
public Tagline tagline;
// ...
}
Damit ist das Datenbank
Datenbanknbank-Modell beschrieben.
beschrieben Wenn Play jetzt einen Movie lädt, lädt es automatisch
auch die zugehörige Tagline. Wir müssen uns nicht um die notwendige Abfrage mit JOIN von Movie und
Tagline kümmern.
a. Erstellen Sie analog eine Klasse models.Quote, welche die Tabelle quotes in Java abbildet.
b. Verknüpfen Sie analog die Klasse Movie mit der Klasse Quote.
Quote.
3. Jetzt müssen die Taglines noch anzeigt werden.
Dafür ist die View views/movie.scala.html zuständig, sie zeigt alle Informationen zu einem Film in den
verschiedenen Tabs an:
<div id="tabs-2">
@if(movie.tagline != null) {
<ul>
@for(tagline <- movie.tagline.taglinetext.split("\n")) {
<li>@tagline</li>
}
</ul>
}
</div>
Zuerst prüft der Code, ob eine Tagline für den darzustellenden Film vorhanden ist (nicht alle Filme
haben eine Tagline). Das geschieht mit dem Scala-Ausdruck @if(movie.tagline
@if(movie.tagline != null).
null) Die Variable
movie vom Typ Movie enthält den darzustellenden Film; das Feld tagline in der Klasse Movie haben wir
oben definiert.
Mit <ul> wird eine „unsortierte Liste“ in HTML gestartet. Da ein Tagline-Text wie oben erwähnt alle
Taglines zu einem Film enthält, pro Zeile eine Tagline, splitten wir den Inhalt des Feldes „taglinetext“
nach Zeile (movie.tagline.
movie.tagline.taglinetext.
n"), \n steht für „New Line“). So erhalten wir einen Array von
movie.tagline.taglinetext.split("
taglinetext.split("\
split("\n")
Strings. In Scala können wir mit for (tagline <<- …) eine Schleife über alle Elemente dieses Arrays laufen
lassen, wobei das aktuelle Element jeweils in der Variable tagline abgelegt ist. So können wir dann
über <li>@tagline</li> eine einzelne Tagline als „List Item“ (li) in HTML ausgeben. Zuletzt schliessen
wir die unsortierte Liste mit </ul>.
Erstellen Sie analog die Ansicht
Ansicht für die Quotes. Sie können dazu das noch leere HTMLHTML-Element <div
id="tabs--2"> verwenden. Hinweis: Die Zitate in der IMDB-Datenbank sind im Gegensatz zu den Taglines
id="tabs
durch jeweils eine leere Zeile getrennt. Sie müssen daher splitten nach zwei New Lines: split("\n\n").
Letzte Teilaufgabe: Erklären Sie sich selbst in eigenen Worten, welche Schritte warum notwendig waren,
damit wir die Zitate zu einem Film
Film anzeigen konnten.
konnten.
4
Aufgabe 3 : Zusatzaufgabe für die Schnellen: Nach Regisseur suchen
Die Suche nach Regisseuren ist noch nicht vollständig implementiert:
Es sind folgende Schritte notwendig:
1. Das DatenbankDatenbank-Modell für Regisseure (Tabelle directors in der IMDB-Datenbank) muss in Java
abgebildet werden.
werden Ergänzen Sie dazu das Gerüst der Klasse models.Director in Analogie zur Klasse
models.Actor: Ergänzen Sie die Felder der Tabelle (directorid, name) sowie die M:N-Beziehung zur
Tabelle actors. Ergänzen Sie die die Implementationen der Methoden findDirectorsByName und
findDirectorById.
2. Die View views/directors.scala.html für die Liste der Regisseure
Regisseure ist noch unvollständig: Ergänzen Sie
diese View in Analogie zur View views/actors.scala.html.
3. Die View views/director.scala.html für die Filme eines Regisseur
Regisseurs
sseurs ist noch unvollständig: Ergänzen Sie
diese View in Analogie zur View views/actor.scala.html.
4. Die Controller-Methoden in controllers.Application sind bereits vorhanden:
@Transactional(readOnly = true)
public static Result directors(String name) {
List<Director> director = Director.findDirectorsByName(name);
return ok(views.html.directors.render(director));
}
@Transactional(readOnly = true)
public static Result director(Long id) {
Director directors = Director.findDirectorById(id);
return ok(views.html.director.render(directors));
}
5. Ebenso ist die Konfiguration des Play-Controllers in conf/routes bereits erledigt.
Mit den oben beschriebenen Ergänzungen sollten Sie jetzt nach Regisseuren suchen können; Sie sollten
eine Liste von Regisseuren angezeigt erhalten, in dieser Liste sollten Sie auf einen einzelnen Regisseur
klicken können und anschliessend eine Liste aller Filme dieses Regisseurs angezeigt erhalten.
Letzte Teilaufgabe: Erklären Sie sich selbst in eigenen Worten, wozu welche der oben genannten Elemente
notwendig sind,
sind, damit wir nach Regisseuren suchen können.
können.
5
Herunterladen