Grails: Tutorial 3 – Weitere Tipps
In diesem Tutorial findet man weiterführende Hinweise zu Grails, die nicht in Grails-Tutorial: 1 – Anwendung inkl. Bild-Upload und Grails-Tutorial: 2 – Erweiterung um Suchfunktion enthalten sind.
Ich habe zu diesem Zweck ein neues, sehr übersichtliches Projekt angelegt. Es handelt sich um eine Liste von Obstbäumen mit den Feldern „Name“, „Art“, „Typ“, „Kaufdatum“ und „Bemerkung“. Da in diesem Tutorial das Datenmodell zwischendurch öfter geändert wird, steht
erzeugt. Das Basisverzeichnis ist
Das Listenansicht sieht so aus:
„Name“ und „Art“ sind Pflichtfelder, die anderen nicht, da für diese Felder in der Domain
In dieser Datei kann man auch die Texte anpassen, die in der Weboberfläche (beispielsweise in den Dialogen) angezeigt werden. An einigen Stellen wird automatisch der Name der Domain verwendet (in diesem Fall „Baum“), z. B. in der Listenansicht in der Überschrift „Baum Liste“. Diesen Text kann man ebenfalls hier ändern. Außerdem wird der Name des Feldes „gekauft“ auf „Kaufdatum“ geändert:
Nachdem noch einige Bäume angelegt wurden, sieht die Liste so aus:
Bei mehr als zehn Einträgen wird eine Seitennummerierung angelegt. Die Anzahl der Einträge pro Seite kann man so ändern:
Jetzt ist die Liste länger und die Seitennummerierung erscheint erst wieder, wenn mehr als 15 Einträge in der Liste vorhanden sind.
Jetzt kommen noch ein paar Experimente mit der Domain (Grails ist gestoppt).
Bisher ist das Feld „Name“
Grails wird wieder gestartet, die Datenbanktabelle wird automatisch angepaßt. Die Liste sieht jetzt so aus:
Jetzt gibt es ein Problem: die Datensätze, in denen das Feld „Name“ leer ist, können nicht angezeigt oder verändert werden, da ein Link auf sie fehlt. Im Grails-Tutorial: 1 – Anwendung inkl. Bild-Upload haben wir gesehen, daß das Ausschließen eines Feldes aus der Listenansicht das Feld „Id“ sichtbar macht. Das probieren wir aus und schließen das Feld „Bemerkung“ aus:
Jetzt wird in der Liste das Feld „Id“ angezeigt, welches der Primärschlüssel der Tabelle „Baum“ ist:
Da das Feld „Bemerkung“ in der Listenansicht natürlich angezeigt werden soll, wird ein zusätzliches Dummy-Feld im Datenmodell definiert und dann in den verschiedenen Views (i
Jetzt hat man auch die Möglichkeit, Datensätze mit leerem Feld „Name“ aufzurufen:
Datenbanktabelle löschen:
Controller und Views neu generieren
macOS Catalina
Grails Version: 4.0.8
JVM Version: 11.0.10
MySQL Community Server 8.0.23
Ich habe zu diesem Zweck ein neues, sehr übersichtliches Projekt angelegt. Es handelt sich um eine Liste von Obstbäumen mit den Feldern „Name“, „Art“, „Typ“, „Kaufdatum“ und „Bemerkung“. Da in diesem Tutorial das Datenmodell zwischendurch öfter geändert wird, steht
dbCreate
in der Datei grails-app/conf/application.yml
auf update
. Das funktioniert meistens, um die Änderungen auch der Datenbank bekannt zu machen. Falls Grails trotzdem abstürzt, findet man am Ende dieses Beitrages zwei Möglichkeiten, das Problem zu beheben.Beispielanwendung erstellen
Die Anwendung wird mit% grails create-app Garten
% mv Garten Garten-DB
% cd Garten-DB
Garten-DB % grails create-domain-class Baum
erzeugt. Das Basisverzeichnis ist
Garten-DB
, die Datenbank heißt garten
.Datenmodell
Die Domain sieht so aus:Garten-DB % vi grails-app/domain/garten/Baum.groovy
package garten
class Baum {
String name
String art
String typ
Date gekauft
String bemerkung
static constraints = {
name (unique:true)
art inList: ['Süßkirsche','Sauerkirsche','Apfel','Birne','Zwetschge','Mirabelle','Quitte','Blaubeere','Himbeere','Brombeere','Heidelbeere']
typ inList: ['Halbstamm','Buschbaum','Säule','Strauch']
typ (nullable:true)
gekauft (nullable:true)
bemerkung (nullable:true)
}
}
Das Listenansicht sieht so aus:
„Name“ und „Art“ sind Pflichtfelder, die anderen nicht, da für diese Felder in der Domain
nullable:true
hinterlegt ist. Für die Felder „Art“ und „Typ“ ist eine Liste mit vorgegebenen Werten definiert, die man beim Anlegen des Baumes in einem Dropdown-Menu angezeigt bekommt:Datumsformat und individuelle Texte
Das Datum enthält auch die Uhrzeit, diese löscht man hier:Garten-DB % vi grails-app/i18n/messages_de.properties
löschen:
default.date.format=dd.MM.yyyy HH:mm:ss z
In dieser Datei kann man auch die Texte anpassen, die in der Weboberfläche (beispielsweise in den Dialogen) angezeigt werden. An einigen Stellen wird automatisch der Name der Domain verwendet (in diesem Fall „Baum“), z. B. in der Listenansicht in der Überschrift „Baum Liste“. Diesen Text kann man ebenfalls hier ändern. Außerdem wird der Name des Feldes „gekauft“ auf „Kaufdatum“ geändert:
Garten-DB % vi grails-app/i18n/messages_de.properties
ergänzen:
typeMismatch.java.math.BigInteger=Die Eigenschaft {0} muss eine gültige Zahl sein
baum.label=Obstbaum
baum.gekauft.label=Kaufdatum
Nachdem noch einige Bäume angelegt wurden, sieht die Liste so aus:
Bei mehr als zehn Einträgen wird eine Seitennummerierung angelegt. Die Anzahl der Einträge pro Seite kann man so ändern:
Garten-DB % vi grails-app/controllers/garten/BaumController.groovy
ändern:
def index(Integer max) {
params.max = Math.min(max ?: 15, 100)
respond baumService.list(params), model:[baumCount: baumService.count()]
}
Jetzt ist die Liste länger und die Seitennummerierung erscheint erst wieder, wenn mehr als 15 Einträge in der Liste vorhanden sind.
Datensätze ohne Link?
Jetzt kommen noch ein paar Experimente mit der Domain (Grails ist gestoppt).
Bisher ist das Feld „Name“
unique
, d.h. ein Wert darf nur einmal vorkommen und das Feld darf nicht leer sein. Das wird nun so verändert, daß diese Einschränkungen nicht mehr gelten:Garten-DB % vi grails-app/domain/garten/Baum.groovy
ändern:
static constraints = {
name (nullable:true)
Grails wird wieder gestartet, die Datenbanktabelle wird automatisch angepaßt. Die Liste sieht jetzt so aus:
Jetzt gibt es ein Problem: die Datensätze, in denen das Feld „Name“ leer ist, können nicht angezeigt oder verändert werden, da ein Link auf sie fehlt. Im Grails-Tutorial: 1 – Anwendung inkl. Bild-Upload haben wir gesehen, daß das Ausschließen eines Feldes aus der Listenansicht das Feld „Id“ sichtbar macht. Das probieren wir aus und schließen das Feld „Bemerkung“ aus:
Garten-DB % vi grails-app/views/baum/index.gsp
ergänzen:
</g:if>
<f:table collection="${baumList}" except="bemerkung"/>
<div class="pagination">
Jetzt wird in der Liste das Feld „Id“ angezeigt, welches der Primärschlüssel der Tabelle „Baum“ ist:
Da das Feld „Bemerkung“ in der Listenansicht natürlich angezeigt werden soll, wird ein zusätzliches Dummy-Feld im Datenmodell definiert und dann in den verschiedenen Views (i
ndex.gsp, edit.gsp, show.gsp, create.gsp
) wieder ausgeschlossen:Garten-DB % vi grails-app/domain/garten/Baum.groovy
ergänzen:
</g:if>
String bemerkung
String dummy
static constraints = {
…
bemerkung (nullable:true)
dummy (nullable:true)
}
Garten-DB % vi grails-app/views/baum/index.gsp
ergänzen:
</g:if>
<f:table collection="${baumList}" except="dummy"/>
<div class="pagination">
Jetzt hat man auch die Möglichkeit, Datensätze mit leerem Feld „Name“ aufzurufen:
Grails stürzt ab?
Wenn Grails nach Änderungen am Datenmodell abstürzt, kann man folgendes tun:Datenbanktabelle löschen:
Garten-DB % mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 913
Server version: 8.0.23 MySQL Community Server - GPL
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use garten
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> drop table baum;
Query OK, 0 rows affected (0.00 sec)
mysql> quit
Controller und Views neu generieren
Garten-DB % grails generate-all Baum -force
macOS Catalina
Grails Version: 4.0.8
JVM Version: 11.0.10
MySQL Community Server 8.0.23