写作时间:2019-09-16
Spring Boot: 2.1 ,JDK: 1.8, IDE: IntelliJ IDEA

说明

MongoDB 是一款开源的文档型数据库

  • https://www.mongodb.com

MongoDB is a document database, which means it stores data in JSON-like documents. We believe this is the most natural way to think about data, and is much more expressive and powerful than the traditional row/column model.

{"_id": "5cf0029caff5056591b0ce7d","firstname": "Jane","lastname": "Wu","address": {"street": "1 Circle Rd","city": "Los Angeles","state": "CA","zip": "90404"},"hobbies": ["surfing", "coding"]
}

Rich JSON Documents
The most natural and productive way to work with data.

Supports arrays and nested objects as values.
Allows for flexible and dynamic schemas.

Spring 对 MongoDB的支持

  • Spring Data MongoDB

    • MongoTemplate
    • Repository 支持

初始化MongoDB的库及权限

Docker运行MongoDB镜像

docker start mongo

注释:
docker run, 表示create一个新的容器,并启动
docker start, 表示启动一个已经存在的容器
docker ps, 正在运行的容器
docker ps -a, 已经存在的容器,包括正在运行,和不在运行的容器
docker rm $Container ID, 删除容器

登录到MongoDB容器中

% docker exec -it mongo bash

通过Shell 连接 MongoDB

mongo -u admin -p admin

注释:上面两条请参照上一篇【SpringBoot 2.1 | 第廿三篇:SpringBoot之Docker安装MongoDB】

创建库

use starbucks;

创建用户

db.createUser({user: "starbucks",pwd: "starbucks",roles: [{ role: "readWrite", db: "starbucks" }]}
)

1.工程建立

参照教程【SpringBoot 2.1 | 第一篇:构建第一个SpringBoot工程】新建一个Spring Boot项目,名字叫demodbmybatisgenerator, 在目录src/main/java/resources 下找到配置文件application.properties,重命名为application.yml

在Dependency中选择
Developer Tools > Lombok
NoSQL > Spring Data MongoDB


pom.xml增加, joda


<dependencies><dependency><groupId>org.joda</groupId><artifactId>joda-money</artifactId><version>RELEASE</version></dependency>
</dependencies>

1.application配置

src > main > resources > application.yml

spring:data:mongodb:uri: 'mongodb://starbucks:starbucks@localhost:27017/starbucks'

1.Model

zgpeace.spring.data.mongo.model.Coffee

package zgpeace.spring.data.mongo.model;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.joda.money.Money;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;@Document
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Coffee {@Idprivate String id;private String name;private Money price;private Date createTime;private Date updateTime;
}

1.Money类型转换类

zgpeace.spring.data.mongo.converter.MoneyReadConverter

package zgpeace.spring.data.mongo.converter;import org.bson.Document;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.core.convert.converter.Converter;public class MoneyReadConverter implements Converter<Document, Money> {@Overridepublic Money convert(Document document) {Document money = (Document)document.get("money");double amount = Double.parseDouble(money.getString("amount"));String currency = ((Document)money.get("currency")).getString("code");return Money.of(CurrencyUnit.of(currency), amount);}
}

1.Controller CRUD MongoDB

zgpeace.spring.data.mongo.MongoApplication

package zgpeace.spring.data.mongo;import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import zgpeace.spring.data.mongo.converter.MoneyReadConverter;
import zgpeace.spring.data.mongo.model.Coffee;import java.util.Arrays;
import java.util.Date;
import java.util.List;import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;@SpringBootApplication
@Slf4j
public class MongoApplication implements ApplicationRunner {@Autowiredprivate MongoTemplate mongoTemplate;@Beanpublic MongoCustomConversions mongoCustomConversions() {return new MongoCustomConversions(Arrays.asList(new MoneyReadConverter()));}@Overridepublic void run(ApplicationArguments args) throws Exception {Coffee espresso = Coffee.builder().name("espresso").price(Money.of(CurrencyUnit.of("CNY"), 20.0)).createTime(new Date()).updateTime(new Date()).build();Coffee saved = mongoTemplate.save(espresso);log.info("Coffee {}", saved);List<Coffee> list = mongoTemplate.find(query(where("name").is("espresso")), Coffee.class);log.info("Find {} Coffee", list.size());list.forEach(c -> log.info("Coffee {}", c));Thread.sleep(1000); // sleep 1 second, to make the update time different from create timeUpdateResult result = mongoTemplate.updateFirst(query(where("name").is("espresso")),new Update().set("price", Money.ofMajor(CurrencyUnit.of("CNY"), 30)).currentDate("updateTime"),Coffee.class);log.info("Update Result: {}", result.getModifiedCount());Coffee updateOne = mongoTemplate.findById(saved.getId(), Coffee.class);log.info("Update Result: {}", updateOne);mongoTemplate.remove(updateOne);}public static void main(String[] args) {SpringApplication.run(MongoApplication.class, args);}
}

运行数据入库和查询日志如下:

Opened connection [connectionId{localValue:2, serverValue:5}] to localhost:27017Coffee Coffee(id=5d802fbba7b56962a0cb115f, name=espresso, price=CNY 20.00, createTime=Tue Sep 17 08:58:35 CST 2019, updateTime=Tue Sep 17 08:58:35 CST 2019)Find 1 Coffee
Coffee Coffee(id=5d802fbba7b56962a0cb115f, name=espresso, price=CNY 20.00, createTime=Tue Sep 17 08:58:35 CST 2019, updateTime=Tue Sep 17 08:58:35 CST 2019)Update Result: 1
Update Result: Coffee(id=5d802fbba7b56962a0cb115f, name=espresso, price=CNY 30.00, createTime=Tue Sep 17 08:58:35 CST 2019, updateTime=Tue Sep 17 08:58:37 CST 2019)Closed connection [connectionId{localValue:2, serverValue:5}] to localhost:27017 because the pool has been closed.

注释: 程序运行必要条件,必须启动Docker > 加载MongoDB镜像到容器 > 登录到MongoDB容器 > 通过shell连接到MongoDB。

2.工程建立

请参照1.工程建立,名字为MongoRepository

2. application配置

请参照1. application配置

2. Model

请参照1. Model

2.Money类型转换类

请参照1. Money类型转换类,
只有一个区别在类上加上注解 @Component

// the same ...@Component
public class MoneyReadConverter implements Converter<Document, Money> {// the same ...

2. Repository

zgpeace.spring.data.mongorepository.repository.CoffeeRepository

package zgpeace.spring.data.mongorepository.repository;import org.springframework.data.mongodb.repository.MongoRepository;
import zgpeace.spring.data.mongorepository.model.Coffee;import java.util.List;public interface CoffeeRepository extends MongoRepository<Coffee, String> {List<Coffee> findByName(String name);
}

2. Controller Repository 操作数据

zgpeace.spring.data.mongorepository.MongorepositoryApplication

package zgpeace.spring.data.mongorepository;import lombok.extern.slf4j.Slf4j;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import zgpeace.spring.data.mongorepository.converter.MoneyReadConverter;
import zgpeace.spring.data.mongorepository.model.Coffee;
import zgpeace.spring.data.mongorepository.repository.CoffeeRepository;import java.util.Arrays;
import java.util.Date;@Slf4j
@SpringBootApplication
@EnableMongoRepositories
public class MongorepositoryApplication implements CommandLineRunner {@Autowiredprivate CoffeeRepository coffeeRepository;@Beanpublic MongoCustomConversions mongoCustomConversions() {return new MongoCustomConversions(Arrays.asList(new MoneyReadConverter()));}@Overridepublic void run(String... args) throws Exception {Coffee espresso = Coffee.builder().name("espresso").price(Money.of(CurrencyUnit.of("CNY"), 20.0)).createTime(new Date()).updateTime(new Date()).build();Coffee latte = Coffee.builder().name("latte").price(Money.of(CurrencyUnit.of("CNY"), 30.0)).createTime(new Date()).updateTime(new Date()).build();coffeeRepository.insert(Arrays.asList(espresso, latte));coffeeRepository.findAll(Sort.by("name")).forEach(c -> log.info("Saved Coffee {}", c));Thread.sleep(1000);latte.setPrice(Money.of(CurrencyUnit.of("CNY"), 35.0));latte.setUpdateTime(new Date());coffeeRepository.save(latte);coffeeRepository.findByName("latte").forEach(c -> log.info("Coffee {}", c));coffeeRepository.deleteAll();}public static void main(String[] args) {SpringApplication.run(MongorepositoryApplication.class, args);}
}

Shell log

Opened connection [connectionId{localValue:2, serverValue:5}] to localhost:27017
Saved Coffee Coffee(id=5d8180fea7b569f3eddd5195, name=espresso, price=CNY 20.00, createTime=Wed Sep 18 Saved Coffee Coffee(id=5d8180fea7b569f3eddd5196, name=latte, price=CNY 30.00, createTime=Wed Sep 18 08:57:34 CST 2019, updateTime=Wed Sep 18 08:57:34 CST 2019)Coffee Coffee(id=5d8180fea7b569f3eddd5196, name=latte, price=CNY 35.00, createTime=Wed Sep 18 08:57:34 CST 2019, updateTime=Wed Sep 18 08:57:35 CST 2019)Closed connection [connectionId{localValue:2, serverValue:5}] to localhost:27017 because the pool has been closed.

Docker 中查看MongoDB数据

在Controller中注释掉删除数据代码

//coffeeRepository.deleteAll();

查询有多少个数据库

> show dbs
admin      0.000GB
config     0.000GB
local      0.000GB
starbucks  0.000GB

选择数据库,查看表,查看数据

> use starbucks
switched to db starbucks
> show collections
coffee
> db.coffee.find()
{ "_id" : ObjectId("5d8236bfa7b56957caf1fe6e"), "name" : "espresso", "price" : { "money" : { "currency" : { "code" : "CNY", "numericCode" : 156, "decimalPlaces" : 2 }, "amount" : "20.00" } }, "createTime" : ISODate("2019-09-18T13:53:02.972Z"), "updateTime" : ISODate("2019-09-18T13:53:02.972Z"), "_class" : "zgpeace.spring.data.mongorepository.model.Coffee" }
{ "_id" : ObjectId("5d8236bfa7b56957caf1fe6f"), "name" : "latte", "price" : { "money" : { "currency" : { "code" : "CNY", "numericCode" : 156, "decimalPlaces" : 2 }, "amount" : "35.00" } }, "createTime" : ISODate("2019-09-18T13:53:02.972Z"), "updateTime" : ISODate("2019-09-18T13:53:04.202Z"), "_class" : "zgpeace.spring.data.mongorepository.model.Coffee" }

解析:在数据转换类中,需要嵌套获取currency的过程是
price > money > currency > code, 实际上是为了拿出currency:“CNY”,和
amout:“20.00”

删除数据

> db.coffee.remove({"name":"espresso"})
WriteResult({ "nRemoved" : 1 })

源码解析

Controller 里面怎么知道MongoCustomConversions是可以自定义的呢?

 @Beanpublic MongoCustomConversions mongoCustomConversions() {return new MongoCustomConversions(Arrays.asList(new MoneyReadConverter()));}

请看类MongoDataConfiguration, 这里注解ConditionalOnMissingBean表明只有在缺失的时候才会用空数组表示


package org.springframework.boot.autoconfigure.data.mongo;// 省略 import .../*** Base configuration class for Spring Data's mongo support.** @author Madhura Bhave*/
@Configuration
class MongoDataConfiguration {private final ApplicationContext applicationContext;private final MongoProperties properties;// 省略方法 ...@Bean@ConditionalOnMissingBeanpublic MongoCustomConversions mongoCustomConversions() {return new MongoCustomConversions(Collections.emptyList());}}

注释:这里得到的启发,从Spring-boot-autoconfigure中查看,哪些类可以自定义。

总结

恭喜你,学会了MongoDB的MongoTemplate,Mongo Repository 操作数据。
代码下载:

https://github.com/zgpeace/Spring-Boot2.1/tree/master/Nosql/MongoTemplate

https://github.com/zgpeace/Spring-Boot2.1/tree/master/Nosql/MongoRepository

参考

https://www.mongodb.com/

https://github.com/geektime-geekbang/geektime-spring-family/tree/master/Chapter%204/mongo-demo

https://github.com/geektime-geekbang/geektime-spring-family/tree/master/Chapter%204/mongo-repository-demo

易筋SpringBoot 2.1 | 第廿四篇:SpringBoot访问Docker中的MongoDB相关推荐

  1. 【前端部署第四篇】使用 Docker 构建缓存及多阶段构建优化单页应用

    大家好,我是山月,这是我最近新开的专栏:前端部署系列.包括 Docker.CICD 等内容,大纲图示如下: 示例代码开源,置于 Github 中,演示如何对真实项目进行部署上线. simple-dep ...

  2. GWAS分析中SNP解释百分比PVE | 第四篇,MLM模型中如何手动计算PVE?

    系列部分: GWAS分析中SNP解释百分比PVE | 第一篇,SNP解释百分比之和为何大于1? GWAS分析中SNP解释百分比PVE | 第二篇,GLM模型中如何计算PVE? GWAS分析中SNP解释 ...

  3. 从零开始搭建Java开发环境第四篇:精选IDEA中十大提高开发效率的插件!

    Lombok 知名的插件,无需再写那么多冗余的get/set代码 JRebel 热部署插件 alibaba java coding guide 阿里巴巴代码规范插件,自动检查代码规范问题 ![在这里插 ...

  4. 第三十四篇:在SOUI中使用异步通知

    概述 异步通知是客户端开发中常见的需求,比如在一个网络处理线程中要通知UI线程更新等等. 通常在Windows编程中,为了方便,我们一般会向UI线程的窗口句柄Post/Send一个窗口消息从而达到将非 ...

  5. 【opencv学习笔记】第五篇:访问图像中像素的三种方式、ROI区域图像叠加和图像混合

    1. 访问图像中像素的三种方式 任何图像处理算法,都是从操作每个像素开始的.在OpenCV中,提供了三种访问每个像素的方法. 方法1:指针访问:C操作符[] 方法2:迭代器iterator 方法3:动 ...

  6. Go实现Raft第四篇:持久化和调优

    女主宣言 今天小编为大家分享一篇关于Golang实现Raft的文章,本篇文章为系列中的第四篇,对Raft中通过添加持久性和一些优化来完成Raft的基本实现.希望能对大家有所帮助. PS:丰富的一线技术 ...

  7. 最简单人工智能python_Python人工智能之路 - 第四篇 : jieba gensim 最好别分家之最简单的相似度实现...

    简单的问答已经实现了,那么问题也跟着出现了,我不能确定问题一定是"你叫什么名字",也有可能是"你是谁","你叫啥"之类的,这就引出了人工智能 ...

  8. SpringBoot启动流程分析(四):IoC容器的初始化过程

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  9. 第四篇:整合Thymeleaf模板

    第四篇:整合Thymeleaf模板 本文链接:http://blog.battcn.com/2018/04/28/springboot/v2-web-thymeleaf/ 在前面几章中已经介绍了如何创 ...

  10. SpringCloud核心教程 | 第四篇:服务注册与发现 Consul篇

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...

最新文章

  1. 洗礼灵魂,修炼python(70)--爬虫篇—补充知识:json模块
  2. Mongodb主从配置
  3. Xcode:Foundation框架找不到,或者是自动提示出现问题
  4. Tomcat 配置详解/优化方案
  5. postgreSQL源码分析——索引的建立与使用——GIST索引(1)
  6. (转载)设计模式之-策略模式(Strategy)
  7. Java Web 开发详解
  8. webpack使用笔记
  9. android原生browser分析(一)--Application
  10. Word控件Spire.Doc 转换教程(四):如何将 Word 转换为文本
  11. 手机迅雷打不开html,迅雷打不开了怎么办
  12. 全面剖析雅虎助手以及网络实名的流氓行径(5)
  13. sudo chmod 755 ....指令分析
  14. NetScaler AG自定义用户门户
  15. python处理金融数据_Python金融大数据分析-数据获取与简单处理
  16. Apache ServiceComb Kie | 一个语义型配置中心
  17. FastDFS 系统架构和功能原理
  18. IPv6基本配置(华为设备)
  19. Vue3.x 报 Uncaught TypeError:Object(...) is not a function( Vue3对象不是函数解决思路)
  20. 移动电力猫HG260GT pon实现路由拨号

热门文章

  1. selenium webdriver实战宝典 pdf_Selenium+webdriver爬虫技术实战之沃运维报表提取
  2. android 判断主线程_腾讯Android面试:Handler中有Loop死循环,为什么没有阻塞主线程...
  3. 数据中心淘汰服务器,浅谈数据中心危机严重的程度
  4. css3中2D变形tranform总结(附实例)
  5. centos 7 install VirtualBox
  6. 【TensorFlow系列】【九】利用tf.py_func自定义算子
  7. Centos yum安装snmp
  8. Convert.ToInt32、(int)和int.Parse 三者的区别 转
  9. python字符串以什么为结束符_Python代码中 如何判断字符串是否使用指定字符结尾(endswith)呢?...
  10. python股票_十分钟学会用Python交易股票