YuXuan
发布于 2020-08-30 / 14 阅读
0

MongoDB应用实战

MongoDB的适用场景

  • 网站数据:Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  • 缓存:由于性能很高,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
  • 大尺寸、低价值的数据:使用传统的关系型数据库存储一些大尺寸低价值数据时会比较浪费,在此之前,很多时候程序员往往会选择传统的文件进行存储。
  • 高伸缩性的场景:Mongo 非常适合由数十或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置支持以及集群高可用的解决方案。
  • 用于对象及JSON 数据的存储:Mongo 的BSON 数据格式非常适合文档化格式的存储及查询。

MongoDB的行业具体应用场景

  • 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新。
  • 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
  • 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
  • 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。
  • 直播,使用 MongoDB 存储用户信息、礼物信息等。

如何抉择是否使用MongoDB

应用特征Yes/No
应用不需要事务及复杂 join 支持必须Yes
新应用,需求会变,数据模型无法确定,想快速迭代开发
应用需要2000-3000以上的读写QPS(更高也可以)
应用需要TB甚至 PB 级别数据存储
应用发展迅速,需要能快速水平扩展
应用要求存储的数据不丢失
应用需要99.999%高可用
应用需要大量的地理位置查询、文本查询

一般情况下,满足上面2条及以上就可以选用MongoDB

Java访问MongoDB

maven 依赖

<dependency>
  <groupId>org.mongodb</groupId>
  <artifactId>mongo-java-driver</artifactId>
  <version>3.10.1</version>
</dependency>

文档添加

MongoClient mongoClient = new MongoClient("192.168.211.133", 37017);
MongoDatabase database = mongoClient.getDatabase("mg");
MongoCollection<Document> collection = database.getCollection("mg_preview");
Document document = Document.parse("{name:'lisi',city:'bj',birth_day:new ISODate('2001-08-01'),expectSalary:18000}");
collection.insertOne(document);
mongoClient.close();

文档查询

MongoClient mongoClient = new MongoClient("192.168.211.133", 37017);
MongoDatabase database = mongoClient.getDatabase("mg");
MongoCollection<Document> collection = database.getCollection("mg_preview");
Document sdoc = new Document();
//按expectSalary倒序
sdoc.append("expectSalary", -1);
FindIterable<Document> findIterable = collection.find().sort(sdoc);
for (Document document : findIterable) {
  System.out.println(document);
}
mongoClient.close();

文档查询过滤

MongoClient mongoClient = new MongoClient("192.168.211.133", 37017);
MongoDatabase database = mongoClient.getDatabase("mg");
MongoCollection<Document> collection = database.getCollection("mg_preview");
Document sdoc=new Document();
//按expectSalary倒序
sdoc.append("expectSalary", -1);
FindIterable<Document> findIterable = collection.find(Filters.gt("expectSalary",21000)).sort(sdoc);
for (Document document : findIterable) {
  System.out.println(document);
}
mongoClient.close();

Spring访问MongoDB

  1. 基于maven新建工程,导入依赖的包
<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-mongodb</artifactId>
  <version>2.0.9.RELEASE</version>
</dependency>
  1. 在配置文件中配置 MongoTemplate
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/data/mongo
         http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">

<!-- 构建MongoDb工厂对象 -->
<mongo:db-factory id="mongoDbFactory" client-uri="mongodb://192.168.211.133:37017/mg"></mongo:db-factory>
<!-- 构建 MongoTemplate 类型的对象 -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
  <constructor-arg index="0" ref="mongoDbFactory"></constructor-arg>
</bean>
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.mgtest"></context:component-scan>

</beans>
  1. 创建实体类,dao实现类注入 MongoTemplate 完成增删改查
@Autowired
private MongoTemplate mongoTemplate;

@Override
public void insertxxx(实体 xxx){
  mongoTemplate.insert(xxx);
}

@Override
public List<实体> findList(String name){
  Query query = new Query();
  query.addCriteria(Criteria.where("name").is(name));
  List<实体> datas = mongoTemplate.find(query, 实体.class, "mg_datas");
  return datas;
}
  1. 从Spring容器中获取dao对象进行测试 (注意:要开启组件扫描)
    注:实体类的id(_id)等同于MongoDB中的_id,如果set了值,那么MongoDB就不会产生_id,如果没有set值,那么MongoDB会自动生成一个_id
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
Dao dao = applicationContext.getBean(实体.class);
//TODO 此处set值
dao.insertxxx(实体);
dao.findList(name);

Spring Boot 访问 MongoDB

MongoTemplate 的方式

  1. 基于maven新建springboot工程
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
  <version>2.2.2.RELEASE</version>
</dependency>
  1. 配置文件application.properties
spring.data.mongodb.host=192.168.211.133
spring.data.mongodb.port=37017
spring.data.mongodb.database=mg
  1. 创建实体类,dao实现类注入 MongoTemplate 完成增删改查
@Autowired
private MongoTemplate mongoTemplate;

@Override
public void insertxxx(实体 xxx){
  mongoTemplate.insert(xxx);
}

@Override
public List<实体> findList(String name){
  Query query = new Query();
  query.addCriteria(Criteria.where("name").is(name));
  List<实体> datas = mongoTemplate.find(query, 实体.class, "mg_datas");
  return datas;
}
  1. 从Spring容器中获取dao对象进行测试
    注:实体类的id(_id)等同于MongoDB中的_id,如果set了值,那么MongoDB就不会产生_id,如果没有set值,那么MongoDB会自动生成一个_id
    启动类main方法中:
ApplicationContext applicationContext = SpringApplication.run(启动类.class, args);
Dao dao = applicationContext.getBean(实体.class);
//TODO 此处set值
dao.insertxxx(实体);
dao.findList(name);

MongoRepository 的方式

  1. 基于maven新建springboot工程
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
  <version>2.2.2.RELEASE</version>
</dependency>
  1. 配置文件application.properties
spring.data.mongodb.host=192.168.211.133
spring.data.mongodb.port=37017
spring.data.mongodb.database=mg
  1. 编写实体类,并在实体类上打@Document(“集合名”)
  2. 编写 Repository 接口,继承 MongoRepository
    方法具体参考:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
    如果内置方法不够用,就自己定义
    如:定义find|read|get 等开头的方法进行查询
  3. 从Spring容器中获取Repository对象进行测试