转载

Spring Boot MongoDB 数据库应用技巧

一、关于 MongoDB

Spring Boot MongoDB 数据库应用技巧

MongoDB 目前非常流行,在最近的 DB-Engine 排名中居第5位,仅次于传统的关系型数据库如 Oracle、Mysql。

Spring Boot MongoDB 数据库应用技巧

然而在非关系型数据库领域,MongoDB已经持续成为佼佼者一段时间了,这与 MongoDB的一些优势存在一定关系:

  • 无模式(Schema),便于快速开发;

  • 面向文档化的数据,基于BSON格式(类JSON),灵活性强

  • 高性能,得益于其内存计算能力;

  • 副本集、自动分片特性,提供了高可用及水平扩展能力

MongoDB 的主要对象包括数据库(database)、集合(collection)、文档对象(document),与关系型数据库的对应关系如下:

MySql MongoDB
schema database
table collection
record document
column field

与关系型数据库一样,MongoDB也支持索引(不支持外键),然而其没有定义固定的列(Column),字段可以是任何类型的值,比如数值、数组或嵌套文档等。 在最近发布的4.0版本中,MongoDB开始支持事务。可见,在未来这些数据库之间的差异只会越来越少。

二、Spring-Data-Mongo

Spring-Data-Mongo 是Spring框架对于MongoDB 数据读写的ORM 封装, 与 大家熟悉的 JPA一样,其在MongoDB-Java-Driver基础之上做了一些封装,令应用开发更加简便。

如下是 SpringData 整体框架的一个概要:

Spring Boot MongoDB 数据库应用技巧

从上图中可以看出,SpringData 是基于分层设计的。从下之上,分别是:

  • 数据库层;

  • 驱动层(JDBC/Driver);

  • ORM层(Repository);

三、整合 MongoDB CRUD

接下来的篇幅,主要针对如何在项目中使用框架进行MongoDB数据库的读写,部分代码可供参考。

A. 引入框架

其中  spring-boot-starter-mongodb 是一个胶水组件,声明对它的依赖会令项目自动引入 spring-data-mongo mongodb-java-driver 等基础组件。

B. 数据库配置

我们在  application.properties 中声明一段配置:

不难理解,这里是数据库主机、端口、用户密码、数据库的设置。

C. 数据模型

接下来,要定义数据集合(collection) 的一个结构,以  Book 实体为例:

这里,我们给Book 实体定义了一些属性:

属性名 描述
id 书籍ID
author 作者
category 书籍分类
title 书籍标题
voteCount 投票数量
price 价格
publishDate 发布日期
updateTime 更新时间
createTime 创建时间

除此以外,我们还会用到几个注解:

注解 描述
@Document 声明实体为MongoDB文档
@Id 标记ID属性
@Indexed 单键索引
@CompoundIndexes 复合索引集
@CompoundIndex 复合索引

关于MongoDB索引形态,可以参考 官方文档 做一个详细了解。

D. 数据操作

ORM 框架可以让你通过操作对象来直接影响数据,这样一来,可以大大减少上手的难度,你不再需要熟悉大量驱动层的API了。 

Spring-Data-Mongo 实现了类JPA的接口,通过预定义好的Repository可实现 代码方法到数据库操作语句DML 的映射。 

下面是一些例子:

  • BookRepository

我们所看到的  findByAttribute 将会直接被转换成对应的条件查询,

如 findByAuthor 等价于

接下来,我们可以方便的在业务逻辑层(service层) 对Repository 进行调用,如下:

关于Repository 映射规则,可以从 这里 找到详细介绍。

E. 自定义操作

有时候,Repository的方法映射无法较好的满足一些特定场景,比如高级检索、局部更新、覆盖索引查询等等, 此时可以使用框架提供的  MongoTemplate 工具类来完成这些定制。

MongoTemplate 提供了大量的  Criteria API 来封装 Mongo-Java-Driver的实现。 

我们一方面可以选择直接使用该API,另一方面,则可以更加 "优雅" 的整合到Repository 接口,如下面的代码:

  • 声明 Custom 接口

  • 声明接口继承关系

  • 实现类

利用 AOP的魔法 ,Spring 框架会自动将我们这段代码实现  织入  到Bean对象中, 这样一来,我们原先对Repository的依赖引用方式就不需要改变了。

四、高级技巧

SpringBoot中完成Mongodb的自动化配置,是通过 MongoAutoConfiguration、MongoDataAutoConfiguration 完成的。

其中MongoAutoConfiguration的实现如下:

从上面的代码可见,如果应用代码中未声明 MongoClient、MongoDbFactory,那么框架会根据配置文件自动做客户端的初始化。 

通过声明,可以取消这些自动化配置:

真实线上的项目中,会对MongoDB 客户端做一些定制 ,下面介绍几个常见用法

1. 连接池配置

这里我们所关心的,往往是连接池大小、超时参数阈值、队列这几个,

如下:

2. 去掉_class属性

通过 SpringDataMongo 定义的实体,会自动写入一个 _class 属性,大多数情况下这个不是必须的,可以通过配置去掉:

   public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext context) {

       MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);

       return mongoTemplate;

3. 自定义序列化

一些基础的字段类型,如 int 、long、string,通过JDK 装箱类就可以完成, 对于内嵌的对象类型,SpringDataMongo框架会将其转换为 DBObject对象(java driver 实体)。 

一般情况下这已经足够了,但某些场景下你不得不实现自己的序列化方式,比如通过文档存储某些特殊格式的内容。

这需要用到 Converter 接口,如下面的代码:

4. 读写分离

MongoDB 本身支持读写分离的实现,前提是采用副本集、分片副本集的架构, 通过声明客户端的 ReadPreference 级别可以达到优先读主、优先读备的控制。

上面的代码中,将会为MongoClient 设置  secondaryPreferred 的读级别。 ReadPreference 级别包括以下几种:

级别 描述
primary 默认值,只从主节点读,主节点不可用时报错
primaryPreferred 优先主节点(primary)读,主节点不可用时到从节点(secondary)读
secondary 仅从备节点(secondary)读取数据
secondaryPreferred 优先从备节点读,从节点不可用时到主节点读取
nearest 到网络延迟最低的节点读取数据,不管是主节点还是从节点

小结

MongoDB 是当下 NoSQL 数据库的首选,也有不少服务化架构采用了 MongoDB作为主要数据库, 其在 4.x版本中即将推出事务功能,在未来该文档数据库相对于RDBMS的差距将会大大缩小。 也正由于MongoDB 具备 简单、易扩展、高性能等特性,其社区活跃度非常高,是非常值得关注和学习的。

欢迎继续关注"美码师的补习系列-springboot篇" ,期待更多精彩内容^-^

Spring Boot MongoDB 数据库应用技巧

原文  https://mp.weixin.qq.com/s?__biz=MzAwNjY3MjgzOA==&mid=2477610491&idx=1&sn=b7cdef0b977cd30aa2a0dfd02defbab2&chksm=8d502d52ba27a444ee41123f7524180cd6945ded258d385cff879c4f089b600e86d1b2fecb17&token=1556993130&lang=zh_CN
正文到此结束
Loading...