• Like
Spring Data y Mongo DB en un proyecto Real
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Spring Data y Mongo DB en un proyecto Real

  • 1,667 views
Published

Presentación que utilicé en el Spring IO 2012 para la charla "Spring Data y Mongo DB en un proyecto Real". …

Presentación que utilicé en el Spring IO 2012 para la charla "Spring Data y Mongo DB en un proyecto Real".

Published in Technology , Sports
  • 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,667
On SlideShare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
52
Comments
0
Likes
2

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 y MongoDB en un proyecto real. David Gómez @dgomezgsábado 18 de febrero de 12
  • 2. David Gómez rchitect & Trainer Sw A mas.com siste extrema- dgomez@ zg @dgomesábado 18 de febrero de 12
  • 3. Spring CORE Rich Web Applications with Spring Enterprise Integrationsábado 18 de febrero de 12
  • 4. #springio #extremasábado 18 de febrero de 12
  • 5. Hablaremos de Un caso real ¿Por qué NoSQL? ¿Por qué MongoDB? MongoDB ‘a pelo’ Spring Data al rescate ¡Cuidado!sábado 18 de febrero de 12
  • 6. Un caso real. Control de tráfico marítimosábado 18 de febrero de 12
  • 7. Emisor AIX 3-5 minsábado 18 de febrero de 12
  • 8. Emisor AIX 3-5 minsábado 18 de febrero de 12
  • 9. Receptor GPS Radar (3 s) Goniometro Estación Meteo, Emisor AIX Cámaras, 3-5 min ...sábado 18 de febrero de 12
  • 10. El problema: La escalabilidadsábado 18 de febrero de 12
  • 11. El problema: La escalabilidad Por cada barco: Recepción y procesamiento de señales (nº) Transacciones, Cálculo de alarmas Gestión de Históricossábado 18 de febrero de 12
  • 12. El problema: La escalabilidad Señales (1 AIS x 3 min + 1 radar x 3 seg) x 100 barcos Alarmas Persistencia de Líneas de Varada (10.000+ ptos x 100+ líneas) 40 Alarmas Zonas, Elementos Navegación Persistencia: Total: 87 tablas + históricos(x2)sábado 18 de febrero de 12
  • 13. El problema: La escalabilidadsábado 18 de febrero de 12
  • 14. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 15. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency C Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 16. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency Availability C A Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 17. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency Availability C A P Partition Tolerance Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 18. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency Availability C A P Partition Tolerance Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 19. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency Availability C A Sólo 2 P Partition Tolerance Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 20. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency Availability A Oracle, MySQL, C Sólo 2 P Partition Tolerance Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 21. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency Availability A Oracle, MySQL, C Sólo M Hyp is, M on er em 2 go Ta c Re DB ble ac d , D , H heD at Ba B aS se to re , P Partition Tolerance Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 22. ¿Por qué NoSQL? RDBMS Orientadas a documento Teorema CAP (Eric Brewer) orientadas a columna Key-Value Consistency Availability A Oracle, MySQL, C Sólo M Hyp is, M , on er em uc ra, ort 2 aK go Ta c Co nd m Re Ri DB ble ac B, a de d B, D ass ol , D , H heD hD ple C o,V at Ba B am aS se to yn re D , P Partition Tolerance Sim Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  • 23. Pero... ¿NoSQL? (cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150sábado 18 de febrero de 12
  • 24. Pero... ¿NoSQL? (cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150sábado 18 de febrero de 12
  • 25. Pero... ¿NoSQL? NoSQL !== no SQL Not only SQL (cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150sábado 18 de febrero de 12
  • 26. NoSQL: ACID vs BASE Atomicity, Basically Available, Consistency, Soft state, Isolation, Eventual Durability consistency (cc) Photo by zhouxuan12345678 - http://www.flickr.com/photos/53921113@N02/5645102295/sábado 18 de febrero de 12
  • 27. Tipos. orientadas a Columna orientadas a Documento Key-value orientadas a Grafossábado 18 de febrero de 12
  • 28. ¿Por qué MongoDB? Orientada a documento Almacenados en Colecciones (bajo una clave) Los documentos pueden ser heterogéneos Formatos textuales: JSON & BSON (cc) Photo by Ampersand Duck - http://www.flickr.com/photos/ampersandduck/4941185476sábado 18 de febrero de 12
  • 29. MongoDB Escrita en C++ Orientada a documento Formato JSON (o BSON) Un poco SQL (queries, índices, Referencias externas) Particionado horizontal (sharding) Consultas Javascript (cc) Photo by Ampersand Duck - http://www.flickr.com/photos/ampersandduck/4941185476sábado 18 de febrero de 12
  • 30. Orientadas a Documento Documentos formateados en JSONsábado 18 de febrero de 12
  • 31. Orientadas a Documento Documentos formateados en JSON { "_id" : "224000999", "_class" : "com.vts.model.Vessel", "flag" : "ALBANIA", "name" : "Sample NOT_AVAILABLE Vessel 224000999", "callsign" : "SV224000999", "toBow" : 25, "toStern" : 5, "toPort" : 5, "toStarboard" : 5, "comments" : "Sample vessel created automatically for test purposes" }sábado 18 de febrero de 12
  • 32. El API Consola y API JavaScript:sábado 18 de febrero de 12
  • 33. El API Consola y API JavaScript: beleriand:bin dgomez$ ./mongo MongoDB shell version: 1.8.1 connecting to: test >sábado 18 de febrero de 12
  • 34. El API Consola y API JavaScript: beleriand:bin dgomez$ ./mongo MongoDB shell version: 1.8.1 connecting to: test > use vts switched to db vts >sábado 18 de febrero de 12
  • 35. El API Consola y API JavaScript: beleriand:bin dgomez$ ./mongo MongoDB shell version: 1.8.1 connecting to: test > use vts switched to db vts > show collections > Event WeatherData system.indexes vessel >sábado 18 de febrero de 12
  • 36. El API Consola y API JavaScript: beleriand:bin dgomez$ ./mongo MongoDB shell version: 1.8.1 connecting to: test > use vts switched to db vts > show collections > Event WeatherData system.indexes vessel > db.Event.find() > { "_id" : ObjectId("4e0b5b211446446f6be3bb1a"), "_class" : "com.vts.model.events.SystemEvent", "timestamp" : ISODate("2011-06-29T17:04:33.039Z") } { "_id" : ObjectId("4e0b5b3d144676f49946443f"), "_class" : "com.vts.model.events.SystemEvent", "timestamp" : ISODate("2011-06-29T17:05:01.394Z") } >sábado 18 de febrero de 12
  • 37. El API Consola y API JavaScript:sábado 18 de febrero de 12
  • 38. El API Consola y API JavaScript: > show collections Event WeatherData system.indexes vessel >sábado 18 de febrero de 12
  • 39. El API Consola y API JavaScript: > show collections Event WeatherData system.indexes vessel > db.alarms.save({"type" : "speed", "severity" : "warn", "vesselSSID" : > "224000999"}) >sábado 18 de febrero de 12
  • 40. El API Consola y API JavaScript: > show collections Event WeatherData system.indexes vessel > db.alarms.save({"type" : "speed", "severity" : "warn", "vesselSSID" : > "224000999"}) > show collections > Event WeatherData alarms system.indexes vessel >sábado 18 de febrero de 12
  • 41. El API Consola y API JavaScript: > show collections Event WeatherData system.indexes vessel > db.alarms.save({"type" : "speed", "severity" : "warn", "vesselSSID" : > "224000999"}) > show collections > Event WeatherData alarms system.indexes vessel > db.alarms.find() > { "_id" : ObjectId("4f3acca3ed4cc8078fd1a4be"), "type" : "speed", "severity" : "warn", "vesselSSID" : "224000999" } >sábado 18 de febrero de 12
  • 42. Documentos Identificados por un “_id” (generado o asignado) Textual (JSON) Binario (BSON)* Documentos grandes divididos en chunkssábado 18 de febrero de 12
  • 43. Programación de clientes Multitud de lenguajes (drivers) Transformación a JSON realizada por el driversábado 18 de febrero de 12
  • 44. Programación de clientes Multitud de lenguajes (drivers) Transformación a JSON realizada por el driver { "_id" : "224000999", "flag" : "ALBANIA", "name" : "Sample NOT_AVAILABLE Vessel 224000999", "callsign" : "SV224000999", "toBow" : 25, "toStern" : 5, "toPort" : 5, "toStarboard" : 5, "comments" : "Sample vessel created automatically for test purposes" } sample.pysábado 18 de febrero de 12
  • 45. Programación de clientes Multitud de lenguajes (drivers) Transformación a JSON realizada por el driver { "_id" : "224000999", { "_id" => "224000999", "flag""flag" => "ALBANIA", : "ALBANIA", "name""name" => "Sample NOT_AVAILABLE 224000999", : "Sample NOT_AVAILABLE Vessel Vessel 224000999", "callsign" : "SV224000999", "callsign" => "SV224000999", "toBow" : 25, => 25, "toBow" "toStern" : 5, => 5, "toStern" "toPort" : 5, => 5, "toPort" "toStarboard" : 5, => 5, "toStarboard" "comments" : "Sample"Sample createdcreated automatically for test purposes" } "comments" => vessel vessel automatically for test purposes" } sample.py Rubysábado 18 de febrero de 12
  • 46. Programación de clientes Multitud de lenguajes (drivers) Transformación a JSON realizada por el driver { "_id" : "224000999", { "_id" => "224000999", "224000999", array( "_id" => "flag""flag" "flag" => "ALBANIA", : "ALBANIA", => "ALBANIA", "name""name" "name" => "Sample NOT_AVAILABLE Vessel 224000999", : "Sample"Sample NOT_AVAILABLE 224000999", => NOT_AVAILABLE Vessel Vessel 224000999", "callsign" : "callsign" => "SV224000999", "callsign" => "SV224000999", "SV224000999", "toBow" : 25, => 25, => 25, "toBow""toBow" "toStern" : 5, => 5, => 5, "toStern" "toStern" "toPort" : 5, => 5, => 5, "toPort" "toPort" "toStarboard" : 5, => 5, => 5, "toStarboard" "toStarboard" "comments" : "comments" => "Sample vessel created automatically for test purposes"} "comments" => "Sample createdcreated automatically for test purposes" } "Sample vessel vessel automatically for test purposes" } sample.py sample.php Rubysábado 18 de febrero de 12
  • 47. Programación de clientes Multitud de lenguajes (drivers) Transformación a JSON realizada por el driver BasicDBObject doc = new BasicDBObject(); { "_id" : "224000999", { "_id" => "224000999", "224000999", array( "_id" => doc.put("flag", vessel.getFlag()); "flag""flag" "flag" => "ALBANIA", : "ALBANIA", => "ALBANIA",doc.put("name", vessel.getName()); "name""name" "name" => "Sample NOT_AVAILABLE Vessel 224000999", : "Sample"Sample NOT_AVAILABLE 224000999", => NOT_AVAILABLE Vessel Vessel 224000999", doc.put("callsign", vessel.getCalSign()); "callsign" : "callsign" => "SV224000999", "callsign" => "SV224000999", "SV224000999", doc.put("toBow", vessel.getBow()); "toBow" : 25, => 25, => 25, "toBow""toBow" "toStern" : 5, => 5, => 5, "toStern" "toStern" doc.put("toPort", vessel.getStern()); "toPort" : 5, => 5, => 5, "toPort" "toPort" doc.put("toStern", vessel.getPort()); "toStarboard" : 5, => 5, doc.put("toStartboard", vessel.getStarboard()); "toStarboard" "toStarboard" => 5, "comments" : "comments" => doc.put("comments", vessel.getComments()); purposes"} "comments" => "Sample createdcreated automatically for test purposes" } "Sample vessel vessel vessel created automatically for test "Sample automatically for test purposes" } sample.py sample.php Ruby sample.javasábado 18 de febrero de 12
  • 48. Cliente Java con MongoDB ‘a pelo’sábado 18 de febrero de 12
  • 49. 1. Obtener el Driver Importar el driversábado 18 de febrero de 12
  • 50. 1. Obtener el Driver Importar el driver <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</ artifactId> <version>2.7.0-rc1</version> </dependency>sábado 18 de febrero de 12
  • 51. 2. Conexión Obtener la referencia a la BD y la conexiónsábado 18 de febrero de 12
  • 52. 2. Conexión Obtener la referencia a la BD y la conexión Mongo m = new Mongo( "127.0.0.1" , 27017 ); DB db = m.getDB( "playground" ); sábado 18 de febrero de 12
  • 53. 3. Inserciones Crear e insertar un objetosábado 18 de febrero de 12
  • 54. 3. Inserciones Crear e insertar un objeto BasicDBObject doc = new BasicDBObject(); doc.put("flag", vessel.getFlag()); doc.put("name", vessel.getName()); doc.put("callsign", vessel.getCalSign()); doc.put("toBow", vessel.getBow()); doc.put("toPort", vessel.getStern()); doc.put("toStern", vessel.getPort()); doc.put("toStartboard", vessel.getStarboard()); doc.put("comments", vessel.getComments()); DBCollection coll = db.getCollection("vessel"); coll.insert(doc);sábado 18 de febrero de 12
  • 55. 4. Consultas (I) Obtener todos los documentos de una colecciónsábado 18 de febrero de 12
  • 56. 4. Consultas (I) Obtener todos los documentos de una colección DBCollection vessels = db.getCollection("vessel"); DBCursor cursor = vessels.find(); List<Vessel> vessels = new ArrayList<>(); while (cursor.hasNext()) { DBObject jsonVessel = cursor.next(); Vessel vessel = new Vessel(); vessel.setMmsi(jsonVessel.get(“mmsi”)); vessel.setLength(jsonVessel.get(“length”)); // ... vessels.add(vessel); }sábado 18 de febrero de 12
  • 57. 4. Consultas (I) Obtener todos los documentos de una colección DBCollection vessels = db.getCollection("vessel"); DBCursor cursor = vessels.find(); List<Vessel> vessels = new ArrayList<>(); while (cursor.hasNext()) { class DBCollection { public abstract DBObject jsonVessel = cursor.next(); public final DBCursor find(){ Vessel vessel = new Vessel(); public final DBCursor find( DBObject ref ) vessel.setMmsi(jsonVessel.get(“mmsi”)); public final DBCursor find( DBObject ref , DBObject keys ) vessel.setLength(jsonVessel.get(“length”)); // ... public final DBObject findOne( Object obj ) vessels.add(vessel); DBObject findOne( Object obj, DBObject fields ) public final } public DBObject findAndModify( DBObject query , DBObject update ) }sábado 18 de febrero de 12
  • 58. 4. Consultas (II) Consultas “SQL-like”sábado 18 de febrero de 12
  • 59. 4. Consultas (II) Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; Las consultas se hacen también en JSONsábado 18 de febrero de 12
  • 60. 4. Consultas (II) Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; Las consultas se hacen también en JSON { “flag” : “ALBANIA” }sábado 18 de febrero de 12
  • 61. 4. Consultas (II) Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; Las consultas se hacen también en JSON { “flag” : “ALBANIA” } beleriand:bin dgomez$ ./mongo MongoDB shell version: 1.8.1 connecting to: test > use vts switched to db vts > db.vessel.find( { "flag" : "ALBANIA" }); { "_id" : "224312999", "_class" : "com.vts.model.Vessel", "flag" : "ALBANIA", "name" : "Sample TOWING Vessel 224312999", "callsign" : "SV224312999", “length”: 30, “beam” : “10”, "toBow" : 25, "toStern" : 5, "toPort" : 5, "toStarboard" : 5, "comments" : "Sample vessel created automatically for test purposes" } >sábado 18 de febrero de 12
  • 62. 4. Consultas (II) Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; Las consultas se hacen también en JSON { “flag” : “ALBANIA” } beleriand:bin dgomez$ ./mongo MongoDB shell version: 1.8.1 connecting to: test > use vts switched to db vts DBObject query = new BasicDBObject(); query.put("flag", "ALBANIA"); > db.vessel.find( { "flag" : "ALBANIA" }); { "_id" : "224312999", "_class" : "com.vts.model.Vessel", "flag" : "ALBANIA", DBCursor albanianShips = vessels.find(query); "name" : "Sample TOWING Vessel 224312999", "callsign" : "SV224312999", “length”: 30, “beam” : “10”, "toBow" : 25, "toStern" : 5, "toPort" : 5, { while (albanianShips.hasNext()) "toStarboard" : 5, // ... "comments" : "Sample vessel created automatically for test purposes" } > }sábado 18 de febrero de 12
  • 63. Operadores de consulta Otros operadoressábado 18 de febrero de 12
  • 64. Operadores de consulta Otros operadores $all $and $exists $gt $in $lt $mod $ne $nin $nor $or $size $typesábado 18 de febrero de 12
  • 65. Consultas complejas Concatenación de consultas RDBMS:sábado 18 de febrero de 12
  • 66. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 RDBMS: AND (flag = “ALBANIA” or flag = ”SAN MARINO”);sábado 18 de febrero de 12
  • 67. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 RDBMS: AND (flag = “ALBANIA” or flag = ”SAN MARINO”); { “length” : { $lt : 90, $gt : 30}, Mongo: $or : [ { “flag” : “ALBANIA”}, { “flag” : “SAN MARINO”} ] }sábado 18 de febrero de 12
  • 68. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 RDBMS: AND (flag = “ALBANIA” or flag = ”SAN MARINO”); { “length” : { $lt : 90, $gt : 30}, Mongo: $or : [ { “flag” : “ALBANIA”}, { “flag” : “SAN MARINO”} ] } DBObject query = new BasicDBObject(); DBObject condition = new BasicDBObject("$lt",90); condition.put("$gt",30); query.put("length", condition); DBObject [] flags = { Mongo new BasicDBObject("flag", "ALBANIA"), new BasicDBObject("flag", "SAN MARINO") }; Driver: query.put("$or", flags); talks.find(query);sábado 18 de febrero de 12
  • 69. DBObjects desde JSON com.mongo.util.JSONsábado 18 de febrero de 12
  • 70. DBObjects desde JSON com.mongo.util.JSON Object query = JSON.parse("{ length : { $lt : 90, $gt : 30}, " + $or : [ { flag : ALBANIA}, " + " " { flag : SAN MARINO} ] }"); DBCursor cursor = db.find((DBObject) query);sábado 18 de febrero de 12
  • 71. Además... Gestión de excepciones Gestión recursos DB, Collección, Cursores, DBObjects... Transformaciones Objeto JSONsábado 18 de febrero de 12
  • 72. Spring Data MongoDBsábado 18 de febrero de 12
  • 73. Spring Data Objetivo: Proporcionar un mecanismo homogéneo y completo para el acceso a BD NoSQL Multiples proyectos: Soportados: MongoDB, Redis, Neo4j, Hadoop, GemFire, RiaK En proceso: CouchDB, Hbase, Cassandrasábado 18 de febrero de 12
  • 74. Spring Data y MongoDB XML namespace para configurar driver Mongo MongoTemplate Conversión de excepciones automática Conversión Configurable JMX monitoringsábado 18 de febrero de 12
  • 75. Importando Spring Datasábado 18 de febrero de 12
  • 76. Importando Spring Data <repository> <id>spring-release</id> <name>Spring Maven Release Repository</name> <url>http://repo.springsource.org/libs-release</url> </repository> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>1.0.1.RELEASE</version> </dependency>sábado 18 de febrero de 12
  • 77. Namespacesábado 18 de febrero de 12
  • 78. Namespace <?xml  version="1.0"  encoding="UTF-­‐8"?> <beans  xmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-­‐instance"     xmlns:mongo="http://www.springframework.org/schema/data/mongo"   xmlns:context="http://www.springframework.org/schema/context"   xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-­‐beans.xsd            http://www.springframework.org/schema/data/mongo            http://www.springframework.org/schema/data/mongo/spring-­‐mongo-­‐1.0.xsd          http://www.springframework.org/schema/context            http://www.springframework.org/schema/context/spring-­‐context.xsd"> </beans>sábado 18 de febrero de 12
  • 79. Namespace <?xml  version="1.0"  encoding="UTF-­‐8"?> <beans  xmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-­‐instance"     xmlns:mongo="http://www.springframework.org/schema/data/mongo"   xmlns:context="http://www.springframework.org/schema/context"   xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-­‐beans.xsd            http://www.springframework.org/schema/data/mongo            http://www.springframework.org/schema/data/mongo/spring-­‐mongo-­‐1.0.xsd          http://www.springframework.org/schema/context            http://www.springframework.org/schema/context/spring-­‐context.xsd"> <mongo:db-­‐factory  dbname="vts"/> </beans>sábado 18 de febrero de 12
  • 80. Namespace <?xml  version="1.0"  encoding="UTF-­‐8"?> <beans  xmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-­‐instance"     xmlns:mongo="http://www.springframework.org/schema/data/mongo"   xmlns:context="http://www.springframework.org/schema/context"   xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-­‐beans.xsd            http://www.springframework.org/schema/data/mongo            http://www.springframework.org/schema/data/mongo/spring-­‐mongo-­‐1.0.xsd          http://www.springframework.org/schema/context            http://www.springframework.org/schema/context/spring-­‐context.xsd"> <mongo:db-­‐factory  dbname="vts"/>   <bean  id="mongoTemplate"  class="org.springframework.data.mongodb.core.MongoTemplate">     <constructor-­‐arg  name="mongoDbFactory"  ref="mongoDbFactory"  />   </bean> </beans>sábado 18 de febrero de 12
  • 81. MongoTemplate <bean  id="mongoTemplate"  class="org.springframework.data.mongodb.core.MongoTemplate">   <constructor-­‐arg  name="mongoDbFactory"  ref="mongoDbFactory"  /> </bean> Identifica la colección Convierte query a JSON Convierte respuesta (“_class”) Gestiona las conexiones y cursores Convierte las excepcionessábado 18 de febrero de 12
  • 82. MongoTemplate - Consultassábado 18 de febrero de 12
  • 83. MongoTemplate - Consultas public class MongoTemplate implements MongoOperations, ApplicationContextAware { public <T> T findOne(Query query, Class<T> entityClass) public <T> List<T> find(Query query, Class<T> entityClass) public <T> T findById(Object id, Class<T> entityClass) public <T> List<T> findAll(Class<T> entityClass) }sábado 18 de febrero de 12
  • 84. MongoTemplate - Consultas public class MongoTemplate implements MongoOperations, ApplicationContextAware { public <T> T findOne(Query query, Class<T> entityClass) public <T> List<T> find(Query query, Class<T> entityClass) public <T> T findById(Object id, Class<T> entityClass) public <T> List<T> findAll(Class<T> entityClass) } public <T> T findOne(Query query, Class<T> entityClass, String collectionName) ....sábado 18 de febrero de 12
  • 85. Consultas Consultas “SQL-like” RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;sábado 18 de febrero de 12
  • 86. Consultas Consultas “SQL-like” RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; Las consultas se hacen también en JSON Mongo: { “flag” : “ALBANIA” }sábado 18 de febrero de 12
  • 87. Consultas Consultas “SQL-like” RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; Las consultas se hacen también en JSON Mongo: { “flag” : “ALBANIA” } DBCollection vessels = db.getCollection("vessel"); DBObject query = new BasicDBObject(); query.put("flag", "ALBANIA"); Mongo DBCursor albanianShips = vessels.find(query); while (albanianShips.hasNext()) { Driver: DBObject result = albanianShips.next(); // Create Vessel object from DBObject }sábado 18 de febrero de 12
  • 88. Consultas Consultas “SQL-like” RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; Las consultas se hacen también en JSON Mongo: { “flag” : “ALBANIA” } Query query = new Query(Criteria.where("flag").is("ALBANIA"); List<Vessel> vessels = mongoTemplate.find(query, Vessel.class); Utilizado para Identificación de la colección Serialización JSONsábado 18 de febrero de 12
  • 89. Serialización automáticasábado 18 de febrero de 12
  • 90. Serialización automática {  "_id"  :  "224000999",    "_class"  :  "com.vts.model.Vessel",    "flag"  :  "ALBANIA",    "name"  :  "Sample  NOT_AVAILABLE  Vessel  224000999",    "callsign"  :  "SV224000999",    "toBow"  :  25,    "toStern"  :  5,    "toPort"  :  5,    "toStarboard"  :  5,    "comments"  :  "Sample  vessel  created  automatically  for  test  purposes"  }sábado 18 de febrero de 12
  • 91. Consultas complejas Concatenación de consultassábado 18 de febrero de 12
  • 92. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 ORDER BY lastUpdate;sábado 18 de febrero de 12
  • 93. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 ORDER BY lastUpdate; { “length” : { $lt : 90, $gt : 30} }sábado 18 de febrero de 12
  • 94. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 ORDER BY lastUpdate; { “length” : { $lt : 90, $gt : 30} } DBObject query = new BasicDBObject(); DBObject condition = new BasicDBObject("$lt",90); condition.put("$gt",30); query.put("length", condition); DBObject [] flags = { new BasicDBObject("flag", "ALBANIA"), new BasicDBObject("flag", "SAN MARINO") }; query.put("$or", flags); vessels.find(query);sábado 18 de febrero de 12
  • 95. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 ORDER BY lastUpdate; { “length” : { $lt : 90, $gt : 30} }sábado 18 de febrero de 12
  • 96. Consultas complejas Concatenación de consultas SELECT * FROM VESSELS WHERE length < 90 AND length > 30 ORDER BY lastUpdate; { “length” : { $lt : 90, $gt : 30} } Criteria criteria = Criteria.where("length"); criteria.gte(from); criteria.lte(to); Query query = new Query(criteria); query.sort().on("lastUpdate", Order.ASCENDING); List<Vessel> vessels = mongoTemplate.find(query, Vessel.class);sábado 18 de febrero de 12
  • 97. MongoTemplate - insercionessábado 18 de febrero de 12
  • 98. MongoTemplate - inserciones public class MongoTemplate implements MongoOperations, ApplicationContextAware { public void save(Object objectToSave) public void save(Object objectToSave, String collectionName) }sábado 18 de febrero de 12
  • 99. AbstractRepositorysábado 18 de febrero de 12
  • 100. AbstractRepository public abstract class AbstractMongoRepository<T> { @Inject protected MongoTemplate mongoTemplate; /** Clase que utiliza Mongo para identificar el nombre de la coleccion */ private Class<T> persistentClass; protected AbstractService(Class<T> persistentClass) { this.persistentClass = persistentClass; } public String determineCollection() { return persistentClass.getSimpleName(); } }sábado 18 de febrero de 12
  • 101. AbstractRepositorysábado 18 de febrero de 12
  • 102. AbstractRepository public abstract class AbstractMongoRepository<T> { public void save(T e) { mongoTemplate.save(e, determineCollection()); } public void save(Collection<T> entities) { for (T e : entities) { save(e); } } public void removeById(String id) { Object e = findById(id); if (e != null) { mongoTemplate.remove(e, determineCollection()); } } public T findById(String id) { T t = mongoTemplate.findById(id, persistentClass); if (t == null) { throw new ObjectNotFoundException(persistentClass, id); } return t; } }sábado 18 de febrero de 12
  • 103. VesselRepositorysábado 18 de febrero de 12
  • 104. VesselRepository public class VesselRepository extends AbstractMongoRepository<Vessel> { public VesselRepository() { super(Vessel.class); } }sábado 18 de febrero de 12
  • 105. A tener en cuentasábado 18 de febrero de 12
  • 106. El caso de BitSet Cuidado con los campos transientsábado 18 de febrero de 12
  • 107. El caso de BitSet Cuidado con los campos transient public class BitSet implements Cloneable, java.io.Serializable { /** The internal field corresponding to the serialField "bits". */ */ private long[] words; /** The number of words in the logical size of this Bitset */ private transient int wordsInUse = 0; private void expandTo(int wordIndex) { int wordsRequired = wordIndex+1; if (wordsInUse < wordsRequired) { ensureCapacity(wordsRequired); wordsInUse = wordsRequired; } } }sábado 18 de febrero de 12
  • 108. Conversión Manualsábado 18 de febrero de 12
  • 109. Conversión Manual public  class  BitSetReadConverter  implements  Converter<DBObject,  BitSet>  {   @Override   public  BitSet  convert(DBObject  source)  {     BasicDBList  words  =  (BasicDBList)source.get("words");     BitSet  bitset  =  new  BitSet();     int  index  =  0;     for  (Object  word  :  words)  {       long  value  =  (Long)word;       while  (value  !=  0L)  {       if  ((value  &  1L)  !=  0)  {                bitset.set(index);         }         ++index;         value  =  value  >>>  1;       }         }         return  bitset;   } }sábado 18 de febrero de 12
  • 110. Conversión Manual Porque a veces lo automático no funcionasábado 18 de febrero de 12
  • 111. Conversión Manual Porque a veces lo automático no funciona <?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" /> <constructor-arg name="mongoConverter" ref="mappingConverter" /> </bean> <mongo:db-factory dbname="vts"/> <mongo:mapping-converter> <mongo:custom-converters> <mongo:converter> <bean class="com.vts.db.BitSetReadConverter"/> </mongo:converter> </mongo:custom-converters> </mongo:mapping-converter> </beans>sábado 18 de febrero de 12
  • 112. Queries con multiples valoressábado 18 de febrero de 12
  • 113. Queries con multiples valores Query query = new Query( Criteria .where("length").gte(20) .and("length").lt(60));sábado 18 de febrero de 12
  • 114. Queries con multiples valores Query query = new Query( Criteria .where("length").gte(20) .and("length").lt(60)); DEBUG MongoTemplate - find using query: { "length" : { "$lt" : 60} }sábado 18 de febrero de 12
  • 115. Queries con multiples valoressábado 18 de febrero de 12
  • 116. Queries con multiples valores Query query = new Query( Criteria .where("length").gte(20).lte(60));sábado 18 de febrero de 12
  • 117. Queries con multiples valores Query query = new Query( Criteria .where("length").gte(20).lte(60)); DEBUG MongoTemplate - find using query: { "toBow" : { "$gte" : 20 , "$lte" : 60} }sábado 18 de febrero de 12
  • 118. Conclusiones Reducción del número de tablas (87x2 vs 5) Optimización en el rendimiento de escrituras Simplificación de los DAOs con Spring-Data Otras ventajas: Documentos en formato de Respuesta REST interfaz Javascript en la consolasábado 18 de febrero de 12
  • 119. Q&A David Gómez @dgomezgsábado 18 de febrero de 12