易筋SpringBoot 2.1 | 第廿四篇:SpringBoot访问Docker中的MongoDB
写作时间: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相关推荐
- 【前端部署第四篇】使用 Docker 构建缓存及多阶段构建优化单页应用
大家好,我是山月,这是我最近新开的专栏:前端部署系列.包括 Docker.CICD 等内容,大纲图示如下: 示例代码开源,置于 Github 中,演示如何对真实项目进行部署上线. simple-dep ...
- GWAS分析中SNP解释百分比PVE | 第四篇,MLM模型中如何手动计算PVE?
系列部分: GWAS分析中SNP解释百分比PVE | 第一篇,SNP解释百分比之和为何大于1? GWAS分析中SNP解释百分比PVE | 第二篇,GLM模型中如何计算PVE? GWAS分析中SNP解释 ...
- 从零开始搭建Java开发环境第四篇:精选IDEA中十大提高开发效率的插件!
Lombok 知名的插件,无需再写那么多冗余的get/set代码 JRebel 热部署插件 alibaba java coding guide 阿里巴巴代码规范插件,自动检查代码规范问题 ![在这里插 ...
- 第三十四篇:在SOUI中使用异步通知
概述 异步通知是客户端开发中常见的需求,比如在一个网络处理线程中要通知UI线程更新等等. 通常在Windows编程中,为了方便,我们一般会向UI线程的窗口句柄Post/Send一个窗口消息从而达到将非 ...
- 【opencv学习笔记】第五篇:访问图像中像素的三种方式、ROI区域图像叠加和图像混合
1. 访问图像中像素的三种方式 任何图像处理算法,都是从操作每个像素开始的.在OpenCV中,提供了三种访问每个像素的方法. 方法1:指针访问:C操作符[] 方法2:迭代器iterator 方法3:动 ...
- Go实现Raft第四篇:持久化和调优
女主宣言 今天小编为大家分享一篇关于Golang实现Raft的文章,本篇文章为系列中的第四篇,对Raft中通过添加持久性和一些优化来完成Raft的基本实现.希望能对大家有所帮助. PS:丰富的一线技术 ...
- 最简单人工智能python_Python人工智能之路 - 第四篇 : jieba gensim 最好别分家之最简单的相似度实现...
简单的问答已经实现了,那么问题也跟着出现了,我不能确定问题一定是"你叫什么名字",也有可能是"你是谁","你叫啥"之类的,这就引出了人工智能 ...
- SpringBoot启动流程分析(四):IoC容器的初始化过程
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- 第四篇:整合Thymeleaf模板
第四篇:整合Thymeleaf模板 本文链接:http://blog.battcn.com/2018/04/28/springboot/v2-web-thymeleaf/ 在前面几章中已经介绍了如何创 ...
- SpringCloud核心教程 | 第四篇:服务注册与发现 Consul篇
Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...
最新文章
- 洗礼灵魂,修炼python(70)--爬虫篇—补充知识:json模块
- Mongodb主从配置
- Xcode:Foundation框架找不到,或者是自动提示出现问题
- Tomcat 配置详解/优化方案
- postgreSQL源码分析——索引的建立与使用——GIST索引(1)
- (转载)设计模式之-策略模式(Strategy)
- Java Web 开发详解
- webpack使用笔记
- android原生browser分析(一)--Application
- Word控件Spire.Doc 转换教程(四):如何将 Word 转换为文本
- 手机迅雷打不开html,迅雷打不开了怎么办
- 全面剖析雅虎助手以及网络实名的流氓行径(5)
- sudo chmod 755 ....指令分析
- NetScaler AG自定义用户门户
- python处理金融数据_Python金融大数据分析-数据获取与简单处理
- Apache ServiceComb Kie | 一个语义型配置中心
- FastDFS 系统架构和功能原理
- IPv6基本配置(华为设备)
- Vue3.x 报 Uncaught TypeError:Object(...) is not a function( Vue3对象不是函数解决思路)
- 移动电力猫HG260GT pon实现路由拨号
热门文章
- selenium webdriver实战宝典 pdf_Selenium+webdriver爬虫技术实战之沃运维报表提取
- android 判断主线程_腾讯Android面试:Handler中有Loop死循环,为什么没有阻塞主线程...
- 数据中心淘汰服务器,浅谈数据中心危机严重的程度
- css3中2D变形tranform总结(附实例)
- centos 7 install VirtualBox
- 【TensorFlow系列】【九】利用tf.py_func自定义算子
- Centos yum安装snmp
- Convert.ToInt32、(int)和int.Parse 三者的区别 转
- python字符串以什么为结束符_Python代码中 如何判断字符串是否使用指定字符结尾(endswith)呢?...
- python股票_十分钟学会用Python交易股票