Spring Data NHJUG April 2012

  • 1,752 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,752
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
33
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Spring Data Thomas Risberg VMware trisberg@vmware.comTuesday, April 17, 12 1
  • 2. •expert in NO SQL • committer on Spring Framework • currently works for VMware’s Cloud • former Oracle DBA Foundry team on framework integration • former Java J2EE developer • member of Spring Data team email: trisberg@vmware.com twitter: @trisbergTuesday, April 17, 12 2
  • 3. Tuesday, April 17, 12 3
  • 4. New demands on data access ... • massive amounts of data • social networking features • structured and • inexpensive horizontal scaling unstructured data • deploying apps in the cloud • real-time analysis • ... image courtesy of BitcurrentTuesday, April 17, 12 4
  • 5. New types of data stores ... Column/ • Redis • Cassandra • Riak • HBase • MongoDB • CouchDB • Neo4j HadoopTuesday, April 17, 12 5
  • 6. Spring Framework built-in data access support • Transaction abstractions, Data access exceptions • JDBC - JdbcTemplate • ORM - Hibernate, JPA support • OXM - Object to XML mapping • Cache support (Spring 3.1)Tuesday, April 17, 12 6
  • 7. Spring Data • Bring classic Spring benefits to all databases ✓ Productivity ✓ Programming model consistency • Conventions based generic repository support • Mapping between Java domain objects and data store • Support for a wide range of new databasesTuesday, April 17, 12 7
  • 8. Spring Data sub-projects • JPA Repository • JDBC Extensions • Redis (Key Value) • MongoDB (Document) • Neo4j (Graph) • Gemfire (Data Grid) • Apache Hadoop (Big Data) • Riak (Key Value - in development) • Cassandra (Column Store - planned)Tuesday, April 17, 12 8
  • 9. Spring Data Building Blocks • Low level data access APIs ✓ MongoTemplate, RedisTemplate ... • Object Mapping (Java to Datastore) • Generic Repository support • Cross Store Persistence Programming modelTuesday, April 17, 12 9
  • 10. Finding Spring Data • GitHub: https://github.com/SpringSource • Web page: http://www.springsource.org/spring-data • Forum: http://forum.springsource.org/forumdisplay.php?f=80Tuesday, April 17, 12 10
  • 11. Three databases for today’s talk • Relational database • Document database • Graph databaseTuesday, April 17, 12 11
  • 12. Three persistence strategies for today’s talk • Conventions based persistence -- Repositories • Lower-level Template approach • Cross-store persistence using JPA and a non-relational databaseTuesday, April 17, 12 12
  • 13. Repository http://www.sxc.hu/photo/1020163Tuesday, April 17, 12 13
  • 14. Repository Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. http://martinfowler.com/eaaCatalog/repository.html http://msdn.microsoft.com/en-us/library/ff649690.aspxTuesday, April 17, 12 14
  • 15. Spring Data Repository • Generic repository implementation • Basic CRUD (create, read, update and delete) methods • Generating code for dynamic find methods defined in repository interface like findByName, findByAgeBetween etc. • Pagination and sorting support • Currently JPA, Mongo and Neo4j implementationsTuesday, April 17, 12 15
  • 16. Repository<T, ID extends Serializable> CrudRepository<T, ID extends Serializable> PagingAndSortingRepository<T, ID extends Serializable>Tuesday, April 17, 12 16
  • 17. Query MethodsTuesday, April 17, 12 17
  • 18. <persistence> <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="test"> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/> </properties> </persistence-unit> </persistence>Tuesday, April 17, 12 18
  • 19. <configuration> <jpa:repositories base-package="org.springframework.data.demo.repository" /> <tx:annotation-driven transaction-manager="transactionManager"/> <context:component-scan base-package="org.springframework.data.demo"> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="persistenceUnitName" value="test"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="true" /> </bean> </property> </bean>Tuesday, April 17, 12 19
  • 20. r Fo lt ui B <beans profile="default"> <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost/test"/> <property name="username" value="root"/> <property name="password" value=""/> <property name="testOnBorrow" value="true"/> </bean> </beans> <beans profile="cloud"> <cloud:data-source id="dataSource"/> </beans>Tuesday, April 17, 12 20
  • 21. App using JPA Repository CODE https://github.com/trisberg/jpa-bookshelf-repositoryTuesday, April 17, 12 21
  • 22. { "title" : "Spring Data REST in Action", "price" : 22.55, "_links" : [ { "rel" : "author", "href" : "http://localhost:8080/data/author" }, { "rel" : "self", "href" : "http://localhost:8080/data/author/2" } ], "categories" : [ "Spring", "Java" ], "published" : "2012-04-24" } { "_links" : [ { "rel" : "Book", { "href" : "http://localhost:8080/data/author/2/books/1234567890" "name" : "Jon Brisbin", }] "_links" : [ { } "rel" : "books", "href" : "http://localhost:8080/data/author/2/books" }, { "rel" : "self", "href" : "http://localhost:8080/data/author/2" }] } https://github.com/SpringSource/spring-data-restTuesday, April 17, 12 22
  • 23. Tuesday, April 17, 12 23
  • 24. Application Document Oriented High { author: “steve”, date: new Date(), Performance text: “About MongoDB...”, tags: [“tech”, “database”]} Horizontally ScalableTuesday, April 17, 12 24
  • 25. Documents > p = {author: “roger”, date: new Date(), text: “about mongoDB...”, tags: [“tech”, “databases”]} > db.posts.save(p)Tuesday, April 17, 12 25
  • 26. Querying > db.posts.find() > { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), author : "roger", date : "Sat Jul 24 2010 19:47:11", text : "About MongoDB...", tags : [ "tech", "databases" ] }Tuesday, April 17, 12 26
  • 27. Secondary Indexes // 1 means ascending, -1 means descending > db.posts.ensureIndex({author: 1}) > db.posts.find({author: roger}) > { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), author : "roger", ... }Tuesday, April 17, 12 27
  • 28. Conditional Query Operators $all, $exists, $mod, $ne, $in, $nin, $nor, $or, $size, $type, $lt, $lte, $gt, $gte // find posts with any tags > db.posts.find( {tags: {$exists: true }} ) // find posts matching a regular expression > db.posts.find( {author: /^rog*/i } ) // count posts by author > db.posts.find( {author: ‘roger’} ).count()Tuesday, April 17, 12 28
  • 29. Atomic Updates $set, $unset, $inc, $push, $pushAll, $pull, $pullAll, $bit > comment = { author: “fred”, date: new Date(), text: “Best Movie Ever”} > db.posts.update( { _id: “...” }, $push: {comments: comment} );Tuesday, April 17, 12 29
  • 30. Nested Documents { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), author : "roger", date : "Sat Apr 24 2011 19:47:11", text : "About MongoDB...", tags : [ "tech", "databases" ], comments : [ { author : "Fred", date : "Sat Apr 25 2010 20:51:03 GMT-0700", text : "Best Post Ever!" } ] }Tuesday, April 17, 12 30
  • 31. Advanced indexing // Index nested documents > db.posts.ensureIndex( “comments.author”: 1) > db.posts.find({‘comments.author’:’Fred’}) // Index on tags (multi-key index) > db.posts.ensureIndex( tags: 1) > db.posts.find( { tags: ‘tech’ } ) // geospatial index > db.posts.ensureIndex( “author.location”: “2d” ) > db.posts.find( “author.location”: { $near : [22,42] } )Tuesday, April 17, 12 31
  • 32. Rich Documents { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), line_items : [ { sku: ‘tt-123’, name: ‘Coltrane: Impressions’ }, { sku: ‘tt-457’, name: ‘Davis: Kind of Blue’ } ], address : { name: ‘Banker’, street: ‘111 Main’, zip: 10010 }, payment: { cc: 4567, exp: Date(2011, 7, 7) }, subtotal: 2355 }Tuesday, April 17, 12 32
  • 33. Getting started with $ wget http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-2.0.4.tgz $ tar xvzf mongodb-osx-x86_64-2.0.4.tgz $ cd mongodb-osx-x86_64-2.0.4 $ ./bin/mongod --dbpath /Users/trisberg/Data/mongodb/ Sun Apr 15 11:33:11 [initandlisten] MongoDB starting : pid=34692 port=27017 dbpath=/Users/trisberg/Data/ mongodb/ 64-bit host=Montserrat.local Sun Apr 15 11:33:11 [initandlisten] db version v2.0.4, pdfile version 4.5 Sun Apr 15 11:33:11 [initandlisten] git version: 329f3c47fe8136c03392c8f0e548506cb21f8ebf Sun Apr 15 11:33:11 [initandlisten] build info: Darwin erh2.10gen.cc 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386 BOOST_LIB_VERSION=1_40 Sun Apr 15 11:33:11 [initandlisten] options: { dbpath: "/Users/trisberg/Data/mongodb/" } Sun Apr 15 11:33:11 [initandlisten] journal dir=/Users/trisberg/Data/mongodb/journal Sun Apr 15 11:33:11 [initandlisten] recover : no journal files present, no recovery needed Sun Apr 15 11:33:12 [websvr] admin web console waiting for connections on port 28017 Sun Apr 15 11:33:12 [initandlisten] waiting for connections on port 27017Tuesday, April 17, 12 33
  • 34. & $ vmc create-service mongodb mongo-books $ vmc tunnel mongo-books mongo Password: ***** Binding Service [mongo-books]: OK Stopping Application: OK Staging Application: OK Starting Application: OK Getting tunnel connection info: OK Service connection info: username : 97da4cc2-8919-42f9-8bdb-11f0e565c2b6 password : 61b04646-4f9f-4804-8360-20662c2a2c95 name : db Starting tunnel to mongo-books on port 10000. Launching mongo --host localhost --port 10000 -u 97da4cc2-8919-42f9-8bdb-11f0e565c2b6 -p 61b04646-4f9f-4804-8360-20662c2a2c95 db MongoDB shell version: 2.0.1 connecting to: localhost:10000/db > show collections author book system.indexes system.users > db.author.find() { "_id" : ObjectId("4f8af65d942bb7cb40b29764"), "_class" : "org.springframework.data.demo.domain.Author", "name" : "Craig Walls" } { "_id" : ObjectId("4f8af65d942bb7cb40b29765"), "_class" : "org.springframework.data.demo.domain.Author", "name" : "Kristina Chodorow" } ...Tuesday, April 17, 12 34
  • 35. Spring Data MongoDB ✓ MongoTemplate • MongoConverter interface for mapping Mongo documents • MappingMongoConverter for POJO mapping support, leveraging Spring TypeConverters • Annotation based mapping (@Document, @Id, @DbRef) • Connection affinity callbacks • Exception translation • Support for GridFS and Map Reduce ✓ MongoRepository • Similar support as JPA RepositoriesTuesday, April 17, 12 35
  • 36. <configuration> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> </bean> <context:component-scan base-package="org.springframework.data.demo"> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan>Tuesday, April 17, 12 36
  • 37. r Fo lt ui B <beans profile="default"> <mongo:db-factory host="localhost" port="27017" dbname="db"/> </beans> <beans profile="cloud"> <cloud:mongo-db-factory id="mongoDbFactory" write-concern="NORMAL"/> </beans>Tuesday, April 17, 12 37
  • 38. Document store using MongoTemplate LIVE CODE https://github.com/trisberg/mongo-bookshelf-templateTuesday, April 17, 12 38
  • 39. • DB is a collection of graph nodes, relationships • Nodes and relationships have properties • Querying is done via a traversal API • Indexes on node/relationship properties • Written in Java, can be embedded • Transactional (ACID) • Master-Slave replication • Standalone using REST APITuesday, April 17, 12 39
  • 40. Neo4j Data ModelTuesday, April 17, 12 40
  • 41. Features • Support for property graphs (nodes connected via relationships, each with arbitrary properties) • Transparent mapping of annotated POJO entities (using AspectJ • Neo4jTemplate with convenient API, exception translation and optional transaction management • Supports the Cypher and Gremlin query languages • Dynamic type projections (duck typing) • Spring Data Repositories Support • Cross-store support for partial JPA – Graph EntitiesTuesday, April 17, 12 41
  • 42. Cross-store • JPA data and “NOSQL” data can share a data model • Separate the persistence provider by using annotations – could be the entire Entity – or, some of the fields of an Entity • We call this cross-store persistence – One transaction manager to coordinate the “NOSQL” store with the JPA relational database – AspectJ support to manage the “NOSQL” entities and fields • holds on to changed values in “change sets” until the transaction commits for non-transactional data storesTuesday, April 17, 12 42
  • 43. A cross-store scenario ... You have a traditional web app using JPA to persist data to a relational databaseTuesday, April 17, 12 43
  • 44. JPA Data Model Restaurant UserAccount @Entity @Entity public class Restaurant { @Table(name = "user_account") @Id @GeneratedValue public class UserAccount { private Long id; @Id @GeneratedValue private String name; private Long id; private String city; private String userName; private String state; private String firstName; private String zipCode; private String lastName; @Temporal(TemporalType.TIMESTAMP) private Date birthDate; @ManyToMany(cascade = CascadeType.ALL) private Set<Restaurant> favorites;Tuesday, April 17, 12 44
  • 45. Cross-store Data Model Restaurant UserAccount @Entity @Entity @NodeEntity(partial = true) @Table(name = "user_account") public class Restaurant { @NodeEntity(partial = true) @Id @GeneratedValue public class UserAccount { private Long id; @Id @GeneratedValue private String name; private Long id; private String city; private String userName; private String state; private String firstName; private String zipCode; private String lastName; @Temporal(TemporalType.TIMESTAMP) private Date birthDate; @ManyToMany(cascade = CascadeType.ALL) Recommendation private Set<Restaurant> favorites; @RelationshipEntity @GraphProperty public class Recommendation { String nickname; @StartNode @RelatedTo(type = "friends", private UserAccount user; elementClass = UserAccount.class) @EndNode Set<UserAccount> friends; private Restaurant restaurant; @RelatedToVia(type = "recommends", private int stars; elementClass = Recommendation.class) private String comment; Iterable<Recommendation> recommendations;Tuesday, April 17, 12 45
  • 46. Cross-store persistence with JPA/Neo4j DEMO https://github.com/SpringSource/spring-data-neo4j/tree/ 2.0.1.RELEASE/spring-data-neo4j-examples/myrestaurants-socialTuesday, April 17, 12 46
  • 47. Questions? http://www.sxc.hu/photo/860327Tuesday, April 17, 12 47