Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Advanced GORM - Beyond Relational

2,585 views

Published on

In this talk, Grails project lead Graeme Rocher will demonstrate some less known, advanced features of GORM and explore the possibilities offered going beyond the relational database.

Published in: Software
  • Be the first to comment

Advanced GORM - Beyond Relational

  1. 1. Advanced GORM - Beyond Relational By Graeme Rocher © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  2. 2. Agenda § Understanding GORM Internals § GORM Standalone § Tips and Tricks § Jumping into MongoDB § Unit testing with GORM § Summary / Q & A
  3. 3. GORM • Powerful multi-datastore query layer • Dynamic finders, criteria, and persistence methods • Integrated validation • Automatic mapping of entities to underlying datastore • Easy access to native APIs 3
  4. 4. Understanding what makes GORM tick © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. GORM Internals
  5. 5. Grails Data Mapping Project • https://github.com/grails/grails-data-mapping 5
  6. 6. Built by Travis • https://travis-ci.org/grails/grails-data-mapping 6
  7. 7. Developer Documentation • http://grails.github.com/grails-data-mapping/ 7
  8. 8. Important Subprojects • grails-datastore-core – Core low level API • grails-datastore-gorm – GORM API layer • grails-datastore-gorm-tck – Test Suite 8
  9. 9. Demo: Code Walkthrough © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  10. 10. Contribute to GORM • GORM is huge and sprawling • Covers loads of data stores • Great area to contribute to the community. Some ideas: • Multi Tenancy • Elastic Search • Hadoop / HBase 10
  11. 11. GORM Standalone © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Use GORM outside of Grails
  12. 12. What is GORM Standalone? • Easy initialisation of GORM outside of Grails • And a set of Spring Boot plugins • Required modularisation of codebase • Reduction of external dependencies • Simplification of GORM setup 12
  13. 13. Standalone Entities • Annotated with grails.persistence.Entity 13 @Entity class Person { String name static constraints = { name blank:false } }
  14. 14. GORM for Hibernate Standalone • https://gist.github.com/graemerocher/c25ec929d9bcd1adcbea 14 @Grab("org.grails:grails-­‐datastore-­‐gorm-­‐hibernate4:3.1.2.RELEASE") @Grab("com.h2database:h2:1.3.164") import grails.orm.bootstrap.* init = new HibernateDatastoreSpringInitializer(Person) def dataSource = new DriverManagerDataSource(Driver.name, "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALS E", 'sa', '') init.configureForDataSource(dataSource)
  15. 15. GORM for MongoDB Standalone • https://gist.github.com/graemerocher/9683650 15 @Grab("org.grails:grails-­‐datastore-­‐gorm-­‐mongodb:3.0.2.RELEASE") import grails.mongodb.bootstrap.* init = new MongoDbDataStoreSpringInitializer(Person) init.configure()
  16. 16. Demo: GORM Standalone © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  17. 17. GORM for Hibernate in Spring Boot • Add gorm-hibernate4-spring-boot as a dependency • Then add persistent entities that are annotated with grails.persistence.Entity 17 compile "org.grails:gorm-­‐hibernate4-­‐ spring-­‐boot:1.0.0.RELEASE"
  18. 18. GORM for MongoDB in Spring Boot • Add gorm-mongodb-spring-boot as a dependency • Then add persistent entities that are annotated with grails.persistence.Entity 18 compile "org.grails:gorm-­‐mongodb-­‐spring-­‐ boot:1.1.0.RELEASE"
  19. 19. © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Tips & Tricks Take GORM to the next level
  20. 20. GORM Tips & Tricks • Understanding where queries • Working with DetachedCriteria • Using formula and column readers / writers • Going asynchronous 20
  21. 21. Where Queries • Type-safe, composable query API 21 DetachedCriteria<Person> query = Person.where { lastName == "Simpson" } def results = query.list()
  22. 22. Demo: Where Queries © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  23. 23. Hibernate Subqueries • Perform nested “in” or “notIn” sub queries that span domain classes using where queries: 23 def employees = Employee.where { region.continent in ['APAC', "EMEA"] }.id() def results = Sale.where { employee in employees && total > 50000 }.employee.list()
  24. 24. Hibernate Correlated Subqueries • Declare aliases using “def” for cross query references: 24 def query = Employee.where { def em1 = Employee exists Sale.where { def s1 = Sale def em2 = employee return em2.id == em1.id }.id() } def results = query.list()
  25. 25. Hibernate Column Formula • A column can be a read-only formula 25 Product { Float price Float taxRate Float tax static mapping = { class tax formula: 'PRICE * TAX_RATE' } }
  26. 26. Hibernate Column Readers/Writers • New in 2.4: Implement custom column readers and writers to transform data when written or read from the database. 26 Name { String title static class mapping = { title write:'UPPER(?)', read:'REPEAT(title, 2)' } }
  27. 27. Asynchronous GORM • Database operations are blocking • Can be helpful to isolate these blocking operations on a separately managed thread • Work underway in some NoSQL datastore on fully asynchronous drivers (MongoDB, CouchDB etc.) • No usable asynchronous SQL/JDBC drivers on the horizon (to my knowledge) 27
  28. 28. Async Namespace • Any GORM method can become Async 28 import static grails.async.Promises.* def p1 = Person.async.get(1L) def p2 = Person.async.get(2L) def p3 = Person.async.get(3L) def results = waitAll(p1, p2, p3)
  29. 29. Demo: Async GORM © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  30. 30. Async Tasks • Individual async method calls often too fine grained, use task method to implement Async GORM tasks 30 def promise = Person.async.task { withTransaction { def person = findByFirstName("Homer") person.firstName = "Bart" person.save(flush:true) } } Person updatedPerson = promise.get()
  31. 31. Jumping into MongoDB © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Go schemaless!
  32. 32. GORM for MongoDB • Geospacial querying • GeoJSON models • Full text search • Schemaless domain models • Projections via MongoDB aggregation • Stateless and Stateful modes • Custom user types 32
  33. 33. GORM for MongoDB Internals • MongoEntityPersister implements persistence • MongoQuery implements querying aggregation • MongoSession implements batch inserts, updates and deletes • MongoGormStaticApi adds extra GORM methods • GeoJSONType and subclasses implement GeoJSON custom types • https://github.com/grails/grails-data-mapping/tree/master/ grails-datastore-gorm-mongodb 33
  34. 34. GORM, MongoDB & GeoJSON • Geo Data in MongoDB represented by GeoJSON types – http://geojson.org • Package grails.mongodb.geo contains GeoJSON types – Point, Polygon, LineString, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection 34
  35. 35. Geospacial Querying 35 def point = new Point(2, 1) def p = new Place(point: point) poly1 = Polygon .valueOf([ [0.0, 0.0], [3.0, 0.0], def [3.0, 3.0], [0.0, 3.0], [0.0, 0.0] ]) Place.findByPointGeoWithin(poly1)
  36. 36. MongoDB Text Search • Create text indices and use methods 36 Product.search('"Coffee Cake"') .size() == 1 Product.searchTop("cake").size() == 4 Product.searchTop("cake",3).size() == 3 Product.countHits('coffee') == 5
  37. 37. Schemaless Dynamic Properties • Add dynamic properties with the subscript operator 37 def p = new Plant(name:"Pineapple") p.save() p["color"] = "Yellow" p["hasLeaves"] = true
  38. 38. Demo: GORM for MongoDB © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  39. 39. Other Implementations • Neo4j – http://grails.org/plugin/neo4j • Redis GORM – http://grails.org/plugin/redis-gorm • GORM for REST – http://grails.org/plugin/gorm-rest-client • Cassandra – https://github.com/grails/grails-data-mapping/ 39
  40. 40. Unit Testing GORM © 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Spin up GORM inside a unit test
  41. 41. Hibernate in Unit Tests • Add a dependency on grails-datastore-test-support • Provides HibernateTestMixin that will load Hibernate inside a unit test 41 test "org.grails:grails-­‐datastore-­‐test-­‐ support:1.0-­‐grails-­‐2.4"
  42. 42. Hibernate in Unit Tests 42 import grails.test.mixin.TestMixin import grails.test.mixin.gorm.Domain import grails.test.mixin.hibernate.* import spock.lang.Specification @Domain(Person) @TestMixin(HibernateTestMixin) class PersonSpec extends Specification { … }
  43. 43. Summary • GORM provides a rich and diverse ecosystem • Goes far beyond relational databases • Can be used standalone or within Grails • Great area to contribute to! 43
  44. 44. Q & A
  45. 45. Stay Connected. Web: grails.org StackOverflow: http://stackoverflow.com/tags/grails Twitter: http://twitter.com/grailsframework LinkedIn: http://linkedin.com/groups/Grails-User-Group-39757 Google+: https://plus.google.com/communities/ 109558563916416343008

×