简介
通过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/