paintfree object-document mapping for mongodb by philipp krenn

87
Java Day Charkiv Painfree Object- Document Mapping for MongoDB Philipp Krenn @xeraa

Upload: javadayua

Post on 06-Jan-2017

200 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Java Day Charkiv

Painfree Object-Document Mapping

for MongoDBPhilipp Krenn���@xeraa

Page 2: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Vienna

Page 3: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Vienna

Page 4: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Vienna

Page 5: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

ViennaDBPapers We Love Vienna

Page 6: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Electronic Data Interchange (EDI)

Page 7: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Who uses

JPA?

Page 8: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Who uses

MongoDB?

Page 9: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Who has heard of

Morphia?

Page 10: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Like JPA for MongoDB

...but better

Page 11: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

@OneToMany(mappedBy = "destCustomerId")@ManyToMany@Fetch(FetchMode.SUBSELECT)@JoinTable(name = "customer_dealer_map", joinColumns = { @JoinColumn(name = "customer_id", referencedColumnName = "id")}, inverseJoinColumns = { @JoinColumn(name = "dealer_id", referencedColumnName = "id")})private Collection<Client> dealers;

Page 12: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Page 13: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Relations vs Objects

Page 14: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Ted Neward: ORM is "The Vietnam of

Computer Science"http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx

Page 15: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

MongoDB

Page 16: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Table = CollectionSchemaless

Row = DocumentJSON

Page 17: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

{ "name": "Philipp", "isAlive": true, "age": 30, "height_cm": 181.5, "address": { "city": "Vienna", "postalCode": "1190" }, "phoneNumbers": [ { "type": "mobile", "number": "+43 123 4567890" } ]}

Page 18: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

MongoDB Java driver

Page 19: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

List<BasicDBObject> phoneNumbers = new ArrayList<>();phoneNumbers.add( new BasicDBObject("type", "mobile") .append("number", "+43 123 4567890"));

BasicDBObject document = new BasicDBObject("name", "Philipp") .append("isAlive", true) .append("age", 30) .append("height_cm", 181.5f) .append("address", new BasicDBObject("city", "Vienna") .append("postalCode", "1190")) .append("phoneNumbers", phoneNumbers);

Page 20: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Page 21: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Morphia

Page 22: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Object-Document Mapping

POJO + AnnotationsObject-Relational Mapping

Page 23: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

FeaturesLightweight

Type safe & preserving

Page 24: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Required librarieshttps://github.com/mongodb/

mongo-java-driver (3.0.4)+

https://github.com/mongodb/morphia (1.0.1)

Page 25: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Show me some codehttps://github.com/xeraa/

morphia-demo

Page 26: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Page 27: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

$ gradle testStandalone or embedded

MongoDB

Page 28: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Annotations

Page 29: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Collections

Page 30: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

@Entity( value = "company")public class CompanyEntity {

@Id protected ObjectId id;

public CompanyEntity() { }

Page 31: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Do notuse dashes in the collection name

Page 32: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

https://www.destroyallsoftware.com/talks/wat

Page 33: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Do notcopy paste the value attribute

Page 34: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Do notuse @Id as String (without reason)

Page 35: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Polymorphism

Page 36: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public abstract class EmployeeEntity { protected String name;}

public class ManagerEntity extends EmployeeEntity { protected Boolean approveFunds;}

public class WorkerEntity extends EmployeeEntity { protected Integer yearsExperience;}

Page 37: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

RDBMS1. Union table with (many) NULL

values

Page 38: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

RDBMS2. Concrete instances without

common queries

Page 39: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

RDBMS3. Base table joined with all

subtables

Page 40: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Page 41: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

@Entity(value = "employee", noClassnameStored = false)public abstract class EmployeeEntity { @Id protected ObjectId id;

protected String name;}

public class ManagerEntity extends EmployeeEntity { protected Boolean approveFunds;}

public class WorkerEntity extends EmployeeEntity { protected Integer yearsExperience;}

Page 42: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

{ "_id": ObjectId("5461c8bf9e2acf32ed50c079"), "className": "net.xeraa.morphia_demo.entities.ManagerEntity", "name": "Peter", "approveFunds": true}{ "_id": ObjectId("524d9fe7e4b0f8bd3031f84e"), "className": "net.xeraa.morphia_demo.entities.WorkerEntity", "name": "Philipp", "yearsExperience": 10}

Page 43: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

className and refactoring?

Page 44: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Properties

Page 45: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

protected String firstname;

@AlsoLoad("lastname")protected String surname;

protected Boolean approveFunds;

@Property("hire")protected boolean managerCanApproveHires;

public EmployeeEntity setFirstname(String firstname) { this.firstname = firstname; return this;}

Page 46: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Dotrim property names (MMAPv1)

Page 47: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Douse object data types

Page 48: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Doprovide chainable setters

Page 49: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

DoOr use Lombok !

Page 50: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Indexes

Page 51: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

@Entity(value = "employee", noClassnameStored = false)@Indexes(@Index(name = "name", fields = { @Field(value = "surname"), @Field(value = "firstname")}))public class EmployeeEntity {

protected String firstname;

protected String surname;

@Indexed(unique = true, sparse = false) protected String email;

Page 52: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Optimistic lockingvs pessimistic locking in RDBMS

Page 53: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

@Versionprivate long version;

{ ... "version": NumberLong("1")}

Page 54: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Anti JOIN

Page 55: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public class EmployeeEntity {

@Reference protected CompanyEntity company;

@Embedded protected BankConnectionEntity bankConnection;

Page 56: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Queries

Page 57: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Save or upsert

Page 58: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public ObjectId persistCompanyEntity(CompanyEntity company) { mongoDatastore.save(company); return company.getId();}

public ObjectId persistManagerEntity(ManagerEntity manager) { mongoDatastore.save(manager); return manager.getId();}

public ObjectId persistWorkerEntity(WorkerEntity worker) { mongoDatastore.save(worker); return worker.getId();}

Page 59: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Get data

Page 60: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public EmployeeEntity findByEmail(final String email) { return mongoDatastore.find(EmployeeEntity.class) .field("email").equal(email).get();}

public List<EmployeeEntity> getAllEmployees() { return mongoDatastore.find(EmployeeEntity.class).asList();}

public List<ManagerEntity> getAllManagers() { return mongoDatastore.find(ManagerEntity.class) .disableValidation() .field("className").equal(ManagerEntity.class.getName()) .asList();}

Page 61: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Watch out.equal() != .equals()

Trust your compiler

Page 62: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

PerformanceNormalize fields

email.toLowerCase() before saving

Page 63: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

More queriesRegular expressions

.exists(), .doesNotExist().greaterThan(), .hasAnyOf(),...

.sort(), .skip(), .limit()

Page 64: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

More featuresCapped collections

GridFSAggregation framework

Geo locations

Page 65: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Patterns

Page 66: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Base Class

Page 67: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public abstract class BaseEntity {

@Id protected ObjectId id;

protected Date creationDate; protected Date lastChange;

@Version private long version;

Page 68: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public BaseEntity() { super(); }

// No setters public ObjectId getId() { return id; } public Date getCreationDate() { return creationDate; } public Date getLastChange() { return lastChange; }

Page 69: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

@PrePersist public void prePersist() { this.creationDate = (creationDate == null) ? new Date() : creationDate; this.lastChange = (lastChange == null) ? creationDate : new Date(); }

public abstract String toString();

}

Page 70: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public <E extends BaseEntity> ObjectId persist(E entity) { mongoDatastore.save(entity); return entity.getId();}

public <E extends BaseEntity> long count(Class<E> clazz) { return mongoDatastore.find(clazz).countAll();}

public <E extends BaseEntity> E get(Class<E> clazz, final ObjectId id) { return mongoDatastore.find(clazz).field("id").equal(id).get();}

Page 71: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Converters

Page 72: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Option 1Not readable or searchable in the database

@Serializedprotected BigDecimal bonus;

Page 73: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Option 2Fugly

@Transientprotected BigDecimal salary;protected String salaryString;

Page 74: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

@PrePersistpublic void prePersist() { super.prePersist(); if (salary != null) { this.salaryString = this.salary.toString(); }}

@PostLoadpublic void postLoad() { if (salaryString != null) { this.salary = new BigDecimal(salaryString); } else { this.salary = null; }}

Page 75: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Option 3Yes!

@Converters({BigDecimalConverter.class})public class WorkerEntity extends EmployeeEntity { protected BigDecimal dailyAllowance;

Page 76: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

public class BigDecimalConverter extends TypeConverter implements SimpleValueConverter { @Override public Object encode(Object value, MappedField optionalExtraInfo) { if (value == null) { return null; } return value.toString(); }

@Override public Object decode(Class targetClass, Object fromDBObject, MappedField optionalExtraInfo) throws MappingException { if (fromDBObject == null) { return null; } return new BigDecimal(fromDBObject.toString()); }}

Page 77: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Morehttp://projects.spring.io/spring-data-mongodb/

https://github.com/fakemongo/fongohttps://github.com/evanchooly/critter

Page 78: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

CritterQuery<Query> query = ds.createQuery(Query.class);query.and( query.criteria("bookmark").equal(bookmark), query.criteria("database").equal(database));

QueryCriteria criteria = new QueryCriteria(datastore);criteria.and( criteria.bookmark(bookmark), criteria.database(database));Query query = criteria.query().get();

Page 79: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

But is it fast?

Page 80: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Page 81: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Conclusion

Page 82: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Things you won't getTransactions

JOINs

Page 83: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Things you will getRapid development

Easy replication and shardingImpedence match with rich

documents

Page 84: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

To sum up

Developers ❤ Morphia

Page 85: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Page 86: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Thanks!Questions?

@xeraa

Page 87: Paintfree Object-Document Mapping for MongoDB by Philipp Krenn

Image Credit• Schnitzel https://flic.kr/p/9m27wm

• Architecture https://flic.kr/p/6dwCAe

• Conchita https://flic.kr/p/nBqSHT

• Paper: http://www.freeimages.com/photo/432276