Natywne zapytania SQL w Groovy i Grails

Grails jeśli chodzi o zabawy z bazą danych potrafi być bardzo wdzięczny. Niestety czasami potrzebujemy odpytać bazę w sposób, do którego magii Grails po prostu nie da się użyć. Tutaj z pomocą przychodzi sam Groovy.

Załóżmy, że potrzebujemy zapytania sumującego szereg wartości z tabeli. Posłużę się znów przykładem tabeli z wpisami na blogu. Przyjmijmy, że w wierszach trzymamy informacje o odsłonach danego wpisu, ale z podziałem na np. dni. Czyli mamy dzisiejsze odsłony, odsłony z wczoraj i odsłony od początku istnienia danego wpisu. Użycie Grailsów w tym przypadku nie bardzo się powiedzie zatem kod napiszemy w Groovym, korzystając z dobrodziejstw klasy groovy.sql.Sql.


 def dataSource

 String sqlAllCommand = "SELECT SUM(show_count_all) AS sca, SUM(show_count_yesterday) AS scy, SUM(show_count_today) AS sct FROM posts";
 groovy.sql.Sql sql = new groovy.sql.Sql( dataSource )

 sql.eachRow( sqlAllCommand, { row ->
			println row.sca + " " + row.scy + " " + row.sct
		} )

 sql.close()

Jak widać rzecz jest dość prosta. Jedyną rzeczą o której należy pamiętać jest skorzystanie z dependency injection dla otrzymania obiektu dataSource. Problemem niestety jest to, iż bezpośrednie posługiwanie się beanem dataSource może w perspektywie powodować wyczerpywanie się puli wątków na serwerze lub komunikatem w stylu dataSource is closed (pomimo teoretycznego zamykania połączenia odpowiednią metodą). Poszukując w internecie rozwiązania natknąłem się na rozwiązanie bazujące na Hibernate. Oto ono:

def sessionFactory

String sqlAllCommand = "SELECT SUM(show_count_all) AS sca, SUM(show_count_yesterday) AS scy, SUM(show_count_today) AS sct FROM posts";
groovy.sql.Sql sql = new groovy.sql.Sql( sessionFactory.currentSession.connection() )

 sql.eachRow( sqlAllCommand, { row ->
		println row.sca + " " + row.scy + " " + row.sct
		} )

W tym przypadku pozwalamy by to Hibernate grzecznie użyczył nam obiektu sesji, a po zakończeniu pracy bez jakiegokolwiek udziału z naszej strony zajmuje się połączeniem. Błędy dotyczące ilości połączeń znikają.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s