簡介
通過Spring我們可以很方便的使用非關係型數據庫-MongoDB,包括增、刪、查、改等操作。爲實現整個操作,我們首先在Windows環境上搭建MongoDB,具體安裝過程可參考Windows環境安裝MongoDB 。
host: localhost
port:27017
訪問MongoDB
通過Spring訪問搭建好的mongodb,以Repository爲例,主要有幾個步驟
- 加載依賴
- Document定義
- Repository接口定義
- MongoDbFactory和MongoTemplate定義
- 啓用MongoDB
加載依賴
我們選擇springboot提供的mongo依賴,這個依賴比較全面,我們以gradle爲例,更新build.gradle文件。
dependencies {
// 其他依賴
...
// mongodb依賴
compile("org.springframework.boot:spring-boot-starter-data-mongodb:1.2.5.RELEASE")
}
Document定義
MongoDB屬於非關係型數據庫,每張數據表中存儲的記錄爲一個Document,對Document的數據類型並不進行強制限制。
Document定義是一條記錄中包含的字段信息,有以下幾點說明:
- @Document註解,定義一個Document,可指定collection名字,即MongoDB中存儲的數據表的名稱,默認是class的名字。
- @Id註解,標識Document的ID
- @Field註解,自定義數據表存儲的字段名稱,默認是變量的名稱
- @Indexed註解,索引標識,unique=true表示爲唯一索引
package com.notepad.springnote.nosql.mongo.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
/**
* Description: 實體定義
* <p>
* Create: 2018/12/2 14:45
*
* @author Marvin Yang
*/
@Document(collection = "entity")
public class Entity {
@Id
private String id;
@Indexed(unique = true)
@Field("name")
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Repository接口定義
利用MongoRepository接口實現Document Repository接口的定義。我們這裏只是定義了一個接口,Repository機制會自動構建一個默認的實現類,當然MongoRepository中實現的都是一些基本的方法,如:
- save(S entity) 存儲一條記錄, 可用於數據的插入和更新操作
- save(Iterable<S> entities) 存儲多條記錄
- insert(S entity) 存儲一條記錄,前提是記錄在數據表中不存在
- findOne(ID id) 根據id查詢一條記錄
- fiindAll() 查詢全部記錄
- count() 統計個數
- delete(ID id) 根據id刪除一條記錄
- deleteAll() 刪除一張數據表的全部記錄
- …
當然我們也可以自定義一些操作, 自定義方式可參考 Spring Data MongoDB - Reference Documentation, 這裏自定義一個根據name查詢的方法。
package com.notepad.springnote.nosql.mongo.repository;
import com.notepad.springnote.nosql.mongo.domain.Entity;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Description:
* <p>
* Create: 2018/12/2 14:46
*
* @author Marvin Yang
*/
@Repository
public interface EntityRepository extends MongoRepository<Entity, String> {
/**
* 根據name搜索entity
*
* @param name 實體名稱
* @return 記錄
*/
Entity findByName(String name);
}
MongoDbFactory和MongoTemplate定義
Document和Repository接口定義完成之後,我們定義MongoDbFactory關聯MongoDB,定義MongoTemplate可實現對於Mongo數據庫的操作。此處需說明,我們這裏顯示的定義是爲了去掉"_class"字段,如果無特殊需求可以不必顯示定義MongoDbFactory和MongoTemplate,Spring會幫我們用默認的實現。
我們使用Java配置實現。
package com.notepad.springnote.config;
import com.mongodb.MongoClientURI;
import com.notepad.springnote.aspects.StringAspect;
import com.notepad.springnote.inject.EncodeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.net.UnknownHostException;
/**
* Description: Spring依賴注入Config(Java8)
* <p>
* Create: 2018/6/24 10:58
*
* @author Marvin Yang
*/
@Configuration
@ComponentScan(basePackages = "com.notepad.springnote")
public class InjectConfig {
@Bean
public MongoDbFactory mongoDbFactory() throws UnknownHostException {
return new SimpleMongoDbFactory(new MongoClientURI(mongoDbUri));
}
/**
* 定義mongo template
*
* @param mongoDbFactory a MongoDbFactory
* @return a MongoOperations
*/
@Bean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory) {
// 去掉_class字段:DefaultMongoTypeMapper的typeKey爲null
MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory),
new MongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
return new MongoTemplate(mongoDbFactory, converter);
}
@Value("${spring.data.mongodb.uri}")
private String mongoDbUri;
}
applicatin.properties中mongoDB配置如下,monogDbUri的更多細節請參考 Connection String URI Format.
#mongo配置
spring.data.mongodb.uri=mongodb://localhost:27017/KnowledgeGraph?connectTimeoutMS=10000&socketTimeoutMS=10000
啓用MongoDB
上述的定義已滿足MongoDB操作的基本需要, 但是爲了使之生效需要啓動MongoDB,利用@EnableMongoRepositories
在Config類聲明掃描package。
@Configuration
@ComponentScan(basePackages = "com.notepad.springnote")
@EnableMongoRepositories(basePackages = "com.notepad.springnote")
public class InjectConfig {
...
}
單元測試
package com.notepad.springnote.nosql.mongo.repository;
import com.notepad.springnote.config.InjectConfig;
import com.notepad.springnote.nosql.mongo.domain.Entity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
import java.util.List;
/**
* Description: Entity實例化測試
* <p>
* Create: 2018/12/2 14:48
*
* @author Marvin Yang
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = InjectConfig.class)
public class EntityRepositoryTest {
@Autowired
private EntityRepository entityRepository;
@Test
public void init() throws Exception {
Assert.notNull(entityRepository);
}
@Test
public void save() throws Exception {
String name = "thing";
Entity entity = new Entity();
entity.setName(name);
if (entityRepository.findByName(name) == null) {
entityRepository.save(entity);
}
System.out.println("insert a entity name of: " + name);
}
@Test
public void count() throws Exception {
Long count = entityRepository.count();
System.out.println("entity count is : " + count);
}
@Test
public void find() throws Exception {
List<Entity> entities = entityRepository.findAll();
for (Entity e : entities) {
System.out.println(e.getName());
}
}
}
數據庫中查詢結果如下:
> use KnowledgeGraph
switched to db KnowledgeGraph
> db.entity.find()
{ "_id" : ObjectId("5c29cb229cac1749f0236063"), "name" : "thing" }
總結
本文主要介紹了通過Spring訪問mongoDB操作,實現的基本的數據插入,查詢,統計計數等功能。
MongoRepository的自定義操作包含很多細節,還需要更多的使用纔可以。另外,如果自定義操作無法滿足要求時,可直接通過monogTemplate實現操作, 如構造Query,Criteria
等,相關細節均可以在參考文獻4中找到。
參考文獻
[1] MongoDbUri格式 https://docs.mongodb.com/manual/reference/connection-string/
[2] springboot配置 https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
[3] springboot訪問monogdb示例 https://spring.io/guides/gs/accessing-data-mongodb/
[4] mongdb自定義操作 https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/