El documento habla sobre el uso de Spring Data y MongoDB en un proyecto real de control de tráfico marítimo. El proyecto enfrentaba desafíos de escalabilidad debido a la gran cantidad de datos generados por cada barco monitoreado. Se eligió MongoDB por su capacidad para escalar horizontalmente y su soporte para formatos de documentos como JSON. Spring Data facilita el desarrollo de aplicaciones que se integran con MongoDB mediante una interfaz de programación familiar.
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óricos
sá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
14. ¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
15. ¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
Consistency
C
Source: Nathan Hurst’s Blog
sábado 18 de febrero de 12
16. ¿Por qué NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
C A
Source: Nathan Hurst’s Blog
sá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 Blog
sá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 Blog
sá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 Blog
sá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 Blog
sá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 Blog
sá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 Blog
sábado 18 de febrero de 12
23. Pero... ¿NoSQL?
(cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150
sábado 18 de febrero de 12
24. Pero... ¿NoSQL?
(cc) Photo by mwin - http://www.flickr.com/photos/wingler/3429634150
sá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/3429634150
sá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 Grafos
sá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/4941185476
sá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/4941185476
sá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
chunks
sábado 18 de febrero de 12
43. Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
sá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.py
sá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 Ruby
sá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
Ruby
sá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.java
sábado 18 de febrero de 12
49. 1. Obtener el Driver
Importar el driver
sá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ón
sá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 objeto
sá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ón
sá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
59. 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
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
64. 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
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
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, Cassandra
sá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 monitoring
sá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
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 excepciones
sá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 JSON
sá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
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
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
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
104. VesselRepository
public class VesselRepository extends AbstractMongoRepository<Vessel> {
public VesselRepository() {
super(Vessel.class);
}
}
sábado 18 de febrero de 12
106. El caso de BitSet
Cuidado con los campos transient
sá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
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 funciona
sá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
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 consola
sábado 18 de febrero de 12
119. Q&A
David Gómez
@dgomezg
sábado 18 de febrero de 12