• Save
MongoDB for Java Developers with Spring Data
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

MongoDB for Java Developers with Spring Data

  • 6,936 views
Uploaded on

The Spring Data project provides sophisticated support for NoSQL datastores. The MongoDB module consists of a namespace to easily setup MongoDB access, a template class to provide a nice API to......

The Spring Data project provides sophisticated support for NoSQL datastores. The MongoDB module consists of a namespace to easily setup MongoDB access, a template class to provide a nice API to persist and query objects as well as sophisticated support to build repositories accessing entities stored in a MongoDB. The talk will introduce the Spring Data MongoDB support.

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
6,936
On Slideshare
6,935
From Embeds
1
Number of Embeds
1

Actions

Shares
Downloads
0
Comments
0
Likes
5

Embeds 1

https://www.linkedin.com 1

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. SpringSource and MongoDBChris RichardsonAuthor of POJOs in ActionFounder of CloudFoundry.comChris.Richardson@SpringSource.Com@crichardson
  • 2. Presentation Goal How SpringSource is making it easier for Java and Grails developers to build MongoDB applications Slide 2
  • 3. About Chris •  Grew up in England and live in Oakland, CA •  Over 25+ years of software development experience including 14 years of Java •  Speaker at JavaOne, SpringOne, NFJS, JavaPolis, Spring Experience, etc. •  Organize the Oakland JUG and the Groovy Grails meetup http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/ Slide 3
  • 4. Agendao  Introduction to Springo  Spring Data and MongoDBo  Introduction to Grailso  Using Grails with MongoDB Slide 4
  • 5. The Spring frameworko  Rapid evolution n  Spring 1.0 – March 2004 n  Spring 2.0 – October 2006 n  Spring 2.5 – December 2007 n  Spring 3.0 – December 2009 n  … n  Complete backward compatibilityo  De facto standard programming model for enterprise Javao  Two million+ developers Slide 5
  • 6. The Spring framework ecosystemFramework DescriptionSpring framework The foundationSpring.NET .NET port of the Spring frameworkSpring Security (a.k.a. Acegi) Extensible framework providing authentication, authorization and instance-level securitySpring Web Flow An excellent framework for building multi-page flowsSpring Web Services Contract-first, document–centric SOAP web servicesSpring Dynamic Modules for OSGI Deploy Spring applications on OSGISpring Batch Powerful batch processing frameworkSpring Integration Implements enterprise integration patternsSpring BlazeDS integration Support for Adobe BlazeDSSpring AMQP AMQP messaging, i.e. RabbitMQSpring Gemfire Simplify Gemfire application development… Slide 6
  • 7. Spring programming model Dependency Injection: resolves inter-component Benefits: dependencies, • Improved developer metadata-driven productivity • Higher quality code • Portability across application servers POJO Aspect-Oriented Programming:Portable Service modularAbstractions: implementation ofTransactions, data cross cuttingaccess, … concerns Slide 7
  • 8. Portable service abstractionso  Portable service abstractions insulate developer Business Logic from low-level programming Infrastructure codeo  Less code Springo  Simpler code Transactions Security Data accesso  Increased … productivityo  Portable code Runtime Environment Slide 8
  • 9. Spring JDBC example@Repositoryclass ActorDaoImpl implements ActorDao { SimpleJdbcTemplate hides@Autowired the low-level, messyprivate SimpleJdbcTemplate simpleJdbcTemplate; details of using JDBCpublic Actor findActor(String specialty, int age) { String sql = "select id, first_name, last_name from T_ACTOR" + " where specialty = ? and age = ?"; RowMapper<Actor> mapper = new RowMapper<Actor>() { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setId(rs.getLong("id")); actor.setFirstName(rs.getString("first_name")); actor.setLastName(rs.getString("last_name")); return actor; } }; return simpleJdbcTemplate.queryForObject(sql, mapper, specialty, age);} Slide 9
  • 10. Externalized database configuration@Configurationpublic class AppConfig { private @Value("#{jdbcProperties.url}") String jdbcUrl; private @Value("#{jdbcProperties.username}") String username; private @Value("#{jdbcProperties.password}") String password; @Bean public SimpleJdbcTemplate jdbcTemplate() { return new SimpleJdbcTemplate (dataSource()); } @Bean public DataSource dataSource() { return new DriverManagerDataSource(jdbcUrl, username, password); }} Reads DB configuration<context:component-scan base-package="..."/> from file<util:properties id="jdbcProperties" location="…/jdbc.properties"/> Slide 10
  • 11. Spring DataAccessExceptiono Base class forexceptions thrown by DataAccess ExceptionDAOso Consistent exception Concurrency Failure Exception ...handling acrossHibernate, JPA, JDBC, Optimistic LockingFailureetc. Exception Pessimistic LockingFailure Exceptiono Unchecked exceptiono Extensible exception CannotSerializemapping: CannotAcquire LockException Transaction ExceptionSqlExceptionTranslator 11
  • 12. Agendao  Introduction to the Spring frameworko  Spring Data and MongoDBo  Introduction to Grailso  Using Grails with MongoDB Slide 12
  • 13. Spring Data Project Goalso  Bring classic Spring value propositions to a wide range of NoSQL databases: n  Productivity n  Programming model consistency: E.g. <NoSQL>Template classes n  “Portability”o  Many entry points to use n  Auto-generated repository implementations n  Opinionated APIs (Think JdbcTemplate) n  Object Mapping (Java and GORM) n  Cross Store Persistence Programming model n  Productivity support in Roo and Grails Slide 13
  • 14. MongoDB API usage patternso  Create and store Mongo singletono  Externalized server detailso  Inserts/Updates n  Map application POJO è DBObject n  mongo.getDatabase(…).getCollection(…) n  Partial document updateso  Queries n  mongo.getDatabase(…).getCollection(…) n  Iterate through Cursor n  Map DBObject è application POJOØ  Higher-level than JDBC but still repetitive, … Slide 14
  • 15. Spring Data - MongoDBo  MongoTemplateo  Generic repository implementationo  Querydsl integrationo  Cross-store persistence Slide 15
  • 16. MongoTemplateSimplifies data MongoTemplate POJO ó DBObjectaccess databaseName mappingTranslates userId Passwordexceptions defaultCollectionName writeConcern writeResultChecking <<interface>> save() MongoConvertor insert() write(Object, DBObject) remove() read(Class, DBObject) updateFirst() findOne() find() … SimpleMongo uses Converter Mongo MongoMapping (Java Driver class) Converter Slide 16
  • 17. Example entitypublic class Restaurant { private String id; private String name; private List<MenuItem> menuItems; public Restaurant() { } public class MenuItem { private String name; public Restaurant(String name) { private double price; this.name = name; … public MenuItem() { } }public String getName() { return name; } public MenuItem(String name, double price) { this.name = name; public void setName(String name) { this.price = price; this.name = name; } } …getters and setters… …getters and setters… Slide 17
  • 18. Example data access code@Repositorypublic class RestaurantRepository { @Autowired private MongoTemplate mongoTemplate; public static final String RESTAURANTS_COLLECTION = "restaurants2"; public void add(Restaurant restaurant) { mongoTemplate.save(RESTAURANTS_COLLECTION, restaurant); }public List<Restaurant> findRestaurantsByName(String restaurantName) { return mongoTemplate.find(RESTAURANTS_COLLECTION, new Query(where("name").is(restaurantName)), Restaurant.class); } Slide 18
  • 19. Mongo document{ "_id" : ObjectId("4d977f55d3fe3119c904e026"), "menuItems" : [ { "name" : "Tandoori Portobello Mushrooms", "price" : 5.5 }, { "name" : "Duck Curry Kerala", "price" : 15 } ], "name" : "Ajanta"} Slide 19
  • 20. Spring MongoDB Example - Config@Configuration public class MongoDbExampleConfig { private @Value("#{mongoDbProperties.databaseName}") String mongoDbDatabase; private @Value("#{mongoDbProperties.host}") String mongoDbHost;@Bean public Mongo mongo() throws Exception { Singleton return new Mongo(mongoDbHost);} @Bean public MongoTemplate mongoTemplate(Mongo mongo) { return new MongoTemplate(mongo, mongoDbDatabase); }… <beans> <context:annotation-config/> External Config <context:component-scan base-package="net.chrisrichardson.mongodb.example"/>mongodb.properties: <util:properties id="mongoDbProperties" location="mongodb.properties"/>databaseName=demo1 </beans>host=192.168.253.150 Slide 20
  • 21. Spring MongoDB Example Testpublic class MongoDbExampleTest { @Autowired private RestaurantRepository restaurantRepository; @Test public void test() { Restaurant ajanta = makeAjantaRestaurant(); restaurantRepository.add(ajanta); List<Restaurant> results = restaurantRepository.findRestaurantsByName("Ajanta"); assertRestaurantFound(ajanta, results); } private Restaurant makeAjantaRestaurant() { Restaurant ajanta = new Restaurant("Ajanta"); ajanta.add(new MenuItem("Tandoori Portobello Mushrooms", 5.50)); ajanta.add(new MenuItem("Duck Curry Kerala", 15.00)); return ajanta; }… Slide 21
  • 22. Update example@Repositorypublic class RestaurantRepository { public void addMenuItem(String restaurantId, MenuItem newMenuItem) { DBObject dbo = new BasicDBObject(); mongoTemplate.getConverter().write(newMenuItem, dbo); mongoTemplate.updateFirst(RESTAURANTS_COLLECTION, new Query(where("_id").is(new ObjectId(restaurantId))), new Update().push("menuItems", dbo));} Atomic, in-place update of document Slide 22
  • 23. Callbacks – access driver API with exception translation@Testpublic void testDbCallback() { Exceptions are Restaurant ajanta = makeAjantaRestaurant(); translated restaurantRepository.add(ajanta); assertCollectionExists("restaurants2");}private Void assertCollectionExists(final String collectionName) { return mongoTemplate.execute(new DbCallback<Void>(){ @Override public Void doInDB(DB db) { Set<String> collectionNames = db.getCollectionNames(); Assert.assertTrue("Missing from " + collectionNames, collectionNames.contains(collectionName)); return null; }});} Slide 23
  • 24. Generic Mongo Repositorieso  Generic Repositories support n  Basic CRUD methods n  Dynamic finders n  Pagination and sortingo  You define interface that extends Repository interfaceo  Spring Data generates Mongo-specific implementation at runtime Slide 24
  • 25. Example Mongo Generic Repositorypublic class Person { private ObjectId id; private String firstname; private String lastname;… getters and setters}interface PersonRepository extends MongoRepository<Person, ObjectId> { List<Person> findByLastname(String lastName);}Person p = new Person("John", "Doe");personRepository.save(p);Person p2 = personRepository.findOne(p.getId());List<Person> johnDoes = personRepository.findByLastname("Doe");assertEquals(1, johnDoes.size()); Slide 25
  • 26. Example Mongo Repository config<bean><mongo:repositories base-package="net.chrisrichardson.mongodb.example.mongorepository" mongo-template-ref="mongoTemplate" /></beans> Scans classpath looking for subtypes of MongoRepository in the base package Slide 26
  • 27. Richer mapping Annotations define mapping: @Document, @Id, @Indexed, @PersistanceConstructor,@Document @CompoundIndex, @DBRef,public class Person { @GeoSpatialIndexed, @Value @Id Map fields instead of properties è private ObjectId id; no getters or setters required private String firstname; Non-default constructor @Indexed private String lastname; Index generation @PersistenceConstructor public Person(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; }….} Slide 27
  • 28. Richer mapping configuration@Configurationpublic class MongoExampleConfig extends AbstractMongoConfiguration{ … @Override public MongoTemplate mongoTemplate() throws Exception { return new MongoTemplate(mongo(), mongoDbDatabase, null, mappingMongoConverter()); }@Overridepublic String getMappingBasePackage() { return Person.class.getPackage().getName();}} Slide 28
  • 29. Support for the QueryDSL project Generated from Type-safe domain model class composable queriesQPerson person = QPerson.person;Predicate predicate = person.homeAddress.street1.eq("1 High Street") .and(person.firstname.eq("John"))List<Person> people = personRepository.findAll(predicate);assertEquals(1, people.size());assertPersonEquals(p, people.get(0)); Slide 29
  • 30. Cross-store/polyglot persistence Person person = new Person(…);@Entitypublic class Person { entityManager.persist(person); // In Database @Id private Long id; Person p2 = entityManager.find(…) private String firstname; private String lastname;// In MongoDB@RelatedDocument private Address address; { "_id" : ObjectId(”….."), "_entity_id" : NumberLong(1), "_entity_class" : "net.. Person", "_entity_field_name" : "address", "zip" : "94611", "street1" : "1 High Street", …} Slide 30
  • 31. Spring MongoDB – Future Ideaso  MongoTemplate n  Support common map-reduce operations from Mongo Cookbook n  GridFS integrationo  Tighter integration with Spring MVC for activity monitoring n  See current example code on github Slide 31
  • 32. Agendao  Introduction to Springo  Spring Data and MongoDBo  Introduction to Grailso  Using Grails with MongoDB Slide 32
  • 33. Grailso  Open-source web application frameworko  Uses Groovy – dynamic programming language for the JVMo  Builds on mature frameworks such as Spring Slide 33
  • 34. GORM = Grails Object Relational Mappingo  Uses convention over configuration n  Defaults for which classes to persist n  Defaults for their O/R mappingo  Leverages the meta-object protocol n  Adds persistence methods and properties to domain classes n  No equivalent of Hibernate Session n  Avoids the need for dependency injection n  Eliminates many DAO cookie-cutter methods Slide 34
  • 35. Database access made easy customer class Customer { <<table>> String name id <<pk>> } version name Customer c = new Customer("John Doe") if (!c.save()) fail "validation failed: ${c.errors}" GORM adds Methods and Customer c2 = Customer.get(c.id) properties to class at runtime c2.delete() assertNull Customer.get(c.id) def customers = Customer.findAllByName(“Fred”) Slide 35
  • 36. Relationships don’t have to be difficult customerclass Customer { <<table>> String name id <<pk>> static hasMany = [ accounts : Account] version} nameclass Account { account static belongsTo = [customer: Customer] <<table>> double balance id <<pk>>} version customer <<fk>> Customer c = <…> balance Account a = new Account(…) c.addToAccounts(a) assertSame c, a.customer assertTrue c.accounts.contains(a) Slide 36
  • 37. When the defaults aren’t rightclass Customer { static transients = ["networth"] static mapping = { id column: customer_id crc_customer <<table>> table crc_customer columns { customer_id <<pk>> version name column: customer_name customer_name } } def getNetworth() { …} …} Slide 37
  • 38. Agendao  Introduction to Springo  Spring Data and MongoDBo  Introduction to Grailso  Using Grails with MongoDB Slide 38
  • 39. GORM for MongoDBo  Extends GORM to support MongoDBo  Announced Nov 2010o  Currently 1.0M5o  Builds on n  Spring Data for MongoDB n  Spring Data Mapping Slide 39
  • 40. GORM/MongoDB examplegrails uninstall-plugin hibernategrails install-plugin mongodbclass Customer { String name Unchanged Address address static hasMany = [ accounts : Account] static embedded = [address]} class Address { String streetclass Account { String city static belongsTo = [customer: Customer] String state double balance String zip} }DataSource.groovymongo { host = "localhost"} Slide 40
  • 41. GORM/MongoDB example> db.customer.find(){ "_id" : NumberLong(24), "address" : { "city" : "Oakland", "state" : "CA", "street" : "1 High Street", "zip" : "94619" }, "name" : "John Doe" }{ "_id" : NumberLong(25), "address" : { "city" : "Oakland", "state" : "CA", "street" : "101 Broadway", "zip" : "94619" }, "name" : "Mary Jane" }> db.account.find(){ "_id" : NumberLong(1), "balance" : 60, "customer" : NumberLong(24), "name" : "Checking" }{ "_id" : NumberLong(2), "balance" : 100, "customer" : NumberLong(24), "name" : "Savings" }{ "_id" : NumberLong(3), "balance" : 0, "customer" : NumberLong(25), "name" : "Checking" } o  Domain class ó Collection o  Property ó Attribute o  Relationship ó "FK attribute" Slide 41
  • 42. Cloud Foundry supports Mongoo  MongoDB is one of the provided servicesè Deploy your MongoDB applications inseconds Slide 42
  • 43. Summaryo  Polyglot persistence is here to stayo  Spring Data is here to help youo  GORM let’s you use the familiar and powerful GORM API with MongoDBo  Deploy your Mongo application on CloudFoundry.como  More info at n  http://www.springframework.org/spring-data n  http://www.cloudfoundry.com/ Slide 43
  • 44. Next steps Checkout Spring Data Consider contributing Deploy on CloudFoundry.com My contact information chris.richardson@springsource.com Twitter: @crichardson Slide 44