SlideShare a Scribd company logo
1 of 35
Grails: a quick tutorial (1) Davide Rossi ,[object Object]
Contents ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Contents (2) ,[object Object],[object Object],[object Object],[object Object],[object Object]
Grails: Groovy on Rails ? ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Creating a new application ,[object Object],> grails create-app JugDemo
Domain classes and GORM ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Datasource 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' }
Datasource 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" } } }
Constraints ,[object Object],[object Object],[object Object],[object Object],[object Object]
Team domain class > grails create-domain-class team  class Team { String name String championship String city Long supporters Integer foundationYear static hasMany = [players: Player] static constraints = { name (unique: true, blank: false, size: 2..30) championship (blank: false, inList: ['Serie A', 'Serie B', 'Serie C1', 'Serie C2']) city (blank: true, size: 2..25) supporters (nullable: true) foundationYear (nullable: true) } }
Player domain class >  grails create-domain-class player class Player { String name String lastName String city Date birth String email static belongsTo = [team: Team] static constraints = { name (blank: false, size: 2..30) lastName (blank: false, size: 2..30) city (blank: true, size: 2..25) birth (nullable:true) email (blank: true, email: true) } }
GORM Associations – One to one Unidirectional -  class Person { BillingAddress address } class BillingAddress { ... } Bidirectional (no update / delete cascading) -  class Person { BillingAddress address } class BillingAddress { Person person }
GORM Associations – One to one Bidirectional (update / delete cascading) -  class Person { BillingAddress address } class BillingAddress { static belongsTo = [person: Person]  }
GORM Associations – One to many Update cascading, no delete -  class Team { static hasMany = [players: Player] } class Player { ...  } Update / delete cascading -  class Team { static hasMany = [players: Player] } class Player { static belongsTo = [team: Team] }
GORM Associations – Many to many ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
GORM notes ,[object Object],[object Object],[object Object],[object Object]
Team controller >  grails generate-controller team Every action is implemented as a closure
Team controller - List def list = { if (!params.max) params.max = 10 [ teamList: Team.list( params ) ] } - params is a map containing the request parameters - list is a GORM method, can take parameters: - max, offset, order, sort, ignoreCase, fetch - No explicit return statement - No explicit view
Team controller - Show def show = { def team = Team.get( params.id ) if (!team) { flash.message = "Team not found with id ${params.id}" redirect(action: list) } else {  return [ team : team ]  } } - get is a GORM method - flash is a new scope introduces by Grails - explicit return statement
Team controller - Save def save = { def team = new Team(params) if(!team.hasErrors() && team.save()) { flash.message = "Team ${team.id} created" redirect(action: show, id: team.id) } else { render(view: 'create', model: [team: team]) } } - save performs validation and return null if errors are found - explicit view declarations (render)
Generate controllers and view >  grails generate-views team >  grails generate-all player
Running the app >  grails run-app
Application bootstrap def init = { servletContext -> if (GrailsUtil.environment == "development") {  def team1 = new Team(name: 'Varese', championship: 'Serie C2', city:  'Varese', supporters: 1000, foundationYear: 1910).save() def team2 = ... def team3 = ... def team4 = ... new Player(name: 'player1', lastName: 'one', city: 'Varese', birth: new Date(),  email: 'player1@team.it', team: team1).save() ... new Player(name: 'player11', lastName: 'eleven', city: 'Palermo', birth: new  Date(), email: 'player11@team.it', team: team4).save() } }
Search types ,[object Object],[object Object],[object Object]
Adding a search form team/list.gsp: <g:form name=”searchForm” action=”search”> Championship: <g:select name=”championship”  from=”${Team.constraints.championship.inList}” /> <input type=”submit” value=”Search” /> </g:form>
Dynamic finders teamController: def search = { def teamList =  Team.findAllByChampionship(params.championship) render(view:'list', model: [teamList: teamList] ) }
Dynamic finders - findBy and findAllBy - def team = Team.findByName(‘Juventus’) - def teamList = Team.findAllByCity(‘Milano’) - Composition of properties, boolean logic and comparators: - and, or - LessThan, LessThanEquals, GreaterThan,  GreaterThanEquals, Like, Ilike, NotEqual, Between,  IsNotNull, IsNull es:  Team.findAllByCityLikeAndSupportersGreaterThan(‘Milano’, 1000, [max: 3, offset: 2, sort: &quot;name&quot;, order: &quot;desc&quot;])
Multiaction search form <g:form name=&quot;searchForm&quot;> <input type=&quot;text&quot; name=&quot;searchQuery&quot; /> <g:actionSubmit value=&quot;Search by Team&quot;  action=&quot;teamSearch&quot; /> <g:actionSubmit value=&quot;Search by City&quot;  action=&quot;citySearch&quot; /> </g:form> - Each button sends the form to a different action
Hql queries def teamSearch = { def playerList = Player.findAll(&quot;from Player as p where  p.team.name = ?&quot;, [&quot;${params.searchQuery}&quot;]) render(view: 'list', model: [playerList: playerList]) } -  You can use HQL queries with named and pagination parameters: es: Player.findAll(&quot;from Player as p where p.team.name  = :teamName order by p.lastName asc&quot;,  [teamName: &quot;Juventus&quot;], [max:10, offset:20])
Hibernate Criteria def citySearch = { def c = Player.createCriteria() def playerList = c.list { ilike(&quot;city&quot;, &quot;%${params.searchQuery}%&quot;) } render(view: 'list', model: [playerList: playerList]) } - Uses a Groovy builder to hide Hibernate's Criteria API complexity
Hibernate Criteria A more complex example: def c = Account.createCriteria() def results = c { like(&quot;holderFirstName&quot;, &quot;Fred%&quot;) and { between(&quot;balance&quot;, 500, 1000) eq(&quot;branch&quot;, &quot;London&quot;) } maxResults(10) order(&quot;holderLastName&quot;, &quot;desc&quot;) }
Pagination problem After the search we see a pagination error: we must  modify the generated action and gsp:
Pagination <div class=&quot;paginateButtons&quot;> <g:paginate total=&quot;${playerCount}&quot; /> </div> def list = { if (!params.max) params.max = 10 def playerList = Player.list( params ) [ playerList:  playerList, playerCount: Player.count()] }
Pagination def teamSearch = { def playerList = Player.findAll(&quot;from Player as p where p.team.name = ?&quot;,  [&quot;${params.searchQuery}&quot;]) render(view: 'list', model: [playerList: playerList,  playerCount: playerList.size()]) } def citySearch = { def c = Player.createCriteria() def playerList = c.list { ilike(&quot;city&quot;, &quot;%${params.searchQuery}%&quot;) } render(view: 'list', model: [playerList: playerList,  playerCount: playerList.size()]) }
Conclusions ,[object Object],[object Object],[object Object]

More Related Content

What's hot

JavaScript Arrays
JavaScript Arrays JavaScript Arrays
JavaScript Arrays Reem Alattas
 
GR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective GroovyGR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective GroovyGR8Conf
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your GroovyAlonso Torres
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門Hiromi Ishii
 
Painless Persistence with Realm
Painless Persistence with RealmPainless Persistence with Realm
Painless Persistence with RealmChristian Melchior
 
The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210Mahmoud Samir Fayed
 
Groovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトークGroovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトークTsuyoshi Yamamoto
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickHermann Hueck
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateKiev ALT.NET
 
Introduction to Gremlin
Introduction to GremlinIntroduction to Gremlin
Introduction to GremlinMax De Marzi
 
Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant)
Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant) Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant)
Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant) BigDataEverywhere
 
Martin Fowler's Refactoring Techniques Quick Reference
Martin Fowler's Refactoring Techniques Quick ReferenceMartin Fowler's Refactoring Techniques Quick Reference
Martin Fowler's Refactoring Techniques Quick ReferenceSeung-Bum Lee
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とかHiromi Ishii
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationJoni
 
Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...
Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...
Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...CloudxLab
 
The Ring programming language version 1.5.2 book - Part 44 of 181
The Ring programming language version 1.5.2 book - Part 44 of 181The Ring programming language version 1.5.2 book - Part 44 of 181
The Ring programming language version 1.5.2 book - Part 44 of 181Mahmoud Samir Fayed
 

What's hot (20)

JavaScript Arrays
JavaScript Arrays JavaScript Arrays
JavaScript Arrays
 
GR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective GroovyGR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective Groovy
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門
 
Painless Persistence with Realm
Painless Persistence with RealmPainless Persistence with Realm
Painless Persistence with Realm
 
The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210
 
Groovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトークGroovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトーク
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with Slick
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
 
Introduction to Gremlin
Introduction to GremlinIntroduction to Gremlin
Introduction to Gremlin
 
Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant)
Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant) Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant)
Big Data Everywhere Chicago: Unleash the Power of HBase Shell (Conversant)
 
Martin Fowler's Refactoring Techniques Quick Reference
Martin Fowler's Refactoring Techniques Quick ReferenceMartin Fowler's Refactoring Techniques Quick Reference
Martin Fowler's Refactoring Techniques Quick Reference
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とか
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
groovy & grails - lecture 3
groovy & grails - lecture 3groovy & grails - lecture 3
groovy & grails - lecture 3
 
Why realm?
Why realm?Why realm?
Why realm?
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET Application
 
Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...
Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...
Apache Spark - Key Value RDD - Transformations | Big Data Hadoop Spark Tutori...
 
The Ring programming language version 1.5.2 book - Part 44 of 181
The Ring programming language version 1.5.2 book - Part 44 of 181The Ring programming language version 1.5.2 book - Part 44 of 181
The Ring programming language version 1.5.2 book - Part 44 of 181
 

Similar to Grails: a quick tutorial (1)

Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail Laurent Dami
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Jonathan Felch
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant TrainingAidIQ
 
Pxb For Yapc2008
Pxb For Yapc2008Pxb For Yapc2008
Pxb For Yapc2008maximgrp
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Curscatalyst
CurscatalystCurscatalyst
CurscatalystKar Juan
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansCarol McDonald
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Michael Schwern
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Shinya Ohyanagi
 
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishGrails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishSven Haiges
 
vfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent testsvfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent testsFrank Kleine
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 

Similar to Grails: a quick tutorial (1) (20)

Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Framework
FrameworkFramework
Framework
 
What's New in ZF 1.10
What's New in ZF 1.10What's New in ZF 1.10
What's New in ZF 1.10
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
 
DataMapper
DataMapperDataMapper
DataMapper
 
Pxb For Yapc2008
Pxb For Yapc2008Pxb For Yapc2008
Pxb For Yapc2008
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Curscatalyst
CurscatalystCurscatalyst
Curscatalyst
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with Netbeans
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
 
B03-GenomeContent-Intermine
B03-GenomeContent-IntermineB03-GenomeContent-Intermine
B03-GenomeContent-Intermine
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishGrails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
 
vfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent testsvfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent tests
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 

Recently uploaded

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 

Recently uploaded (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 

Grails: a quick tutorial (1)

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7. Datasource dataSource { pooled = true driverClassName = &quot;org.hsqldb.jdbcDriver&quot; username = &quot;sa&quot; password = &quot;&quot; } hibernate { cache.use_second_level_cache=true cache.use_query_cache=true cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider' }
  • 8. Datasource environments { development { dataSource { dbCreate = &quot;create-drop&quot; // one of 'create', 'create-drop','update' url = &quot;jdbc:hsqldb:mem:devDB&quot; } } test { dataSource { dbCreate = &quot;update&quot; url = &quot;jdbc:hsqldb:mem:testDb&quot; } } production { dataSource { dbCreate = &quot;update&quot; url = &quot;jdbc:hsqldb:file:prodDb;shutdown=true&quot; } } }
  • 9.
  • 10. Team domain class > grails create-domain-class team class Team { String name String championship String city Long supporters Integer foundationYear static hasMany = [players: Player] static constraints = { name (unique: true, blank: false, size: 2..30) championship (blank: false, inList: ['Serie A', 'Serie B', 'Serie C1', 'Serie C2']) city (blank: true, size: 2..25) supporters (nullable: true) foundationYear (nullable: true) } }
  • 11. Player domain class > grails create-domain-class player class Player { String name String lastName String city Date birth String email static belongsTo = [team: Team] static constraints = { name (blank: false, size: 2..30) lastName (blank: false, size: 2..30) city (blank: true, size: 2..25) birth (nullable:true) email (blank: true, email: true) } }
  • 12. GORM Associations – One to one Unidirectional - class Person { BillingAddress address } class BillingAddress { ... } Bidirectional (no update / delete cascading) - class Person { BillingAddress address } class BillingAddress { Person person }
  • 13. GORM Associations – One to one Bidirectional (update / delete cascading) - class Person { BillingAddress address } class BillingAddress { static belongsTo = [person: Person] }
  • 14. GORM Associations – One to many Update cascading, no delete - class Team { static hasMany = [players: Player] } class Player { ... } Update / delete cascading - class Team { static hasMany = [players: Player] } class Player { static belongsTo = [team: Team] }
  • 15.
  • 16.
  • 17. Team controller > grails generate-controller team Every action is implemented as a closure
  • 18. Team controller - List def list = { if (!params.max) params.max = 10 [ teamList: Team.list( params ) ] } - params is a map containing the request parameters - list is a GORM method, can take parameters: - max, offset, order, sort, ignoreCase, fetch - No explicit return statement - No explicit view
  • 19. Team controller - Show def show = { def team = Team.get( params.id ) if (!team) { flash.message = &quot;Team not found with id ${params.id}&quot; redirect(action: list) } else { return [ team : team ] } } - get is a GORM method - flash is a new scope introduces by Grails - explicit return statement
  • 20. Team controller - Save def save = { def team = new Team(params) if(!team.hasErrors() && team.save()) { flash.message = &quot;Team ${team.id} created&quot; redirect(action: show, id: team.id) } else { render(view: 'create', model: [team: team]) } } - save performs validation and return null if errors are found - explicit view declarations (render)
  • 21. Generate controllers and view > grails generate-views team > grails generate-all player
  • 22. Running the app > grails run-app
  • 23. Application bootstrap def init = { servletContext -> if (GrailsUtil.environment == &quot;development&quot;) { def team1 = new Team(name: 'Varese', championship: 'Serie C2', city: 'Varese', supporters: 1000, foundationYear: 1910).save() def team2 = ... def team3 = ... def team4 = ... new Player(name: 'player1', lastName: 'one', city: 'Varese', birth: new Date(), email: 'player1@team.it', team: team1).save() ... new Player(name: 'player11', lastName: 'eleven', city: 'Palermo', birth: new Date(), email: 'player11@team.it', team: team4).save() } }
  • 24.
  • 25. Adding a search form team/list.gsp: <g:form name=”searchForm” action=”search”> Championship: <g:select name=”championship” from=”${Team.constraints.championship.inList}” /> <input type=”submit” value=”Search” /> </g:form>
  • 26. Dynamic finders teamController: def search = { def teamList = Team.findAllByChampionship(params.championship) render(view:'list', model: [teamList: teamList] ) }
  • 27. Dynamic finders - findBy and findAllBy - def team = Team.findByName(‘Juventus’) - def teamList = Team.findAllByCity(‘Milano’) - Composition of properties, boolean logic and comparators: - and, or - LessThan, LessThanEquals, GreaterThan, GreaterThanEquals, Like, Ilike, NotEqual, Between, IsNotNull, IsNull es: Team.findAllByCityLikeAndSupportersGreaterThan(‘Milano’, 1000, [max: 3, offset: 2, sort: &quot;name&quot;, order: &quot;desc&quot;])
  • 28. Multiaction search form <g:form name=&quot;searchForm&quot;> <input type=&quot;text&quot; name=&quot;searchQuery&quot; /> <g:actionSubmit value=&quot;Search by Team&quot; action=&quot;teamSearch&quot; /> <g:actionSubmit value=&quot;Search by City&quot; action=&quot;citySearch&quot; /> </g:form> - Each button sends the form to a different action
  • 29. Hql queries def teamSearch = { def playerList = Player.findAll(&quot;from Player as p where p.team.name = ?&quot;, [&quot;${params.searchQuery}&quot;]) render(view: 'list', model: [playerList: playerList]) } - You can use HQL queries with named and pagination parameters: es: Player.findAll(&quot;from Player as p where p.team.name = :teamName order by p.lastName asc&quot;, [teamName: &quot;Juventus&quot;], [max:10, offset:20])
  • 30. Hibernate Criteria def citySearch = { def c = Player.createCriteria() def playerList = c.list { ilike(&quot;city&quot;, &quot;%${params.searchQuery}%&quot;) } render(view: 'list', model: [playerList: playerList]) } - Uses a Groovy builder to hide Hibernate's Criteria API complexity
  • 31. Hibernate Criteria A more complex example: def c = Account.createCriteria() def results = c { like(&quot;holderFirstName&quot;, &quot;Fred%&quot;) and { between(&quot;balance&quot;, 500, 1000) eq(&quot;branch&quot;, &quot;London&quot;) } maxResults(10) order(&quot;holderLastName&quot;, &quot;desc&quot;) }
  • 32. Pagination problem After the search we see a pagination error: we must modify the generated action and gsp:
  • 33. Pagination <div class=&quot;paginateButtons&quot;> <g:paginate total=&quot;${playerCount}&quot; /> </div> def list = { if (!params.max) params.max = 10 def playerList = Player.list( params ) [ playerList: playerList, playerCount: Player.count()] }
  • 34. Pagination def teamSearch = { def playerList = Player.findAll(&quot;from Player as p where p.team.name = ?&quot;, [&quot;${params.searchQuery}&quot;]) render(view: 'list', model: [playerList: playerList, playerCount: playerList.size()]) } def citySearch = { def c = Player.createCriteria() def playerList = c.list { ilike(&quot;city&quot;, &quot;%${params.searchQuery}%&quot;) } render(view: 'list', model: [playerList: playerList, playerCount: playerList.size()]) }
  • 35.