Spring Data y Mongo DB en un proyecto Real
-
Upload
david-gomez-garcia -
Category
Technology
-
view
1.788 -
download
2
description
Transcript of Spring Data y Mongo DB en un proyecto Real
David Gómez@dgomezg
Spring Data y MongoDBen un proyecto real.
sábado 18 de febrero de 12
Spring CORE
Rich Web Applications
with Spring
Enterprise Integration
sábado 18 de febrero de 12
#springio
#extrema
sábado 18 de febrero de 12
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
Un caso real. Control de tráfico marítimo
sábado 18 de febrero de 12
Emisor AIX
3-5 min
sábado 18 de febrero de 12
Emisor AIX
3-5 min
sábado 18 de febrero de 12
Emisor AIX
3-5 min
Receptor GPS
Goniometro
Estación Meteo,
Cámaras,
...
Radar (3 s)
sábado 18 de febrero de 12
El problema: La escalabilidad
sábado 18 de febrero de 12
El problema: La escalabilidad
Por cada barco:
Recepción y procesamiento de señales (nº)
Transacciones,
Cálculo de alarmas
Gestión de Históricos
sábado 18 de febrero de 12
El problema: La escalabilidadSeñ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
El problema: La escalabilidad
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
CConsistency
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
C AConsistency Availability
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
C A
P
Consistency Availability
Partition Tolerance
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
C A
P
Consistency Availability
Partition Tolerance
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
C A
P
Consistency Availability
Partition Tolerance
Sólo 2
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
C A
P
Consistency Availability
Partition Tolerance
Sólo 2
Oracle, MySQL,
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
C A
P
Consistency Availability
Partition Tolerance
Sólo 2
Oracle, MySQL,
MongoDB, DataStore,
HyperTable, HBase
Redis, Mem
cacheDB
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
C A
P
Consistency Availability
Partition Tolerance
Sólo 2
Oracle, MySQL,
MongoDB, DataStore,
HyperTable, HBase
Redis, Mem
cacheDBDyn
amo, V
oldem
ort,
Cas
sand
ra,
Simple
DB, Cou
chDB,
RiaK
RDBMSOrientadas a documento
orientadas a columnaKey-Value
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
Pero... ¿NoSQL?
(cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150
sábado 18 de febrero de 12
Pero... ¿NoSQL?
(cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150
sábado 18 de febrero de 12
Pero... ¿NoSQL?
(cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150
NoSQL !== no SQL
Not only SQL
sábado 18 de febrero de 12
NoSQL: ACID vs BASE
Atomicity,
Consistency,
Isolation,
Durability
(cc) Photo by zhouxuan12345678 - http://www.flickr.com/photos/53921113@N02/5645102295/
Basically Available,
Soft state,
Eventual consistency
sábado 18 de febrero de 12
orientadas a Columna orientadas a Documento
orientadas a GrafosKey-value
Tipos.
sábado 18 de febrero de 12
¿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/4941185476
sábado 18 de febrero de 12
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/4941185476
sábado 18 de febrero de 12
Orientadas a Documento
Documentos formateados en JSON
sábado 18 de febrero de 12
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
El API
Consola y API JavaScript:
sábado 18 de febrero de 12
El API
Consola y API JavaScript:beleriand:bin dgomez$ ./mongoMongoDB shell version: 1.8.1connecting to: test>
sábado 18 de febrero de 12
El API
Consola y API JavaScript:beleriand:bin dgomez$ ./mongoMongoDB shell version: 1.8.1connecting to: test> > use vtsswitched to db vts>
sábado 18 de febrero de 12
El API
Consola y API JavaScript:beleriand:bin dgomez$ ./mongoMongoDB shell version: 1.8.1connecting to: test> > use vtsswitched to db vts>> show collectionsEventWeatherDatasystem.indexesvessel>
sábado 18 de febrero de 12
El API
Consola y API JavaScript:beleriand:bin dgomez$ ./mongoMongoDB shell version: 1.8.1connecting to: test> > use vtsswitched to db vts>> show collectionsEventWeatherDatasystem.indexesvessel>> 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
El API
Consola y API JavaScript:
sábado 18 de febrero de 12
El API
Consola y API JavaScript:> show collectionsEventWeatherDatasystem.indexesvessel>
sábado 18 de febrero de 12
El API
Consola y API JavaScript:> show collectionsEventWeatherDatasystem.indexesvessel> > db.alarms.save({"type" : "speed", "severity" : "warn", "vesselSSID" : "224000999"})>
sábado 18 de febrero de 12
El API
Consola y API JavaScript:> show collectionsEventWeatherDatasystem.indexesvessel> > db.alarms.save({"type" : "speed", "severity" : "warn", "vesselSSID" : "224000999"})>> show collectionsEventWeatherDataalarmssystem.indexesvessel>
sábado 18 de febrero de 12
El API
Consola y API JavaScript:> show collectionsEventWeatherDatasystem.indexesvessel> > db.alarms.save({"type" : "speed", "severity" : "warn", "vesselSSID" : "224000999"})>> show collectionsEventWeatherDataalarmssystem.indexesvessel>> db.alarms.find(){ "_id" : ObjectId("4f3acca3ed4cc8078fd1a4be"), "type" : "speed", "severity" : "warn", "vesselSSID" : "224000999" }>
sábado 18 de febrero de 12
Documentos
Identificados por un “_id” (generado o asignado)
Textual (JSON)
Binario (BSON)*
Documentos grandes divididos en chunks
sábado 18 de febrero de 12
Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
sábado 18 de febrero de 12
{ "_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.py
Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
sábado 18 de febrero de 12
{ "_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.py
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" }
Ruby
sábado 18 de febrero de 12
{ "_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.py
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" }
Ruby
array( "_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.php
sábado 18 de febrero de 12
{ "_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.py
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" }
Ruby
array( "_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.php
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());
sample.java
sábado 18 de febrero de 12
Cliente Java con MongoDB
‘a pelo’
sábado 18 de febrero de 12
1. Obtener el Driver
Importar el driver
sábado 18 de febrero de 12
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
2. Conexión
Obtener la referencia a la BD y la conexión
sábado 18 de febrero de 12
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
3. Inserciones
Crear e insertar un objeto
sábado 18 de febrero de 12
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
4. Consultas (I)
Obtener todos los documentos de una colección
sábado 18 de febrero de 12
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);}
4. Consultas (I)
Obtener todos los documentos de una colección
sábado 18 de febrero de 12
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);}
4. Consultas (I)
Obtener todos los documentos de una colección
public abstract class DBCollection {
public final DBCursor find(){ public final DBCursor find( DBObject ref ) public final DBCursor find( DBObject ref , DBObject keys )
public final DBObject findOne( Object obj ) public final DBObject findOne( Object obj, DBObject fields )
public DBObject findAndModify( DBObject query , DBObject update )
}
sábado 18 de febrero de 12
4. Consultas (II)
Consultas “SQL-like”
sábado 18 de febrero de 12
4. Consultas (II)
Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;
Las consultas se hacen también en JSON
sábado 18 de febrero de 12
4. Consultas (II)
Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;
{ “flag” : “ALBANIA” }
Las consultas se hacen también en JSON
sábado 18 de febrero de 12
4. Consultas (II)
Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;
{ “flag” : “ALBANIA” }
Las consultas se hacen también en JSON
beleriand:bin dgomez$ ./mongoMongoDB shell version: 1.8.1connecting to: test> use vtsswitched 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
4. Consultas (II)
Consultas “SQL-like” En RDBMS: SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;
{ “flag” : “ALBANIA” }
Las consultas se hacen también en JSON
beleriand:bin dgomez$ ./mongoMongoDB shell version: 1.8.1connecting to: test> use vtsswitched 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" }>
DBObject query = new BasicDBObject();query.put("flag", "ALBANIA"); DBCursor albanianShips = vessels.find(query);while (albanianShips.hasNext()) { // ...}
sábado 18 de febrero de 12
Operadores de consulta
Otros operadores
sábado 18 de febrero de 12
Operadores de consulta
Otros operadores
$all$and$exists$gt$in$lt$mod$ne$nin$nor$or$size$type
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
RDBMS:
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30AND (flag = “ALBANIA” or flag = ”SAN MARINO”);RDBMS:
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30AND (flag = “ALBANIA” or flag = ”SAN MARINO”);
{ “length” : { $lt : 90, $gt : 30}, $or : [ { “flag” : “ALBANIA”}, { “flag” : “SAN MARINO”} ]}
RDBMS:
Mongo:
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30AND (flag = “ALBANIA” or flag = ”SAN MARINO”);
{ “length” : { $lt : 90, $gt : 30}, $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 = {new BasicDBObject("flag", "ALBANIA"), new BasicDBObject("flag", "SAN MARINO")
};query.put("$or", flags);
talks.find(query);
RDBMS:
Mongo:
Mongo
Driver:
sábado 18 de febrero de 12
DBObjects desde JSON
com.mongo.util.JSON
sábado 18 de febrero de 12
DBObjects desde JSON
Object query = JSON.parse("{ 'length' : { $lt : 90, $gt : 30}, " + " '$or' : [ { 'flag' : 'ALBANIA}, " + " { 'flag' : 'SAN MARINO'} ] }");
DBCursor cursor = db.find((DBObject) query);
com.mongo.util.JSON
sábado 18 de febrero de 12
Además...
Gestión de excepciones
Gestión recursos
DB, Collección, Cursores, DBObjects...
Transformaciones Objeto JSON
sábado 18 de febrero de 12
Spring Data MongoDB
sábado 18 de febrero de 12
Spring DataObjetivo:
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, Cassandra
sábado 18 de febrero de 12
Spring Data y MongoDB
XML namespace para configurar driver Mongo
MongoTemplate
Conversión de excepciones automática
Conversión Configurable
JMX monitoring
sábado 18 de febrero de 12
Importando Spring Data
sábado 18 de febrero de 12
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
Namespace
sábado 18 de febrero de 12
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
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>
<mongo:db-‐factory dbname="vts"/>
sábado 18 de febrero de 12
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>
<mongo:db-‐factory dbname="vts"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-‐arg name="mongoDbFactory" ref="mongoDbFactory" /> </bean>
sábado 18 de febrero de 12
MongoTemplate
Identifica la colección
Convierte query a JSON
Convierte respuesta (“_class”)
Gestiona las conexiones y cursores
Convierte las excepciones
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-‐arg name="mongoDbFactory" ref="mongoDbFactory" /></bean>
sábado 18 de febrero de 12
MongoTemplate - Consultas
sábado 18 de febrero de 12
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
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
Consultas
Consultas “SQL-like”
SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”; RDBMS:
sábado 18 de febrero de 12
Consultas
Consultas “SQL-like”
SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;
{ “flag” : “ALBANIA” }
Las consultas se hacen también en JSON
RDBMS:
Mongo:
sábado 18 de febrero de 12
Consultas
Consultas “SQL-like”
SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;
{ “flag” : “ALBANIA” }
Las consultas se hacen también en JSON
DBCollection vessels = db.getCollection("vessel");
DBObject query = new BasicDBObject();query.put("flag", "ALBANIA"); DBCursor albanianShips = vessels.find(query);while (albanianShips.hasNext()) { DBObject result = albanianShips.next(); // Create Vessel object from DBObject}
RDBMS:
Mongo:
Mongo
Driver:
sábado 18 de febrero de 12
Consultas
Consultas “SQL-like”
SELECT * FROM VESSEL WHERE FLAG = “ALBANIA”;
{ “flag” : “ALBANIA” }
Las consultas se hacen también en JSON
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 JSON
RDBMS:
Mongo:
sábado 18 de febrero de 12
Serialización automática
sábado 18 de febrero de 12
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
Consultas complejasConcatenación de consultas
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30ORDER BY lastUpdate;
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30ORDER BY lastUpdate;
{ “length” : { $lt : 90, $gt : 30}}
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30ORDER 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
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30ORDER BY lastUpdate;
{ “length” : { $lt : 90, $gt : 30}}
sábado 18 de febrero de 12
Consultas complejasConcatenación de consultas
SELECT * FROM VESSELS WHERE length < 90 AND length > 30ORDER 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
MongoTemplate - inserciones
sábado 18 de febrero de 12
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
AbstractRepository
sábado 18 de febrero de 12
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
AbstractRepository
sábado 18 de febrero de 12
AbstractRepositorypublic 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
VesselRepository
sábado 18 de febrero de 12
VesselRepository
public class VesselRepository extends AbstractMongoRepository<Vessel> {
public VesselRepository() { super(Vessel.class); }
}
sábado 18 de febrero de 12
A tener en cuenta
sábado 18 de febrero de 12
El caso de BitSet
Cuidado con los campos transient
sábado 18 de febrero de 12
El caso de BitSet
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; } }}
Cuidado con los campos transient
sábado 18 de febrero de 12
Conversión Manual
sábado 18 de febrero de 12
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
Conversión ManualPorque a veces lo automático no funciona
sábado 18 de febrero de 12
Conversión ManualPorque 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
Queries con multiples valores
sábado 18 de febrero de 12
Queries con multiples valores
Query query = new Query( Criteria .where("length").gte(20) .and("length").lt(60));
sábado 18 de febrero de 12
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
Queries con multiples valores
sábado 18 de febrero de 12
Queries con multiples valores
Query query = new Query( Criteria .where("length").gte(20).lte(60));
sábado 18 de febrero de 12
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
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 consola
sábado 18 de febrero de 12
Q&A
David Gómez@dgomezg
sábado 18 de febrero de 12