63
Java Evangelist, 10gen Jeff Yemin Morphia: Simplifying Persistence for Java and MongoDB

Webinar: Simplifying Persistence for Java and MongoDB

  • Upload
    mongodb

  • View
    1.767

  • Download
    0

Embed Size (px)

DESCRIPTION

Jeff Yemin will host a webinar covering the design and major features of Morphia, an Object Document Mapper (ODM) for Java and MongoDB. This webinar will start with a short introduction to MongoDB and the various options for building MongoDB applications on the JVM before taking a deep dive into Morphia. Morphia will be presented as an extended example format that demonstrates, for each feature, the domain model, a test driver, and the results as they appear in MongoDB.

Citation preview

Page 1: Webinar: Simplifying Persistence for Java and MongoDB

Java Evangelist, 10gen

Jeff Yemin

Morphia: Simplifying Persistence for Java and MongoDB

Page 2: Webinar: Simplifying Persistence for Java and MongoDB

MongoDB on the JVM

• MongoDB Java Driver– Map-based API

• JVM language integrations– Casbah (Scala)– Jmongo (Ruby)– Monger (Clojure)

• ODM (Object Document Mapper)– Morphia– Spring Data MongoDB

Page 3: Webinar: Simplifying Persistence for Java and MongoDB

Morphia

• Object Document Mapper– Specified with annotations– Implemented with reflection

• Fluent query and update APIs– Runtime validation

Page 4: Webinar: Simplifying Persistence for Java and MongoDB

Morphia by Example

• Model

• Test

• Output

Page 5: Webinar: Simplifying Persistence for Java and MongoDB

<dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.10.1</version></dependency>

<dependency> <groupId>com.google.code.morphia</groupId> <artifactId>morphia</artifactId> <version>0.99</version></dependency>

Dependencies

Page 6: Webinar: Simplifying Persistence for Java and MongoDB

<repository> <id>morphia</id> <name>Morphia</name> <url>http://morphia.googlecode.com/svn/mavenrepo/</url> <layout>default</layout></repository>

Repository

Page 7: Webinar: Simplifying Persistence for Java and MongoDB

Morphia morphia = new Morphia();Mongo mongo = new Mongo();Datastore ds = morphia.createDatastore(mongo, "test");

Create the Datastore

Page 8: Webinar: Simplifying Persistence for Java and MongoDB

Entity Modelling

Page 9: Webinar: Simplifying Persistence for Java and MongoDB

Let's model github

Page 10: Webinar: Simplifying Persistence for Java and MongoDB

class Programmer { String name;}

First Entity (model)

Page 11: Webinar: Simplifying Persistence for Java and MongoDB

Programmer programmer = new Programmer();programmer.name= "Scott Hernandez";

ds.save(programmer);

First Entity (test)

Page 12: Webinar: Simplifying Persistence for Java and MongoDB

> db.Programmer.findOne(){

"_id" : ObjectId("503292d51aa814c051554696"),"className" : "demo.Programmer","name" : "Scott Hernandez"

}

First Entity (shell)

Page 13: Webinar: Simplifying Persistence for Java and MongoDB

class Programmer { @Id ObjectId id; String name; public void toString() {…}}

@Id (model)

Page 14: Webinar: Simplifying Persistence for Java and MongoDB

Programmer programmer = new Programmer();programmer.name= "Scott Hernandez";

ds.save(programmer);System.out.println(programmer)

@Id (test)

Page 15: Webinar: Simplifying Persistence for Java and MongoDB

Programmer{id=5032935f1aa8a8aa3485b441, name='Scott Hernandez'}

@Id (toString)

Page 16: Webinar: Simplifying Persistence for Java and MongoDB

class Programmer { @Id String githubUserName; String name;}

String Id (model)

Page 17: Webinar: Simplifying Persistence for Java and MongoDB

Programmer programmer = new Programmer();programmer.githubUserName = "scotthernandez";programmer.name= "Scott Hernandez";

ds.save(programmer);

String Id (test)

Page 18: Webinar: Simplifying Persistence for Java and MongoDB

> db.Programmer.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","name" : "Scott Hernandez"

}

String Id (shell)

Page 19: Webinar: Simplifying Persistence for Java and MongoDB

@Entity("programmers")class Programmer { @Id String githubUserName; String name;}

@Entity (model)

Page 20: Webinar: Simplifying Persistence for Java and MongoDB

> db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","name" : "Scott Hernandez"

}

@Entity (shell)

Page 21: Webinar: Simplifying Persistence for Java and MongoDB

@Entity("programmers")class Programmer { @Id String githubUserName; String name; Date memberSince; boolean active; int followers;}

More primitives (model)

Page 22: Webinar: Simplifying Persistence for Java and MongoDB

Programmer scott = new Programmer();scott.userName = "scotthernandez";scott.name = "Scott Hernandez";scott.since = dateFmt.parse("Aug 12, 2009");scott.active = true;scott.followers = 8;

ds.save(scott);

More primitives (test)

Page 23: Webinar: Simplifying Persistence for Java and MongoDB

> db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","name" : "Scott Hernandez","memberSince" : ISODate("2009-08-12T04:00:00Z"),"active" : true,"followers" : 8

}

More primitives (shell)

Page 24: Webinar: Simplifying Persistence for Java and MongoDB

@Entity("programmers")class Programmer { @Id String githubUserName; String name; Date memberSince; boolean active; int followers; List<String> following;}

Primitive Array (Model)

Page 25: Webinar: Simplifying Persistence for Java and MongoDB

Programmer scott = new Programmer();scott.userName = "scotthernandez";scott.name = "Scott Hernandez";scott.since = dateFmt.parse("Aug 12, 2009");scott.active = true;scott.followers = 8;scott.following = Arrays.asList("moraes", "stickfigure");

ds.save(scott);

Primitive Array (test)

Page 26: Webinar: Simplifying Persistence for Java and MongoDB

db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","name" : "Scott Hernandez","memberSince" : ISODate("2009-08-12T04:00:00Z"),"active" : true,"followers" : 8,"following" : [

"moraes","stickfigure"

]}

Primitive Array (shell)

Page 27: Webinar: Simplifying Persistence for Java and MongoDB

@Entity("programmers")class Programmer { @Id String githubUserName; Name name; Date memberSince; boolean active; int followers; List<String> following;}

@Embeddedclass Name { String first, last;}

@Embedded (model)

Page 28: Webinar: Simplifying Persistence for Java and MongoDB

Programmer programmer = new Programmer();programmer.githubUserName = "scotthernandez";programmer.name = new Name("Scott", "Hernandez");programmer.memberSince = dateFmt.parse("Aug 12, 2009");programmer.active = true;programmer.followers = 8;programmer.following = Arrays.asList("moraes", "stickfigure");

ds.save(programmer);

@Embedded (test)

Page 29: Webinar: Simplifying Persistence for Java and MongoDB

> db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","name" : {

"first" : "Scott","last" : "Hernandez"

},"memberSince" : ISODate("2009-08-12T04:00:00Z"),"active" : true,"followers" : 8,"following" : [

"moraes","stickfigure"

]}

@Embedded (shell)

Page 30: Webinar: Simplifying Persistence for Java and MongoDB

@Entity("programmers")class Programmer { @Id String githubUserName; Name name; Date memberSince; boolean active; int followers; List<String> following; List<Repository> repositories;}

@Embeddedclass Name { String first, last;}

@Embeddedclass Repository { String name; String forkedFrom;}

@Embedded List (model)

Page 31: Webinar: Simplifying Persistence for Java and MongoDB

Programmer programmer = new Programmer();programmer.githubUserName = "scotthernandez";programmer.name = new Name("Scott", "Hernandez");programmer.memberSince = dateFmt.parse("Aug 12, 2009");programmer.active = true;programmer.followers = 8;programmer.following = Arrays.asList("moraes", "stickfigure");programmer.repositories = Arrays.asList( new Repository("docs", "mongodb/docs"), new Repository("mongo-java-driver", "mongodb/mongo-java-driver"));

ds.save(programmer);

@Embedded (test)

Page 32: Webinar: Simplifying Persistence for Java and MongoDB

> db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer",…"repositories" : [

{"name" : "docs","forkedFrom" : "mongodb/docs"

},{

"name" : "mongo-java-driver","forkedFrom" : "mongodb/mongo-java-

driver"}

]}

@Embedded List (shell)

Page 33: Webinar: Simplifying Persistence for Java and MongoDB

@Entity("repos")class Repository { @Id ObjectId id; @Reference Programmer owner; String name; String forkedFrom;}

@Reference (model)

Page 34: Webinar: Simplifying Persistence for Java and MongoDB

Programmer programmer = new Programmer();programmer.githubUserName = "scotthernandez";programmer.name = new Name("Scott", "Hernandez");programmer.memberSince = dateFmt.parse("Aug 12, 2009");programmer.active = true;programmer.followers = 8;programmer.following = Arrays.asList("moraes", "stickfigure");

ds.save(programmer);

Repository repo = new Repository(programmer, "docs", "mongodb/docs");

ds.save(repo);

@Reference (test)

Page 35: Webinar: Simplifying Persistence for Java and MongoDB

> db.repos.findOne(){

"_id" : ObjectId("503297e31aa8255abe542aaa"),"className" : "demo.Repository","owner" : DBRef("programmers", "scotthernandez"),"name" : "docs","forkedFrom" : "mongodb/docs"

}

@Reference (shell)

Page 36: Webinar: Simplifying Persistence for Java and MongoDB

abstract class Member { @Id String userName; @Property("memberSince") Date since; boolean active; String name;}

@Entity("programmers")class Programmer extends Member { int followers; List<String> following;}

@Entity("orgs")class Organization extends Member {}

@Entity("repos")class Repository { @Id ObjectId id; @Reference Member owner; String name; @Reference(lazy=true) Repository forkedFrom;}

Small schema change (model)

Page 37: Webinar: Simplifying Persistence for Java and MongoDB

Programmer scott = new Programmer();//…ds.save(scott);

// save mongodb OrganizationOrganization mongodb = new Organization("mongodb", "mongodb", sdf.parse("Jan 8, 2009"));ds.save(mongodb); // save mongodb's docs RepositoryRepository mongoDocs = new Repository(mongodb, "docs");ds.save(mongoDocs);

// save Scott's forked docs RepositoryRepository scottDocs = new Repository(scott, "docs", mongoDocs);ds.save(scottDocs);

Small schema change (test)

Page 38: Webinar: Simplifying Persistence for Java and MongoDB

> db.orgs.findOne(){

"_id" : "mongodb","className" : "demo.Organization","memberSince" : ISODate("2009-01-08T05:00:00Z"),"active" : false,"name" : "mongodb"

}> db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","memberSince" : ISODate("2009-08-12T04:00:00Z"),"active" : true,"name" : "Scott Hernandez"

…}

Small schema change (shell)

Page 39: Webinar: Simplifying Persistence for Java and MongoDB

> db.repos.find().toArray()[

{"_id" : ObjectId("503298be1aa8b1d255e5d45b"),"className" : "demo.Repository","owner" : DBRef("orgs", "mongodb"),"name" : "docs"

},{

"_id" : ObjectId("503298be1aa8b1d255e5d45c"),"className" : "demo.Repository","owner" : DBRef("programmers",

"scotthernandez"),"name" : "docs","forkedFrom" : DBRef("repos",

ObjectId("503298be1aa8b1d255e5d45b"))}

]

Small schema change (shell, 2)

Page 40: Webinar: Simplifying Persistence for Java and MongoDB

Querying

Page 41: Webinar: Simplifying Persistence for Java and MongoDB

Find by Equality (test)

• ds.get(Programmer.class, "scotthernandez")

• ds.find(Programmer.class, "name", "Scott Hernandez")

• ds.find(Programmer.class).field("name").equal("Scott Hernandez”)

Page 42: Webinar: Simplifying Persistence for Java and MongoDB

Find by Equality (logs)

• test.programmers query: { _id: "scotthernandez" }

• test.programmers query: { name: "Scott Hernandez" }

• test.programmers query: { name: "Scott Hernandez" }

Page 43: Webinar: Simplifying Persistence for Java and MongoDB

Find by Range (test)

• ds.find(Programmer.class).field("followers").greaterThan(0)

• ds.find(Programmer.class).filter("followers >", 0)

• ds.find(Programmer.class).field("memberSince").lessThan(sdf.parse("Jan 1,

2010"))

Page 44: Webinar: Simplifying Persistence for Java and MongoDB

Find by Range (logs)

• test.programmers query: { followers: { $gt: 0 } }

• test.programmers query: { followers: { $gt: 0 } }

• test.programmers query: { memberSince: { $lt: new

Date(1262322000000) } }

Page 45: Webinar: Simplifying Persistence for Java and MongoDB

ds.find(Programmer.class). field("memberSince").lessThan(dateFmt.parse("Jan 1, 2010")).

field("followers").greaterThan(0)

Combining conditions (test)

Page 46: Webinar: Simplifying Persistence for Java and MongoDB

test.programmers query: { memberSince: { $lt: new Date(1262322000000) }, followers: { $gt: 0 } }

Combining conditions(logs)

Page 47: Webinar: Simplifying Persistence for Java and MongoDB

Programmer scott = new Programmer("scotthernandez")ds.find(Repository.class).field("owner").equal(scott)

Find by Reference (test)

Page 48: Webinar: Simplifying Persistence for Java and MongoDB

test.repos query: { owner: { $ref: "programmers", $id: "scotthernandez" } }

Find by Reference (logs)

Page 49: Webinar: Simplifying Persistence for Java and MongoDB

Indexing

Page 50: Webinar: Simplifying Persistence for Java and MongoDB

@Indexed

• Annotation for fields– value (IndexDirection)– name (String)– unique (boolean)– dropDups (boolean)– background (boolean)– sparse (boolean)

• Examples– @Indexed(value=IndexDirection.ASC, name="followers") int

followers;– @Indexed @Reference Repository forkedFrom;

Page 51: Webinar: Simplifying Persistence for Java and MongoDB

@Indexes and @Index

• @Indexes: Annotation for types– value (Index[])

• @Index– value (String)– Others same as @Indexed

• Examples– @Indexes(@Index("since, -followers")) public class

Programmer {…}

Page 52: Webinar: Simplifying Persistence for Java and MongoDB

Updating

Page 53: Webinar: Simplifying Persistence for Java and MongoDB

Programmer jeff = createJeff();ds.save(jeff);

// jeff is following scott, so increment // scott's followers and re-saveProgrammer scott = ds.get(Programmer.class, "scotthernandez")

scott.followers++;ds.save(scott);

Updating with save (test)

Page 54: Webinar: Simplifying Persistence for Java and MongoDB

update test.programmers

query: { _id: "scotthernandez", } update: { _id: "scotthernandez", className: "demo.Programmer", followers: 9, following: [ "moraes", "stickfigure" ], memberSince: new Date(1250049600000), active: true, name: "Scott Hernandez", }

Updating with save (logs)

Page 55: Webinar: Simplifying Persistence for Java and MongoDB

> db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","followers" : 9,"following" : [

"moraes","stickfigure"

],"memberSince" : ISODate("2009-08-12T04:00:00Z"),"active" : true,"name" : "Scott Hernandez"

}

Updating with save (shell)

Page 56: Webinar: Simplifying Persistence for Java and MongoDB

@Entitypublic abstract class Member { @Id String userName; @Property("memberSince") Date since; boolean active; String name; @Version Long version;}

Optimistic Concurrency (model)

Page 57: Webinar: Simplifying Persistence for Java and MongoDB

update test.programmers

query: { _id: "scotthernandez", version: 1345497713173 } update: { _id: "scotthernandez", className: "demo.Programmer", followers: 9, following: [ "moraes", "stickfigure" ], memberSince: new Date(1250049600000), active: true, name: "Scott Hernandez", version: 1345497718181 }

Optimistic Concurrency (logs)

Page 58: Webinar: Simplifying Persistence for Java and MongoDB

> db.programmers.findOne(){

"_id" : "scotthernandez","className" : "demo.Programmer","followers" : 9,"following" : [

"moraes","stickfigure"

],"memberSince" : ISODate("2009-08-12T04:00:00Z"),"active" : true,"name" : "Scott Hernandez","version" : NumberLong("1345497718181")

}

Optimistic Concurrency (shell)

Page 59: Webinar: Simplifying Persistence for Java and MongoDB

Programmer jeff = createJeff();ds.save(jeff);

// increment followers of scott by oneUpdateOperations<Programmer> incrementFollowing = ds.createUpdateOperations(Programmer.class). inc("followers", 1);

Query<Programmer> queryForScott = ds.find(Programmer.class, "_id", "scotthernandez");

ds.update(queryForScott, incrementFollowing);

UpdateOperations (test)

Page 60: Webinar: Simplifying Persistence for Java and MongoDB

update test.programmers

query: { _id: "scotthernandez" }

update: { $inc: { followers: 1 } }

UpdateOperations (logs)

Page 61: Webinar: Simplifying Persistence for Java and MongoDB

Web Resources

• Morphia home: http://code.google.com/p/morphia/

• Morphia user group: https://groups.google.com/forum/?fromgroups#!forum/morphia

• Demo code: https://github.com/jyemin/morphia-demo

– Separate commit and tag for each slide, so you can play along

Page 62: Webinar: Simplifying Persistence for Java and MongoDB

Thanks!

• Jeff Yemin– https://twitter.com/@jeffyemin– [email protected]– https://github.com/jyemin/

Page 63: Webinar: Simplifying Persistence for Java and MongoDB

Engineering Manager, 10gen

Jeff Yemin

Thank You