Прежде чем мы начнем, пожалуйста, скачайте и запустите MongoDB для вашей операционной системы. Это очень просто, поэтому я не буду тратить время на это, и давайте начнем с простого файла POM для нашего проекта:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
4.0.0 mongodb com.example.spring 0.0.1-SNAPSHOT jar UTF-8 3.0.5.RELEASE org.springframework.data spring-data-mongodb 1.0.0.M3 log4j log4j 1.2.16 org.mongodb mongo-java-driver 2.5.3 org.springframework spring-core ${spring.version} org.springframework spring-context ${spring.version} springsource-milestone Spring Framework Milestone Repository |
Здесь есть две ключевые зависимости:
— MongoDB Java-драйвер
— Spring Data для MongoDB
Есть несколько способов определить MongoDB в контексте приложения Spring . Позвольте мне показать немного многословно, но более гибко:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
< beans xmlns:context = "http://www.springframework.org/schema/context" xmlns:mongo = "http://www.springframework.org/schema/data/mongo" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.springframework.org/schema/beans" xsi:schemalocation=" < constructor-arg index = "0" ref = "mongo" /> < constructor-arg index = "1" value = "elements-db" /> < constructor-arg name = "mongoDbFactory" ref = "mongoDbFactory" /> < constructor-arg name = "mappingContext" ref = "mappingContext" /> < constructor-arg name = "mongoDbFactory" ref = "mongoDbFactory" /> < constructor-arg name = "mongoConverter" ref = "converter" /> < property name = "writeResultChecking" value = "EXCEPTION" /> < property name = "writeConcern" value = "NORMAL" /> |
Роль каждого боба здесь:
- Монго определяет соединение с базой данных MongoDB (мы используем настройки по умолчанию, порт 27027)
- конвертер используется для преобразования классов Java в / из DBObject MongoDB (== JSON)
- mongoTemplate предоставляет операции, которые мы можем выполнять над MongoDB
Итак, мы готовы к работе!
Вот несколько фрагментов кода для начала:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package com.example.mongodb; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.document.mongodb.CollectionCallback; import org.springframework.data.document.mongodb.MongoOperations; import org.springframework.data.document.mongodb.query.Index; import org.springframework.data.document.mongodb.query.Index.Duplicates; import org.springframework.data.document.mongodb.query.Order; import org.springframework.stereotype.Service; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.MongoException; @Service public class MongoService { @Autowired private MongoOperations template; public void createCollection( final String name ) { template.createCollection( name ); } public void dropCollection( final String name ) { template.dropCollection( name ); } public void insert( final Object object, final String collection ) { template.insert( object, collection ); } public void createIndex( final String name, final String collection ) { template.ensureIndex( new Index() .on( name, Order.DESCENDING ) .unique( Duplicates.DROP ), collection ); } // Remove / save / ... operations here } |
Вот и все с основами. В следующем посте будут рассмотрены расширенные функции: использование массовых вставок, операции обновления или вставки и выполнение команд MongoDB . 🙂
После обсуждения проектов MongoDB и Spring Data я хотел бы показать некоторые расширенные функции (которые могут быть доступны в следующем выпуске Spring Data или выпуске как часть основных функций).
Прежде всего, давайте расширим наш MongoService с помощью метода, который подсчитывает документы в коллекции, которые соответствуют конкретному запросу.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package com.example.mongodb; import java.util.Arrays; import java.util.Collection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.document.mongodb.CollectionCallback; import org.springframework.data.document.mongodb.MongoOperations; import org.springframework.data.document.mongodb.convert.MongoConverter; import org.springframework.data.document.mongodb.query.Criteria; import org.springframework.data.document.mongodb.query.Index; import org.springframework.data.document.mongodb.query.Index.Duplicates; import org.springframework.data.document.mongodb.query.Order; import org.springframework.data.document.mongodb.query.Query; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.MongoException; @Service public class MongoService { public long countDocuments( final String collection, final Query query ) { return template.executeCommand( "{ " + "\"count\" : \"" + collection + "\"," + "\"query\" : " + query.getQueryObject().toString() + " }" ).getLong( "n" ); } } |
Подход для этой конкретной функции состоит в том, чтобы вызвать собственный счетчик команд MongoDB, передавая запрос в качестве параметра. Возвращающая структура содержит количество документов в n свойстве.
Или, более дружественным к коду способом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
import org.springframework.dao.DataAccessException; import org.springframework.data.document.mongodb.CollectionCallback; import com.mongodb.DBCollection; import com.mongodb.MongoException; public long countDocuments( final String collection, final Query query ) { return template.execute( collection, new CollectionCallback< Long >() { @Override public Long doInCollection( DBCollection collection ) throws MongoException, DataAccessException { return collection.count( q.getQueryObject() ) ); } } ); } |
Следующая полезная функция — массовые вставки. Обратите внимание, что в текущей версии MongoDB 1.8.1, когда в коллекции вставок документов есть дубликат, массовая вставка останавливается на первом дубликате и возвращается, поэтому все остальные документы не будут вставлены . Будьте в курсе такого поведения. Прежде чем перейти к фрагменту кода, позвольте мне представить простой класс SimpleDocument, который мы будем сохранять в MongoDB :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package com.example.mongodb; import org.springframework.data.document.mongodb.mapping.Document; @Document ( collection = "documents" ) public class SimpleDocument { private String id; private String name; private String content; public SimpleDocument() { } public SimpleDocument( final String id, final String name ) { this .id = id; this .name = name; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getId() { return id; } public void setId(String id) { this .id = id; } public String getContent() { return content; } public void setContent(String content) { this .content = content; } } |
Следующий метод вставляет все документы как единое массовое обновление:
1
2
3
|
public void insert( final Collection< SimpleDocument > documents ) { template.insert( documents, SimpleDocument. class ); } |
Еще одна очень полезная и полезная функция для изучения — upserts MongoDB (подробнее об этом здесь http://www.mongodb.org/display/DOCS/Updating): если документ, соответствующий определенным критериям, существует, он будет обновлен, в противном случае — новый документ будет быть вставленным в коллекцию. Ниже приведен код, демонстрируемый с помощью следующего варианта использования: если SimpleDocument с таким именем существует, он будет обновлен, в противном случае новый документ будет добавлен в коллекцию:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Autowired private MongoConverter converter; public void insertOrUpdate( final SimpleDocument document ) { final BasicDBObject dbDoc = new BasicDBObject(); converter.write( document, dbDoc ); template.execute( SimpleDocument. class , new CollectionCallback< Object >() { public Object doInCollection( DBCollection collection ) throws MongoException, DataAccessException { collection.update( new Query() .addCriteria( new Criteria( "name" ).is( document.getName() ) ) .getQueryObject(), dbDoc, true , false ); return null ; } } ); } |
Обратите внимание на использование bean-компонента converter, который помогает конвертировать Java-класс в DBObject MongoDB .
Последнее, что я хотел бы показать, это операция findAndModify, которая делает несколько вещей в виде одной атомарной последовательности:
— найти критерии соответствия документа
— выполнить обновление
— вернуть обновленный документ (или старый, в зависимости от ваших потребностей)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
public void findAndModify( final Query query, final Update update ) { return template.execute( SimpleDocument. class , new CollectionCallback< SimpleDocument >() { @Override public SimpleDocument doInCollection( DBCollection collection ) throws MongoException, DataAccessException { return converter.read( SimpleDocument. class , collection.findAndModify( query.getQueryObject(), null , null , false , update.getUpdateObject(), true , false ) ); } } ); } |
Пока это все интересные случаи использования, с которыми я столкнулся. Честно говоря, я очень рад MongoDB и настоятельно рекомендую его, если он подходит для вашего приложения.
Справка: Использование MongoDB вместе с проектом Spring Data: основные понятия и Использование MongoDB вместе с проектом Spring Data: передовые концепции от нашего партнера по JCG Андрея Редько в блоге Андрея Редько .