9. Motivaciones
Aplicaciones web ultra-escalables
Gran cantidad de datos
Velocidad de guardado
Alto número de peticiones
Máxima disponibilidad
6
miércoles 25 de enero de 12
10. Características
Replicado (particionado horizontal)
Sin esquemas (versatibilidad, adaptabilidad)
BASE (not ACID)
7
miércoles 25 de enero de 12
11. Características: BASE vs ACID
Atomicity, Consistency, Isolation, Durability
Basically Available, Soft state, Eventual consistency
8
(cc) Photo by zhouxuan12345678 - http://www.flickr.com/photos/53921113@N02/5645102295/
miércoles 25 de enero de 12
12. Tipos
orientadas a Columna orientadas a Documento
Key-value orientadas a Grafos
9
miércoles 25 de enero de 12
13. Orientadas a columna
10
(cc) Photo by profzuckerk - http://www.flickr.com/photos/profzucker/4630958694
miércoles 25 de enero de 12
14. Orientadas a columna
Configuración individual de columnas por fila
10
(cc) Photo by profzuckerk - http://www.flickr.com/photos/profzucker/4630958694
miércoles 25 de enero de 12
15. Orientadas a columna
Configuración individual de columnas por fila
También conocidas como BigTable (google paper)
11
(cc) Photo by Ash Brian - http://www.flickr.com/photos/ashbrian/2977673855
miércoles 25 de enero de 12
16. Orientadas a columna
Configuración individual de columnas por fila
También conocidas como BigTable (google paper)
Tamaño
Alta carga de escrituras
Disponibilidad
MapReduce
11
(cc) Photo by Ash Brian - http://www.flickr.com/photos/ashbrian/2977673855
miércoles 25 de enero de 12
17. Orientadas a columna
Configuración individual de columnas por fila
También conocidas como BigTable (google paper)
Tamaño
Alta carga de escrituras
Disponibilidad
MapReduce
11
(cc) Photo by Ash Brian - http://www.flickr.com/photos/ashbrian/2977673855
miércoles 25 de enero de 12
18. Orientadas a Documento
El documento es lo que importa
Almacenados en Colecciones
(bajo una clave)
Los documentos pueden ser heterogéneos
Formatos textuales: XML,YAML, JSON & BSON
Formatos binarios: P ej: PDFs
12
(cc) Photo by Ampersand Duck - http://www.flickr.com/photos/ampersandduck/4941185476
miércoles 25 de enero de 12
19. Orientadas a Documento
El documento es lo que importa
Almacenados en Colecciones
(bajo una clave)
Los documentos pueden ser heterogéneos
Formatos textuales: XML,YAML, JSON & BSON
Formatos binarios: P ej: PDFs
12
(cc) Photo by Ampersand Duck - http://www.flickr.com/photos/ampersandduck/4941185476
miércoles 25 de enero de 12
20. Key-Value
Basadas en:
Dynamo (paper de Amazon)
y Tablas Hash distribuidas
Colleción de pares clave-valor
Almacenados de forma distribuida
Útiles con:
muchas escrituras y lecturas
pequeñas. 13
miércoles 25 de enero de 12
21. Key-Value
Basadas en:
Dynamo (paper de Amazon)
y Tablas Hash distribuidas
Colleción de pares clave-valor
Almacenados de forma distribuida
Útiles con:
muchas escrituras y lecturas
pequeñas. 13
miércoles 25 de enero de 12
22. Orientadas a Grafos
Almacenan:
Nodos y relaciones
Ambos pueden contener pares
clave-valor
Muy rápidos para consultas con
operaciones sobre el gráfo
(p. Ej: personas con un grado de afinidad 3)
14
miércoles 25 de enero de 12
23. Orientadas a Grafos
Almacenan:
Nodos y relaciones
Ambos pueden contener pares
clave-valor
Muy rápidos para consultas con
operaciones sobre el gráfo
(p. Ej: personas con un grado de afinidad 3)
14
miércoles 25 de enero de 12
24. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
25. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency
C
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
26. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
C A
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
27. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
C A
P
Partition Tolerance
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
28. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
C A
P
Partition Tolerance
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
29. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
C A
Sólo
2
P
Partition Tolerance
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
30. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
A
Oracle, MySQL,
C
Sólo
2
P
Partition Tolerance
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
31. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
A
Oracle, MySQL,
C
Sólo
M H yp i s,
on e M
2
go rTa em
Re
DB ble ca
d
, D , H che
at Ba DB
aS s
to e
re
P
,
Partition Tolerance
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
32. ¿Cuándo utilizar NoSQL?
Teorema CAP (Eric Brewer)
Consistency Availability
A
Oracle, MySQL,
C
Sólo
M H yp i s,
hD , rt,
on e M
aK
2
uc ra o
go rTa em
Co and dem
Re
Ri
DB ble ca
d
B,
B, ss ol
, D , H che
eD a , V
at Ba DB
pl C mo
aS s
na
to e
Dy
re
P
,
m
RDBMS
Si Orientadas a documento
Partition Tolerance orientadas a columna
Key-Value
15
Source: Nathan Hurst’s Blog
miércoles 25 de enero de 12
34. MongoDB
Escrita en C++
Orientada a documento
Formato JSON (o BSON)
Un poco SQL (queries, índices, Referencias
externas)
Particionado horizontal (sharding)
Consultas Javascript
Almacenamiento en GridFS
17
miércoles 25 de enero de 12
36. Orientadas a Documento
Documentos formateados en JSON
{
"_id" : {
"$oid" : "4f13f2b98de23dc3d58f959a"
},
"name" : "NoSQL y MongoDB",
"presenter" : "David Gomez",
"Event" : "decharlas",
"duration" : 60,
"timing" : {
"start" : 17,
"end" : 19
}
}
18
miércoles 25 de enero de 12
37. Consultas
Utilizando un API y funciones JavaScript
19
miércoles 25 de enero de 12
38. Consultas
Utilizando un API y funciones JavaScript
beleriand:bin dgomez$ ./mongo
MongoDB shell version: 1.8.1
connecting to: test
>
19
miércoles 25 de enero de 12
39. Consultas
Utilizando un API y funciones JavaScript
beleriand:bin dgomez$ ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> use playground
switched to db playground
>
19
miércoles 25 de enero de 12
40. Consultas
Utilizando un API y funciones JavaScript
beleriand:bin dgomez$ ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> use playground
switched to db playground
> db.talks.insert({'name' : 'codemotion', 'presenter' : 'David Gomez', 'Event' :
'decharlas' });
>
19
miércoles 25 de enero de 12
41. Consultas
Utilizando un API y funciones JavaScript
beleriand:bin dgomez$ ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> use playground
switched to db playground
> db.talks.insert({'name' : 'codemotion', 'presenter' : 'David Gomez', 'Event' :
'decharlas' });
> db.talks.find();
{ "_id" : ObjectId("4f13f7e5a00e6496e7a9541b"), "name" : "codemotion", "presenter" :
"David Gomez", "Event" : "decharlas" }
>
19
miércoles 25 de enero de 12
42. Colecciones
Equivalente a la tabla
Guardan documentos
No todos iguales
Pueden definir índices sobre atributos
Creadas con la primera inserción
Persistidas sobre un GridFS
20
miércoles 25 de enero de 12
43. Documentos
Identificados por un “_id” (generado o asignado)
Textual (JSON)
Binario (BSON)*
Documentos grandes divididos en chunks
21
miércoles 25 de enero de 12
44. Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
22
miércoles 25 de enero de 12
45. Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
{
"name" : "NoSQL y MongoDB",
"presenter" : "David Gomez",
"Event" : "decharlas",
"duration" : 60,
"timing" : {
"start" : 17,
"end" : 19
}
}
sample.py
22
miércoles 25 de enero de 12
46. Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
{ {
"name" : "NoSQL y MongoDB", y MongoDB",
"name" => "NoSQL
"presenter" : "David Gomez",
"presenter" => "David Gomez",
"Event" : "decharlas",
"Event" => "decharlas",
"duration" "duration" => 60,
: 60,
"timing" : "timing" => {
{
"start" : 17,
"start" => 17,
"end" : 19 "end" => 19
} }
} }
sample.py Ruby
22
miércoles 25 de enero de 12
47. Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
{ {
array( "name" => "NoSQL y MongoDB",
"name" : "NoSQL y MongoDB", y MongoDB",
"name" => "NoSQL
"presenter" => "David Gomez",
"presenter" : "David Gomez",
"presenter" => "David Gomez",
"Event" => "decharlas",
"Event" : "decharlas",
"Event" => "decharlas",
"duration" => 60,
"duration" "duration" => 60,
: 60,
"timing" => array(
"timing" : "timing" => {
{
"start" => 17,
"start" : 17,
"start" => 17,
"end" => 19
"end" : 19 "end" => 19
)
} }
}
} }
sample.php
sample.py Ruby
22
miércoles 25 de enero de 12
48. Programación de clientes
Multitud de lenguajes (drivers)
Transformación a JSON realizada por el driver
BasicDBObject doc = new BasicDBObject();
{ {
array( "name" => "NoSQL y MongoDB", y MongoDB");
doc.put("name", "NoSQL
"name" : "NoSQL y MongoDB", y MongoDB",
"name" => "NoSQL
"presenter" => "David Gomez", "David Gomez");
doc.put("presenter",
"presenter" : "David Gomez",
"presenter" => "David Gomez",
"Event" => "decharlas",
doc.put("Event", "decharlas");
"Event" : "decharlas",
"Event" => "decharlas",
doc.put("duration", 60);
"duration" => 60,
"duration" "duration" => 60,
: 60,
"timing" => array(
"timing" : "timing" => {
{
BasicDBObject timing = new BasicDBObject();
"start" => 17,
"start" : 17,
"start" => 17,
"end"timing.put("start", 17);
=> 19
"end" : 19 "end" => 19
) timing.put("end", 19);
} }
} doc.put("timing", timing);
} }
sample.php
sample.py Ruby
sample.java
22
miércoles 25 de enero de 12
49. 1. Obtener el Driver
Importar el driver
23
miércoles 25 de enero 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>
23
miércoles 25 de enero de 12
51. 1. Obtener el Driver
Importar el driver
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</
artifactId>
<version>2.7.0-rc1</version>
</dependency>
23
miércoles 25 de enero de 12
52. 2. Conexión
Obtener la referencia a la BD y la conexión
24
miércoles 25 de enero de 12
53. 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" );
24
miércoles 25 de enero de 12
54. 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" );
Sobre la BD se puede:
24
miércoles 25 de enero de 12
55. 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" );
Sobre la BD se puede:
Boolean authorized = db.authenticate(user, passwd);
if (db.collectionExists("talks")) {
CommandResult cmdResult =
db.command("{ collStats:"db.talks" , scale :
1 }");
}
Set<String> colls = db.getCollectionNames();
for (String s : colls) {
System.out.println(s);
}
24
miércoles 25 de enero de 12
56. 3. Inserciones
Crear e insertar un objeto
25
miércoles 25 de enero de 12
57. 3. Inserciones
Crear e insertar un objeto
BasicDBObject doc = new BasicDBObject();
doc.put("name", "NoSQL y MongoDB");
doc.put("presenter", "David Gomez");
doc.put("Event", "decharlas");
doc.put("duration", 60);
BasicDBObject timing = new BasicDBObject();
timing.put("start", 17);
timing.put("end", 19);
doc.put("timing", timing);
DBCollection coll = db.getCollection("talks");
coll.insert(doc);
25
miércoles 25 de enero de 12
58. 4. Consultas (I)
Obtener todos los documentos de una colección
26
miércoles 25 de enero de 12
59. 4. Consultas (I)
Obtener todos los documentos de una colección
DBCollection talks = db.getCollection("talks");
DBCursor cursor = talks.find();
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
26
miércoles 25 de enero de 12
60. 4. Consultas (I)
Obtener todos los documentos de una colección
DBCollection talks = db.getCollection("talks");
DBCursor cursor = talks.find();
public abstract class DBCollection {
while (cursor.hasNext()) {
public final DBCursor find(){
System.out.println(cursor.next());
} 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 )
}
26
miércoles 25 de enero de 12
61. 4. Consultas (II)
Consultas “SQL-like”
27
miércoles 25 de enero de 12
62. 4. Consultas (II)
Consultas “SQL-like”
SELECT * FROM TALKS WHERE PRESENTER = “David Gomez”;
Las consultas se hacen con Documentos JSON
27
miércoles 25 de enero de 12
63. 4. Consultas (II)
Consultas “SQL-like”
SELECT * FROM TALKS WHERE PRESENTER = “David Gomez”;
Las consultas se hacen con Documentos JSON
{ “presenter” : “David Gomez” }
27
miércoles 25 de enero de 12
64. 4. Consultas (II)
Consultas “SQL-like”
SELECT * FROM TALKS WHERE PRESENTER = “David Gomez”;
Las consultas se hacen con Documentos JSON
{ “presenter” : “David Gomez” }
beleriand:bin dgomez$ ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> use playground
switched to db playground
> db.talks.find( { "presenter" : "David Gomez" });
{ "_id" : ObjectId("4f13f7e5a00e6496e7a9541b"), "name" : "codemotion",
"presenter" : "David Gomez", "Event" : "decharlas" }
>
27
miércoles 25 de enero de 12
65. 4. Consultas (II)
Consultas “SQL-like”
SELECT * FROM TALKS WHERE PRESENTER = “David Gomez”;
Las consultas se hacen con Documentos JSON
{ “presenter” : “David Gomez” }
beleriand:bin dgomez$ ./mongo
MongoDB shell version: 1.8.1
DBObject query = new BasicDBObject();
connecting to: test
query.put("presenter", "David Gomez");
> use playground
switched to db playground
DBCursor davidTalks = talks.find(query);
> db.talks.find( { "presenter" : "David Gomez" });
while (davidTalks.hasNext()) {
{ "_id" : ObjectId("4f13f7e5a00e6496e7a9541b"), "name" : "codemotion",
System.out.println(davidTalks.next());
"presenter" : "David Gomez", "Event" : "decharlas" }
}
>
}
27
miércoles 25 de enero de 12
66. 4. Consultas (III)
Comparadores <, <=, >=, >, !=
28
miércoles 25 de enero de 12
67. 4. Consultas (III)
Comparadores <, <=, >=, >, !=
SELECT * FROM TALKS WHERE duration < 60;
28
miércoles 25 de enero de 12
70. 4. Consultas (III)
Comparadores <, <=, >=, >, !=
SELECT * FROM TALKS WHERE duration < 60;
{ “duration” : { $lt : 60} }
{ “duration” : { $lte : 60} }
{ “duration” : { $gt : 60} }
{ “duration” : { $gte : 60} }
{ “duration” : { $ne : 60} }
beleriand:bin dgomez$ ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> use playground
switched to db playground DBObject query = new BasicDBObject();
query.put("duration", new BasicDBObject("$lt","90"));
> > db.talks.find({"duration" : { $lt : 90 } })
{ "_id" : ObjectId("4f1402f28de2930293c7cf8e"), "name" : "NoSQL y MongoDB",
"presenter" : "David Gomez", DBCursor :shortTalks = talks.find(query);
"Event" "decharlas", "duration" : 60, "timing" :
{ "start" : 17, "end" : 19 } while (shortTalks.hasNext()) {
}
> System.out.println(shortTalks.next());
}
28
miércoles 25 de enero de 12
71. 4. Consultas (IV)
Concatenación de consultas
29
miércoles 25 de enero de 12
72. 4. Consultas (IV)
Concatenación de consultas
SELECT * FROM TALKS WHERE duration < 90 AND duration > 30;
29
miércoles 25 de enero de 12
73. 4. Consultas (IV)
Concatenación de consultas
SELECT * FROM TALKS WHERE duration < 90 AND duration > 30;
{
“duration” : { $lt : 90, $gt : 60} }
}
29
miércoles 25 de enero de 12
74. 4. Consultas (IV)
Concatenación de consultas
SELECT * FROM TALKS WHERE duration < 90 AND duration > 30;
{
“duration” : { $lt : 90, $gt : 60} }
}
DBObject query = new BasicDBObject();
DBObject condition = new BasicDBObject("$lt", 90);
condition.put("$gt",30);
query.put("duration", condition);
DBCursor shortTalks = talks.find(query);
while (shortTalks.hasNext()) {
System.out.println(shortTalks.next());
}
29
miércoles 25 de enero de 12
75. 4. Consultas (V)
Otros operadores
30
miércoles 25 de enero de 12
76. 4. Consultas (V)
Otros operadores
$all
$exists
$mod
$ne
$in
$nin
$nor
$or
$and
$size
$type
30
miércoles 25 de enero de 12
77. 4. Consultas (y VI)
Concatenación de consultas
31
miércoles 25 de enero de 12
78. 4. Consultas (y VI)
Concatenación de consultas
SELECT * FROM TALKS WHERE duration < 90 AND duration > 30
AND (presenter = “David Gomez” or presenter=”Ricardo Borillo”);
31
miércoles 25 de enero de 12
79. 4. Consultas (y VI)
Concatenación de consultas
SELECT * FROM TALKS WHERE duration < 90 AND duration > 30
AND (presenter = “David Gomez” or presenter=”Ricardo Borillo”);
{
“duration” : { $lt : 90, $gt : 60},
$or : [
{ “presenter” : “David Gomez”},
{ “presenter” : “Ricardo Borillo”} ]
}
31
miércoles 25 de enero de 12
80. 4. Consultas (y VI)
Concatenación de consultas
SELECT * FROM TALKS WHERE duration < 90 AND duration > 30
AND (presenter = “David Gomez” or presenter=”Ricardo Borillo”);
{
“duration” : { $lt : 90, $gt : 60},
$or : [
{ “presenter” : “David Gomez”},
{ “presenter” : “Ricardo Borillo”} ]
}
DBObject query = new BasicDBObject();
DBObject condition = new BasicDBObject("$lt",90);
condition.put("$gt",30);
query.put("duration", condition);
DBObject [] speakerCond = {
new BasicDBObject("presenter", "David Gomez"),
new BasicDBObject("presenter", "Ricardo Borillo")
};
query.put("$or", speakerCond);
31
talks.find(query);
miércoles 25 de enero de 12
84. Spring Data
Objetivo:
- Proporcionar un mecanismo homogeneo y
completo para el acceso a BD NoSQL
Multiples proyectos:
- Soportados:
‣ MongoDB, Redis, Neo4j, Hadoop, GemFire, RiaK
- En proceso:
‣ CouchDB, Hbase, Cassandra
34
miércoles 25 de enero de 12
85. Spring Data y MongoDB
XML namespace para configurar driver Mongo
MongoTemplate
Conversión automática de excepciones
OXM Configurable
JMX monitoring
35
miércoles 25 de enero de 12
87. Importando Spring Data
<repository>
<id>spring-milestone</id>
<name>Spring Maven MILESTONE Repository</name>
<url>http://maven.springframework.org/milestone</url>
</repository>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.0.0.RC1</version>
</dependency>
36
miércoles 25 de enero de 12
92. MongoTemplate
<bean
id="mongoTemplate"
class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-‐arg
name="mongoDbFactory"
ref="mongoDbFactory"
/>
</bean>
Convierte query a JSON
Convierte respuesta (“_type”)
Gestiona las conexiones
Maneja las excepciones
38
miércoles 25 de enero de 12
94. Repository
public
abstract
class
AbstractRepository<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
List<T>
findAll(){
return
mongoTemplate.findAll(persistentClass);
}
public
void
save(T
e)
{
mongoTemplate.save(e);
}
public
T
findById(String
id)
{
T
t
=
mongoTemplate.findById(id,
persistentClass);
if
(t
==
null)
{
logger.debug(persistentClass.getSimpleName()
+
"
with
id
"
+
id
+
"
could
not
be
found");
throw
new
ObjectNotFoundException(persistentClass,
id);
}
return
t;
}
}
39
miércoles 25 de enero de 12
96. Consultas más sencillas
public
abstract
class
AbstractRepository<T>
{
public
List<T>
getByType(String
type)
{
return
mongoTemplate.find(
new
Query(Criteria.where("type").is(type)),
T.class,
persistentClass);
}
}
40
miércoles 25 de enero de 12
97. Conversión Manual
Porque a veces lo automático no funciona
41
miércoles 25 de enero de 12
98. Conversión Manual
Porque a veces lo automático no funciona
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;
}
}
41
miércoles 25 de enero de 12
99. Conversión Manual
Porque a veces lo automático no funciona
42
miércoles 25 de enero de 12
100. 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>
42
miércoles 25 de enero de 12
101. Conclusiones
Reducción del número de tablas
Optimización en el rendimiento de escrituras
Simplificación de los DAOs con Spring-Data
Otras ventajas:
Documentos en formato de Respuesta REST
43
miércoles 25 de enero de 12