Groovy SQL (GSQL) przesłania (przykrywa) JDBC udostępniając dodatkowy zestaw metod dostępowych do danych w bazie danych. Z pomocą GSQL możemy tworzyć zapytania SQL i korzystać z wbudowanych iteratorów do obsługi ich wyników.
Podłączamy się do bazy danych z pomocą groovy.sql.Sql.newInstance() podając namiary na bazę danych. Alternatywnie, jeśli mamy już obiekty java.sql.Connection lub java.sql.DataSource, możemy użyć je jako parametry wejściowe dla odpowiednich konstruktorów klasy groovy.sql.Sql zamiast oprzeć się na wspomnianej newInstance(). Informacje o aktywnym połączeniu otrzymujemy przez getConnection() lub po prostu przez atrybut connection na obiekcie Sql. Zamykamy "kramik" metodą close().
Po uwadze Krzyśka postanawiam zrezygnować z groovysh na rzecz groovyConsole, aby zrzuty poszczególnych skryptów Groovy były możliwe do czytania.
Do poprawnego uruchomienia skryptów do pracy z wybraną bazą danych potrzebujemy sterownika bazodanowego - w moim przypadku będzie to mysql-connector-java-5.1.7-bin.jar. Podobno dodanie jara do ścieżki klas groovyConsole jest możliwe przez menu Add Jar to ClassPath, ale u mnie nie dawało to oczekiwanych rezultatów i wciąż tylko miałem NCDFE.
Skończyło się na uruchomieniu groovyConsole z parametrem -cp.
groovyConsole -cp "C:\apps\mysql-connector-java\mysql-connector-java-5.1.7-bin.jar"Tym razem wszystko zagrało i mogłem uruchomić swój pierwszy skrypt z wyświetlenie rekordów z bazy
def sql = groovy.sql.Sql.newInstance('jdbc:mysql://localhost:3306/groovymysqldb', 'root', 'passw0rd', 'com.mysql.jdbc.Driver')wyświetla oczekiwane "groovymysqldb".
println sql.connection.catalog
Można również oprogramować dodanie jara do ścieżki klas.
import groovy.sql.*Baza została świeżo założona na potrzeby doświadczeń z GSQL, więc zaczynamy od utworzenia tabeli i kilku przykładowych rekordów za pomocą klasy DataSet. Wywołanie Sql.dataSet() z parametrem wskazującym na tabelę zwraca proxy (typu DataSet) do danych bez ich pobierania. Tworzenie nowych rekordów w bazie jest możliwe przez DataSet.add(), której parametrami wejściowymi są pary kolumna:wartość. Możemy również skorzystać z bardziej tradycyjnych metod jak Sql.execute() oraz Sql.executeInsert() podając na ich wejściu polecenia INSERT.
this.class.classLoader.rootLoader.addURL(new URL("file:C:/apps/mysql-connector-java/mysql-connector-java-5.1.7-bin.jar"))
def sql = Sql.newInstance('jdbc:mysql://localhost:3306/groovymysqldb', 'root', 'passw0rd', 'com.mysql.jdbc.Driver')
import groovy.sql.*Zapytanie typu SELECT uruchamiamy metodą eachRow(), która na wejściu oczekuje zapytania (jako tekst) oraz domknięcia, które jest uruchamiane, dla każdego rekordu.
def sql = Sql.newInstance('jdbc:mysql://localhost:3306/groovymysqldb', 'root', 'passw0rd', 'com.mysql.jdbc.Driver')
println "Korzystam z bazy: ${sql.connection.catalog}"
sql.execute("DROP TABLE pracownicy")
sql.execute("CREATE TABLE pracownicy(imie varchar(25), nazwisko varchar(25))")
def ds = sql.dataSet('pracownicy')
ds.add(imie: 'Jacek', nazwisko: 'Laskowski')
// wraz z tym, co wyżejW wyniku dostajemy:
println "[Imie]\t[Nazwisko]"
sql.eachRow('SELECT * from pracownicy') {
printf "%s\t%s\n", it.imie, it.nazwisko
}
Korzystam z bazy: groovymysqldbGroovyResultSet, który jest przekazywany domknięciu, pozwala na dostęp do kolumn po nazwie lub indeks.
[Imie] [Nazwisko]
Jacek Laskowski
Inna wersja eachRow(), poza samym zapytaniem, przyjmuje dwa domknięcia - pierwszy do obsługi metadanych bazy i jest wykonywana raz, a drugi, jak poprzednio, do obsługi rekordów. Przykładu nie będzie - należy zajrzeć do książki, bądź do dokumentacji Groovy (można zacząć od lektury Database features)
Możemy również skrócić obsługę wierszy do poziomu obsługi listy z rows(). Odczyt danych jest również możliwy przez each() (podobne do Sql.eachRow()). Dodając do tego możliwość zawężania wyników (filtrowania ich) dzięki findAll() otrzymujemy niezwykle efektywne narzędzie do wyciągania danych z bazy.
Mamy również do dyspozycji Sql.call() do uruchamiania procedur składowanych oraz Sql.withStatement(), które akceptuje domknięcie uruchamiane przed wykonaniem zapytania - interesująca opcja, jeśli chcemy wpływać na ostateczną postać zapytań zanim zostaną wysłane do bazy danych.
W połączeniu z mechanizmem budowniczych w Groovy (ang. Groovy builders) tworzenie XMLi z danych z danych w bazie to "kaszka z mleczkiem". Smacznego! :)
// wraz z tym, co wyżejW wyniku mamy:
bldr = new groovy.xml.MarkupBuilder()
bldr.pracownicy {
sql.eachRow("SELECT * from pracownicy") {
pracownik(imie: it.imie, nazwisko: it.nazwisko)
}
}
Korzystam z bazy: groovymysqldbW sekcji 10.6 "Accessing Microsoft Excel" autor przedstawia sposób na tworzenie plików XLS na podstawie danych z bazy (przez sterownik JDBC-ODBC). Nic odkrywczego z punktu widzenia samego użycia JDBC-ODBC, ale prostota Groovy bije po oczach. Za Krzyśkiem w jego komentarzu do poprzedniego wpisu o Groovy "nie wszystko to zasługa dynamizmu!". Parafrazując szefo pingwinów: "I to jest coś, z czym mogę się pogodzić", bo wychodzę z założenia, że wiele można zrobić, tylko trzeba mieć na to chęć i czas. Skoro robię to w Groovy i uderza mnie jego prostota, to chcę, czy nie, kładę to na barki jego cech języka dynamicznego. Czasami sobie myślę, że warto by wprowadzić swego rodzaju ożywienie w naszych dyskusjach na blogach i odpowiadać na wpisy za pomocą...(kontr)aplikacji. Gdybym tak mógł poczytać wpisy, które pokazywałyby cechy Scali, F# czy Ocaml jako reakcję na te o Groovy byłoby bajecznie. Wchodzisz Krzysiek w temat? Rękawica leży i czeka na podniesienie :)
<pracownicy>
<pracownik imie='Jacek' nazwisko='Laskowski' />
</pracownicy>
Pomyślim (chociaż nie jestem Krzyśkiem). Pytanie retoryczne czy da się nadążyć za Twoją produkcją i pytanie do Ciebie Jacku czy oczekujesz języka polskiego.
OdpowiedzUsuńHaha, wtedy trzeba by założyć bloga, którego jedynym zajęciem jest odpisywanie na Twoje posty ;)
OdpowiedzUsuńPomysł bardzo fajny, z tym, że ja doceniam Groovy i żeby pokonać jego "minimalizm" to bym musiał chyba w Rebol-u pisać ;)
Może jakiś zapalony Scalista się skusi. Hm, jak tylko zamknę kwestię moich uczelni (zachciało mi się dwóch dyplomów i teraz mam...) to coś dorzucę od siebie.
Pozdrawiam,
Krzysztof Kowalczyk
@pedro, oczekuję jakiegokolwiek języka, a skoro już piszesz w EN niech i tak będzie. Jak się rozniesie, że tak można będzie można pomyśleć o rozszerzeniu działalności na PL.
OdpowiedzUsuń@Krzysiek, właśnie! Najwyższa pora ustatkować się trochę z tym pisaniem i skupić się na czymś bardziej przemawiającym do wyobraźni czytelników. Wciąż chodzi mi po głowie pomysł krótkich filmików - cojak (bez 'i' między nimi :)) i podcasty. Na razie chyba przyzwyczaiłem się do tradycyjnej formy blogowania :)