48

Spring Boot MongoDB 数据库应用技巧

 5 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzAwNjY3MjgzOA%3D%3D&%3Bmid=2477610491&%3Bidx=1&%3Bsn=b7cdef0b977cd30aa2a0dfd02defbab2&%3Bchksm=8d502d52ba27a444ee41123f7524180cd6945ded258d385cff879c4f089b600e86d1b2f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、关于 MongoDB

VvE7jem.png!web

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

UzQ3eaV.jpg!web

然而在非关系型数据库领域,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 整体框架的一个概要:

BZ7bMzR.jpg!web

从上图中可以看出,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 属性,大多数情况下这个不是必须的,可以通过配置去掉:

   publicMongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext context) {

       MongoTemplate mongoTemplate = newMongoTemplate(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篇" ,期待更多精彩内容^-^

7fUjay3.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK