MongoDB是一款高性能的分布式文件存储数据库,类似于JSON的存储格式,结构松散,易部署,易扩展,支持索引,简单易用,广泛用于各种类型的系统。MongoDB功能强大,SpringBoot也与之进行集成,下面我们就来看看到底如何使用。
项目搭建
先来一个demo看看应该如何进行整合使用,再来详细描述其中的细节。由于在工作中,接触较多的就是maven,所以还是采用maven的方式进行项目构建。至于采用Gradle等其它构建工具,大家可以自行尝试。
项目版本:SpringBoot (2.1.4)
首先,引入MongoDB相关依赖,如下所示:
pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
application.properties:
spring.data.mongodb.uri=mongodb://localhost/test
ExceptionLog(Entity):
@Data
public class ExceptionLog {
@Id
private String openId;
private Integer status;
private String body;
}
ExceptionLogService(用于操作ExceptionLog):
@Service
public class ExceptionLogService {
private final MongoTemplate mongoTemplate;
@Autowired
public ExceptionLogService(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
/**
* 使用insert添加数据
* @param exceptionLog 实体信息
* @return 保存后的信息
*/
public ExceptionLog add(ExceptionLog exceptionLog) {
return this.mongoTemplate.insert(exceptionLog);
}
/**
* 根据主键进行删除
* @param openId 主键
* @return 删除的数量
*/
public long delete(String openId) {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(openId));
DeleteResult remove = this.mongoTemplate.remove(query, ExceptionLog.class);
return remove.getDeletedCount();
}
/**
* 使用update方式修改数据
* @param exceptionLog 需要修改的信息
*/
public void update(ExceptionLog exceptionLog) {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(exceptionLog.getObjectId()));
Update update = new Update();
update.set("status", exceptionLog.getStatus());
update.set("body", exceptionLog.getBody());
this.mongoTemplate.updateFirst(query, update, ExceptionLog.class);
}
/**
* 查询当前集合中所有的文档
* @return list
*/
public List<ExceptionLog> findAll() {
return this.mongoTemplate.findAll(ExceptionLog.class);
}
}
SpringbootMongodbApplicationTests(测试):
//添加数据
ExceptionLog exceptionLog = new ExceptionLog();
exceptionLog.setStatus(400);
exceptionLog.setBody("传递参数错误");
ExceptionLog add = this.exceptionLogService.add(exceptionLog);
System.out.println("------------------------------------------------------------");
System.out.println("添加数据结果:" + add);
//修改数据
ExceptionLog update = new ExceptionLog();
update.setObjectId(add.getObjectId());
update.setStatus(500);
update.setBody("服务不可用");
this.exceptionLogService.update(update);
//查询数据
List<ExceptionLog> all = this.exceptionLogService.findAll();
System.out.println("------------------------------------------------------------");
System.out.println("所有结果:" + all);
//删除数据
long delete = this.exceptionLogService.delete(add.getObjectId());
System.out.println("------------------------------------------------------------");
System.out.println("删除条数:" + delete);
执行结果:
------------------------------------------------------------
添加数据结果:ExceptionLog(objectId=5caf54c50c3233203065d66d, status=400, body=传递参数错误)
------------------------------------------------------------
所有结果:[ExceptionLog(objectId=5caf54c50c3233203065d66d, status=500, body=服务不可用)]
------------------------------------------------------------
删除条数:1
存储格式:
{
"_id" : ObjectId("5cb0993b0c32334508390171"),
"status" : 404,
"body" : "URL不存在",
"_class" : "com.fanqie.springboot2.mongo.entity.ExceptionLog"
}
现在,我们已经搭建了一个SpringBoot与MongoDB的Demo,大家可以发现整个流程还是比较简单的,没有太多复杂的东西。大家注意到没有,Criteria.where("_id").is(exceptionLog.getObjectId())中的_id是哪里来的,我们好像没有定义这个字段啊。继续往下看。
基础使用
在项目中,针对任何数据库的操作,无非就是增删改查,只要解决了这些基本操作,就能完成至少百分之九十的工作,所以重点讲解一下相关操作。在SpringBoot中操作MongoDB主要有两种方式:MongoTemplate和Repository。
MongoTemplate
MongoTemplate是Spring Data MongoDB提供用于操作MongoDB数据库的一个高级抽象,类似于JdbcTemplete,操作简单。SpringBoot基于自动配置,已经实现相关配置,我们可以直接使用。
添加数据
添加数据相对比较简单,MongoTemplete提供了三种方式:insert、insertAll、save。
-
insert:用于添加文档,即使文档已存在也会再次添加。
-
save: 用于保存文档,文档存在则覆盖文档并更新id。
-
insertAll:用于添加文档集合。
使用相对简单,操作如下:
//单条记录插入
//exceptionLog就是我们需要添加的对象,后面跟着的是MongoDB对应的collection名称
//第二个参数还可以传入ExceptionLog.class或者不传,这样就会默认使用类名的首字母小写作为collection名称
this.mongoTemplate.insert(exceptionLog, "exceptionLog")
//多条记录插入
public List<ExceptionLog> addAll(List<ExceptionLog> list) {
return (List<ExceptionLog>) this.mongoTemplate.insertAll(list);
}
查找数据
数据查询,应该是我们平时最常接触的,针对MongoDB,MongoTemplete也提供了非常多的方式,例如:
-
findAll:查询某个collection的所有文档。
-
findOne:根据条件查询某个collection中的单个文档。
-
findById:通过id查询collection中的文档。
-
find:根据条件,将查询结果映射到List。
相关操作如下:
/**
* 查询集合exceptionLog中所有的文档
* @return list
*/
public List<ExceptionLog> findAll() {
return this.mongoTemplate.findAll(ExceptionLog.class);
}
/**
* 根据status升序获取List
* @return list
*/
public List<ExceptionLog> find() {
Query query = new Query();
query.with(Sort.by(Sort.Order.asc("status")));
return this.mongoTemplate.find(query, ExceptionLog.class);
}
/**
* 查询状态小于404 的一个文档
* @return ExceptionLog
*/
public ExceptionLog findOne() {
Query query = new Query();
query.addCriteria(Criteria.where("status").lt(404));
return this.mongoTemplate.findOne(query, ExceptionLog.class);
}
MongoTemplete依赖Query和Criteria指定查询条件,支持lt,lte,is等方式查询。另外还可以通过Query.with()方法指定Sort和Pageable,满足用户的大部分的需求。假若Query不能满足你的业务,还可以使用Query的子类BasicQuery,采用json格式描述查询条件,例如:
BasicQuery query = new BasicQuery("{ status : { $lt : 404 }}");
修改数据
针对数据修改,MongoTemplete也提供了两种方式:update(updateFirst / updateMulti)、findAndModify。
-
updateFirst:修改查询结果中的第一条记录并返回UpdateResult。
-
updateMulti:修改查询到的所有结果并返回UpdateResult。
-
findAndModify:修改查询结果的第一条记录并返回旧数据。
操作如下:
/**
* 根据主键,修改实体
* @param exceptionLog 需要修改的信息
*/
public void findAndModify(ExceptionLog exceptionLog) {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(exceptionLog.getObjectId()));
Update update = new Update();
update.set("status", exceptionLog.getStatus());
update.set("body", exceptionLog.getBody());
this.mongoTemplate.findAndModify(query, update, ExceptionLog.class);
}
/**
* 使用update方式修改数据
* @param exceptionLog 需要修改的信息
*/
public void update(ExceptionLog exceptionLog) {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(exceptionLog.getObjectId()));
Update update = new Update();
update.set("status", exceptionLog.getStatus());
update.set("body", exceptionLog.getBody());
this.mongoTemplate.updateFirst(query, update, ExceptionLog.class);
}
和Query类似,Update被用于更新文档,支持多种API,大家可以自行尝试。
删除数据
针对数据删除,MongoTemplete也提供了两种方式:remove、findAndRemove。
-
remove:默认会将查询到的所有数据删除。
-
findAndRemove:只会将查询结果中的第一条记录删除
操作如下:
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(openId));
DeleteResult remove = this.mongoTemplate.remove(query, ExceptionLog.class);
或者
this.mongoTemplate.findAndRemove(query,ExceptionLog.class);
大家发现,我们在很多地方都使用到了 _id这个字段,它是哪里来的呢?其实_id是MongoDB自带的一个字符串类型主键,用于文档唯一性,即使我们没有指定这个字段,它也是会自动生成并赋值的。如果我们想在程序中使用它,可以使用@Id注解去映射该字段为主键,这样就可以拿到该值并在程序中使用。
上述我们采用MongoTemplete实现增删改查,接下来,就来看看Repository如何使用。
MongoRepository
MongoRepository是Repository的子类,提供了CRUD相关API,使用方式和JpaRepository类似。MongoRepository<T, ID>在使用过程中需要指定collection实体以及主键类型,使用相对简单,就不做过多介绍,示例如下:
@Repository
public interface ExceptionLogRepository extends MongoRepository<ExceptionLog, String> {
}
springboot2与mongodb的基本内容就到此为止了,这里我就不给大家分析MongoDB自动配置的相关源码了,在之前的几篇文章中,已经简单的为大家介绍了源码如何查找,并且做过简单分析,大致的原理其实都是一样的,我就不重复描述了,大家可以在spring-boot-autoconfigure->spring.factories找到你想要的答案。
总结
springboot2-mongodb整合内容都比较基础,但是平常工作中用的最多的就是它们。相关内容是在学习和使用过程中的一点见解,若有不当的地方,望大家指正,谢谢。
源码见于:https://gitee.com/hpaw/SpringBoot2Demo/tree/master/springboot-mongodb