Grails z MySQL
Z Jacek Laskowski - Wiki Projektanta Java EE
Domyślna konfiguracja Grails obejmuje uruchomienie aplikacji z wbudowaną bazą danych HSQL. Takie podejście pozwala na natychmiastowe budowanie aplikacji webowych bez konieczności zestawiania środowiska uruchomieniowego z bazą danych. Po prostu ją mamy. W tym artykule przedstawię, co jest potrzebne do uruchomienia aplikacji grailsowej z MySQL.
Rozpoczynamy od pobrania MySQL z jego strony domowej mysql.org wraz ze sterownikiem JDBC - Connector/J. Instalacja sprowadza się do wykonania serii kroków z pomocą asystenta instalacji (baza danych) bądź rozpakowania do wybranego katalogu (baza danych i sterownik JDBC).
W przypadku systemu MS Windows uruchomienie/zatrzymanie MySQL to uruchomienie/zatrzymanie usługi MySQL poleceniami net stop MySQL oraz net start MySQL.
$ net start MySQL The MySQL service is starting.. The MySQL service was started successfully. $ net stop MySQL The MySQL service is stopping. The MySQL service was stopped successfully.
Stwórzmy przykładową aplikację, która początkowo korzysta z HSQL, a w kolejnym kroku zdefiniujemy konfigurację uruchomieniową z MySQL.
Zaczynamy od stworzenia struktury katalogowej projektu poleceniem grails create-app grailsmysql.
$ grails create-app grailsmysql
Welcome to Grails 1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:/apps/grails
Base Directory: C:\projs\sandbox
Running script c:\apps\grails\scripts\CreateApp_.groovy
Environment set to development
[mkdir] Created dir: C:\projs\sandbox\grailsmysql\src
...
Executing hibernate-1.1 plugin post-install script ...
Plugin hibernate-1.1 installed
Created Grails Application at C:\projs\sandbox/grailsmysql
W zasadzie uruchomienie grails create-app jest stworzeniem zrębu aplikacji, gdyż już w tym momencie możliwe jest jej uruchomienie (poleceniem grails run-app). Nie miejmy jednak złudzeń, że owa aplikacja sprowadzi się do pojedynczej strony powitalnej, która wyświetla listę dostępnych kontrolerów, a skoro nie mamy jeszcze żadnego, pojawi się jedynie statyczny tekst.
Przechodzimy do katalogu projektu grailsmysql.
$ cd grailsmysql/
Kolejnym krokiem jest utworzenie klasy dziedzinowej pl.jaceklaskowski.grails.Ksiazka poleceniem grails create-domain-class pl.jaceklaskowski.grails.Ksiazka.
$ grails create-domain-class pl.jaceklaskowski.grails.Ksiazka
Welcome to Grails 1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:/apps/grails
Base Directory: C:\projs\sandbox\grailsmysql
Running script c:\apps\grails\scripts\CreateDomainClass.groovy
Environment set to development
[mkdir] Created dir: C:\projs\sandbox\grailsmysql\grails-app\domain\pl\jaceklaskowski\grails
Created DomainClass for Ksiazka
[mkdir] Created dir: C:\projs\sandbox\grailsmysql\test\unit\pl\jaceklaskowski\grails
Created Tests for Ksiazka
Dla stworzonej klasy dziedzinowej Ksiazka tworzymy odpowiedni kontroler poleceniem grails create-controller pl.jaceklaskowski.grails.Ksiazka.
$ grails create-controller pl.jaceklaskowski.grails.Ksiazka
Welcome to Grails 1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:/apps/grails
Base Directory: C:\projs\sandbox\grailsmysql
Running script c:\apps\grails\scripts\CreateController.groovy
Environment set to development
[mkdir] Created dir: C:\projs\sandbox\grailsmysql\grails-app\controllers\pl\jaceklaskowski\grails
Created Controller for Ksiazka
[mkdir] Created dir: C:\projs\sandbox\grailsmysql\grails-app\views\ksiazka
Created Tests for Ksiazka
Modyfikujemy klasę kontrolera KsiazkaController (plik grails-app/controllers/pl/jaceklaskowski/grails/KsiazkaController.groovy) tak, aby zawierała poniższą treść:
package pl.jaceklaskowski.grails
class KsiazkaController {
def scaffold = Ksiazka
}
Istotnym elementem kontrolera jest wykorzystanie dynamicznego rusztowania (ang. dynamic scaffolding), gdzie widoki odpowiadające akcjom CRUD (ang. Create-Read-Update-Delete) są tworzone w pamięci, dynamicznie. Wystarczy zdefiniować statyczną zmienną scaffold z wartością, która wskazuje na obsługiwaną klasę dziedzinową (wartość to nazwa klasy, jednakże w Groovy Ksiazka == Ksiazka.class i dodawanie .class nie jest konieczne).
Zmieniamy treść klasy dziedzinowej Ksiazka (plik grails-app/domain/pl/jaceklaskowski/grails/Ksiazka.groovy) na następującą:
package pl.jaceklaskowski.grails
class Ksiazka {
String tytul
String autor
}
W tym momencie możemy już uruchomić aplikację poleceniem grails run-app.
$ grails run-app Welcome to Grails 1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:/apps/grails Base Directory: C:\projs\sandbox\grailsmysql Running script c:\apps\grails\scripts\RunApp.groovy Environment set to development ... Running Grails application.. Server running. Browse to http://localhost:8080/grailsmysql
Po jej uruchomieniu, wystarczy skierować przeglądarkę na adres http://localhost:8080/grailsmysql i cieszyć się "pięknem" naszej aplikacji grailsowej.
Wykonanie kilku czynności w aplikacji powinno upewnić nas, że domyślna konfiguracja bazodanowa z HSQL działa poprawnie. Pora włączyć konfigurację MySQL.
Jak mogliśmy zauważyć podczas uruchamiania poleceń grails, jednym z komunikatów była informacja z jakiego środowiska uruchomieniowego korzystamy, np.:
Environment set to development
W tym przykładzie, konfiguracja środowiska to środowisko rozwojowe development. W Grails istnieją 3 predefiniowane konfiguracje środowiska - development, test oraz production. Wskazanie, które powinno być bieżące to uruchomienie polecenia grails z parametrem JVM grails.env lub po prostu z podaniem nazwy skróconej konfiguracji jako drugi parametr grails, np.
$ grails test run-app ... Environment set to test
Wykorzystajmy tę wiedzę do zdefiniowania własnej konfiguracji mysql z bazą MySQL w pliku grails-app/conf/DataSource.groovy. Plik DataSource.groovy jest skryptem Groovy, który odpowiada za konfigurację bazodanową i tam właśnie znajdziemy konfigurację domyślną z HSQL.
Plik grails-app/conf/DataSource.groovy powinien zawierać następującą treść:
dataSource {
pooled = true
driverClassName = "org.hsqldb.jdbcDriver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop','update'
url = "jdbc:hsqldb:mem:devDB"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:mem:testDb"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:file:prodDb;shutdown=true"
}
}
mysql {
dataSource {
dbCreate = "create-drop"
url = "jdbc:mysql://localhost/grailsmysqldb"
driverClassName = "com.mysql.jdbc.Driver"
dialect ="org.hibernate.dialect.MySQLDialect"
username = "root"
password = "passw0rd"
}
}
}
Na uwagę zasługuje ostatnia "sekcja" mysql, gdzie definiujemy źródło danych wskazujące na MySQL (w zasadzie to mysql oraz dataSource to wywołania metod akceptujących pojedynczy parametr, który jest de facto domknięciem).
Dostęp do bazy danych w Javie wymaga właściwego sterownika JDBC. W przypadku MySQL będzie to Connector/J jako plik mysql-connector-java-5.1.7-bin.jar, który umieszczamy w katalogu lib projektu. Konieczne jest ponowne uruchomienie aplikacji.
Ostatnim krokiem jest stworzenie bazy danych w MySQL. W naszej konfiguracji mysql w DataSource.groovy założyliśmy nazwę bazy grailsmysqldb. Stworzenie bazy to wykonanie polecenia create database grailsmysqldb.
mysql> create database grailsmysqldb;
Po tych zmianach uruchamiamy aplikację ponownie poleceniem grails -Dgrails.env=mysql run-app.
$ grails -Dgrails.env=mysql run-app Welcome to Grails 1.1 - http://grails.org/ ... Environment set to mysql ... Server running. Browse to http://localhost:8080/grailsmysql
Uruchomienie aplikacji http://localhost:8080/grailsmysql i stworzenie książki
to gwarancja, że aplikacja korzysta z bazy MySQL poprawnie.
Na zakończenie sprawdźmy struktury bazodanowe w MySQL.
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.1.32-community MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> use grailsmysqldb Database changed mysql> show tables; +-------------------------+ | Tables_in_grailsmysqldb | +-------------------------+ | ksiazka | +-------------------------+ 1 row in set (0.00 sec) mysql> describe ksiazka; +---------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | autor | varchar(255) | NO | | NULL | | | tytul | varchar(255) | NO | | NULL | | +---------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) mysql> select * from ksiazka; +----+---------+-----------------+----------------+ | id | version | autor | tytul | +----+---------+-----------------+----------------+ | 1 | 0 | Jacek Laskowski | Grails z MySQL | +----+---------+-----------------+----------------+ 1 row in set (0.00 sec) mysql> quit
Zatem działa jak należy. Gratulacje!


