Прежде чем мы начнем, пожалуйста, скачайте и запустите 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.0mongodbcom.example.spring0.0.1-SNAPSHOTjar 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;@Servicepublic 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;@Servicepublic 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 Андрея Редько в блоге Андрея Редько .