Spring Data y Mongo DB en un proyecto Real

2,597 views

Published on

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
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,597
On SlideShare
0
From Embeds
0
Number of Embeds
76
Actions
Shares
0
Downloads
84
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Spring Data y Mongo DB en un proyecto Real

  1. 1. Spring Data y MongoDB en un proyecto real. David Gómez @dgomezgsábado 18 de febrero de 12
  2. 2. David Gómez rchitect & Trainer Sw A mas.com siste extrema- dgomez@ zg @dgomesábado 18 de febrero de 12
  3. 3. Spring CORE Rich Web Applications with Spring Enterprise Integrationsábado 18 de febrero de 12
  4. 4. #springio #extremasábado 18 de febrero de 12
  5. 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. 6. Un caso real. Control de tráfico marítimosábado 18 de febrero de 12
  7. 7. Emisor AIX 3-5 minsábado 18 de febrero de 12
  8. 8. Emisor AIX 3-5 minsábado 18 de febrero de 12
  9. 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. 10. El problema: La escalabilidadsábado 18 de febrero de 12
  11. 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. 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. 13. El problema: La escalabilidadsábado 18 de febrero de 12
  14. 14. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  15. 15. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency C Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  16. 16. ¿Por qué NoSQL? Teorema CAP (Eric Brewer) Consistency Availability C A Source: Nathan Hurst’s Blogsábado 18 de febrero de 12
  17. 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. 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. 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. 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. 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. 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. 23. Pero... ¿NoSQL? (cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150sábado 18 de febrero de 12
  24. 24. Pero... ¿NoSQL? (cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150sábado 18 de febrero de 12
  25. 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. 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. 27. Tipos. orientadas a Columna orientadas a Documento Key-value orientadas a Grafossábado 18 de febrero de 12
  28. 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. 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. 30. Orientadas a Documento Documentos formateados en JSONsábado 18 de febrero de 12
  31. 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. 32. El API Consola y API JavaScript:sábado 18 de febrero de 12
  33. 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. 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. 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. 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. 37. El API Consola y API JavaScript:sábado 18 de febrero de 12
  38. 38. El API Consola y API JavaScript: > show collections Event WeatherData system.indexes vessel >sábado 18 de febrero de 12
  39. 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. 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. 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. 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. 43. Programación de clientes Multitud de lenguajes (drivers) Transformación a JSON realizada por el driversábado 18 de febrero de 12
  44. 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. 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. 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. 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. 48. Cliente Java con MongoDB ‘a pelo’sábado 18 de febrero de 12
  49. 49. 1. Obtener el Driver Importar el driversábado 18 de febrero de 12
  50. 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. 51. 2. Conexión Obtener la referencia a la BD y la conexiónsábado 18 de febrero de 12
  52. 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. 53. 3. Inserciones Crear e insertar un objetosábado 18 de febrero de 12
  54. 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. 55. 4. Consultas (I) Obtener todos los documentos de una colecciónsábado 18 de febrero de 12
  56. 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. 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. 58. 4. Consultas (II) Consultas “SQL-like”sábado 18 de febrero de 12
  59. 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. 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. 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. 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. 63. Operadores de consulta Otros operadoressábado 18 de febrero de 12
  64. 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. 65. Consultas complejas Concatenación de consultas RDBMS:sábado 18 de febrero de 12
  66. 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. 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. 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. 69. DBObjects desde JSON com.mongo.util.JSONsábado 18 de febrero de 12
  70. 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. 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. 72. Spring Data MongoDBsábado 18 de febrero de 12
  73. 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. 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. 75. Importando Spring Datasábado 18 de febrero de 12
  76. 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. 77. Namespacesábado 18 de febrero de 12
  78. 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. 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. 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. 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. 82. MongoTemplate - Consultassábado 18 de febrero de 12
  83. 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. 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. 85. Consultas Consultas “SQL-like” RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;sábado 18 de febrero de 12
  86. 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. 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. 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. 89. Serialización automáticasábado 18 de febrero de 12
  90. 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. 91. Consultas complejas Concatenación de consultassábado 18 de febrero de 12
  92. 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. 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. 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. 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. 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. 97. MongoTemplate - insercionessábado 18 de febrero de 12
  98. 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. 99. AbstractRepositorysábado 18 de febrero de 12
  100. 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. 101. AbstractRepositorysábado 18 de febrero de 12
  102. 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. 103. VesselRepositorysábado 18 de febrero de 12
  104. 104. VesselRepository public class VesselRepository extends AbstractMongoRepository<Vessel> { public VesselRepository() { super(Vessel.class); } }sábado 18 de febrero de 12
  105. 105. A tener en cuentasábado 18 de febrero de 12
  106. 106. El caso de BitSet Cuidado con los campos transientsábado 18 de febrero de 12
  107. 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. 108. Conversión Manualsábado 18 de febrero de 12
  109. 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. 110. Conversión Manual Porque a veces lo automático no funcionasábado 18 de febrero de 12
  111. 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. 112. Queries con multiples valoressábado 18 de febrero de 12
  113. 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. 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. 115. Queries con multiples valoressábado 18 de febrero de 12
  116. 116. Queries con multiples valores Query query = new Query( Criteria .where("length").gte(20).lte(60));sábado 18 de febrero de 12
  117. 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. 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. 119. Q&A David Gómez @dgomezgsábado 18 de febrero de 12

×