• MongoDB 应用实战


    1、MongoDB的适用场景

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

    2、MongoDB的行业具体应用场景

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

    3、如何抉择是否使用MongoDB

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

    4、Java 访问MongoDB

    (1)导入依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <groupId>com.lagougroupId>
    7. <artifactId>mongo_java_demoartifactId>
    8. <version>1.0-SNAPSHOTversion>
    9. <dependencies>
    10. <dependency>
    11. <groupId>org.mongodbgroupId>
    12. <artifactId>mongo-java-driverartifactId>
    13. <version>3.12.11version>
    14. dependency>
    15. dependencies>
    16. <build>
    17. <plugins>
    18. <plugin>
    19. <groupId>org.apache.maven.pluginsgroupId>
    20. <artifactId>maven-compiler-pluginartifactId>
    21. <version>3.5.1version>
    22. <configuration>
    23. <source>1.8source>
    24. <target>1.8target>
    25. configuration>
    26. plugin>
    27. plugins>
    28. build>
    29. project>

    (2)文档添加操作

    1. package com.lagou.test;
    2. import com.mongodb.MongoClient;
    3. import com.mongodb.client.MongoCollection;
    4. import com.mongodb.client.MongoDatabase;
    5. import org.bson.Document;
    6. public class DocumentInsertTest {
    7. public static void main(String[] args) {
    8. MongoClient mongoClient = new MongoClient("127.0.0.1:27017");
    9. // 获取数据库对象
    10. MongoDatabase mongoDatabase = mongoClient.getDatabase("lg_resume");
    11. // 获取集合对象
    12. MongoCollection collection = mongoDatabase.getCollection("lg_resume_preview");
    13. // 构建Document对象,并插入到集合中
    14. Document document = Document.parse("{name:'lisi', city:'北京',birthday:new ISODate('2000-06-08'), expectSalary:19999}");
    15. collection.insertOne(document);
    16. mongoClient.close();
    17. }
    18. }

    (3)文档查询操作

    1. package com.lagou.test;
    2. import com.mongodb.MongoClient;
    3. import com.mongodb.client.FindIterable;
    4. import com.mongodb.client.MongoCollection;
    5. import com.mongodb.client.MongoDatabase;
    6. import org.bson.Document;
    7. public class DocumentFindTest {
    8. public static void main(String[] args) {
    9. MongoClient mongoClient = new MongoClient("127.0.0.1:27017");
    10. // 获取数据库对象
    11. MongoDatabase mongoDatabase = mongoClient.getDatabase("lg_resume");
    12. // 获取集合对象
    13. MongoCollection collection = mongoDatabase.getCollection("lg_resume_preview");
    14. //按expectSalary降序排列
    15. Document sortDocument = new Document();
    16. // 塞入排序条件
    17. sortDocument.append("expectSalary", -1);
    18. // 直接调用find方法查询的是所有
    19. FindIterable findIterable = collection.find().sort(sortDocument);
    20. for (Document document : findIterable) {
    21. System.out.println(document);
    22. }
    23. mongoClient.close();
    24. }
    25. }

    (4)文档查询过滤

    1. package com.lagou.test;
    2. import com.mongodb.MongoClient;
    3. import com.mongodb.client.FindIterable;
    4. import com.mongodb.client.MongoCollection;
    5. import com.mongodb.client.MongoDatabase;
    6. import com.mongodb.client.model.Filters;
    7. import org.bson.Document;
    8. public class DocumentFiltersTest {
    9. public static void main(String[] args) {
    10. MongoClient mongoClient = new MongoClient("127.0.0.1:27017");
    11. // 获取数据库对象
    12. MongoDatabase mongoDatabase = mongoClient.getDatabase("lg_resume");
    13. // 获取集合对象
    14. MongoCollection collection = mongoDatabase.getCollection("lg_resume_preview");
    15. // 按expectSalary降序排列
    16. Document sortDocument = new Document();
    17. // 塞入排序条件
    18. sortDocument.append("expectSalary", -1);
    19. // FindIterable findIterable = collection.find(Document.parse("{expectSalary:{$gt:15000}}")).sort(sortDocument); // 这种方式使用的是mongo原生的过滤方式
    20. // 这种是Java给我们提供一个Filters过滤器类,通过调用里面的方法完成条件查询操作
    21. FindIterable findIterable = collection.find(Filters.gt("expectSalary", 15000)).sort(sortDocument);
    22. for (Document document : findIterable) {
    23. System.out.println(document);
    24. }
    25. mongoClient.close();
    26. }
    27. }

    5、Spring 访问MongoDB

    (1)导入依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <groupId>com.lagougroupId>
    7. <artifactId>mongo_spring_demoartifactId>
    8. <version>1.0-SNAPSHOTversion>
    9. <dependencies>
    10. <dependency>
    11. <groupId>org.springframework.datagroupId>
    12. <artifactId>spring-data-mongodbartifactId>
    13. <version>2.0.9.RELEASEversion>
    14. dependency>
    15. dependencies>
    16. <build>
    17. <plugins>
    18. <plugin>
    19. <groupId>org.apache.maven.pluginsgroupId>
    20. <artifactId>maven-compiler-pluginartifactId>
    21. <version>3.5.1version>
    22. <configuration>
    23. <source>1.8source>
    24. <target>1.8target>
    25. configuration>
    26. plugin>
    27. plugins>
    28. build>
    29. project>

    (2)创建applicationContext.xml配置文件

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    6. xsi:schemaLocation="
    7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    8. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    9. http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
    10. <mongo:db-factory id="mongoDbFactory" client-uri="mongodb://127.0.0.1:27017/lg_resume"/>
    11. <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    12. <constructor-arg index="0" ref="mongoDbFactory"/>
    13. bean>
    14. <context:component-scan base-package="com.lagou"/>
    15. beans>

    (3)创建映射实体类

    1. package com.lagou.bean;
    2. import java.util.Date;
    3. public class Resume {
    4. private String id; // 注意这里的id等同于MongoDB中的 _id
    5. private String name;
    6. private String city;
    7. private Date birthday;
    8. private double expectSalary;
    9. public Resume() {
    10. }
    11. public Resume(String id, String name, String city, Date birthday, double expectSalary) {
    12. this.id = id;
    13. this.name = name;
    14. this.city = city;
    15. this.birthday = birthday;
    16. this.expectSalary = expectSalary;
    17. }
    18. public String getId() {
    19. return id;
    20. }
    21. public void setId(String id) {
    22. this.id = id;
    23. }
    24. public String getName() {
    25. return name;
    26. }
    27. public void setName(String name) {
    28. this.name = name;
    29. }
    30. public String getCity() {
    31. return city;
    32. }
    33. public void setCity(String city) {
    34. this.city = city;
    35. }
    36. public Date getBirthday() {
    37. return birthday;
    38. }
    39. public void setBirthday(Date birthday) {
    40. this.birthday = birthday;
    41. }
    42. public double getExpectSalary() {
    43. return expectSalary;
    44. }
    45. public void setExpectSalary(double expectSalary) {
    46. this.expectSalary = expectSalary;
    47. }
    48. @Override
    49. public String toString() {
    50. return "Resume{" +
    51. "id='" + id + '\'' +
    52. ", name='" + name + '\'' +
    53. ", city='" + city + '\'' +
    54. ", birthday=" + birthday +
    55. ", expectSalary=" + expectSalary +
    56. '}';
    57. }
    58. }

    (4)创建接口

    1. package com.lagou.dao;
    2. import com.lagou.bean.Resume;
    3. import java.util.List;
    4. public interface ResumeDao {
    5. void insertResume(Resume resume);
    6. // 根据name获取resume对象
    7. Resume findByName(String name);
    8. // 根据name 和 expectSalary 进行多条件查询
    9. List findListByNameAndSalary(String name, int expectSalary);
    10. }

    (5)创建接口实现类

    1. package com.lagou.dao.impl;
    2. import com.lagou.bean.Resume;
    3. import com.lagou.dao.ResumeDao;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.data.mongodb.core.MongoTemplate;
    6. import org.springframework.data.mongodb.core.query.Criteria;
    7. import org.springframework.data.mongodb.core.query.Query;
    8. import org.springframework.stereotype.Repository;
    9. import java.util.List;
    10. @Repository("resumeDao")
    11. public class ResumeDaoImpl implements ResumeDao {
    12. @Autowired
    13. private MongoTemplate mongoTemplate;
    14. @Override
    15. public void insertResume(Resume resume) { // 不指定集合名时,默认集合名就是类型名首字母小写,也就是这里的resume
    16. // mongoTemplate.insert(resume);
    17. mongoTemplate.insert(resume, "lg_resume"); // 插入数据并且指定集合名
    18. }
    19. @Override
    20. public Resume findByName(String name) {
    21. // 构建查询对象
    22. Query query = new Query();
    23. // 向查询对象中封装数据
    24. query.addCriteria(Criteria.where("name").is(name));
    25. return mongoTemplate.findOne(query, Resume.class, "lg_resume"); // 使用findOne方法查询某一字段时,必须要保证该字段唯一否则就会报错,若该字段不为一时,使用find方法
    26. }
    27. @Override
    28. public List findListByNameAndSalary(String name, int expectSalary) {
    29. Query query = new Query();
    30. // 封装条件,根据名字进行查询并且expectSalary大于传入的期望薪水,
    31. query.addCriteria(Criteria.where("name").is(name).andOperator(Criteria.where("expectSalary").gt(expectSalary)));
    32. return mongoTemplate.find(query, Resume.class, "lg_resume");
    33. }
    34. }

    (6)调用方法,进行测试

    1. package com.lagou;
    2. import com.lagou.bean.Resume;
    3. import com.lagou.dao.ResumeDao;
    4. import org.springframework.context.support.ClassPathXmlApplicationContext;
    5. import java.text.ParseException;
    6. import java.text.SimpleDateFormat;
    7. import java.util.Date;
    8. import java.util.List;
    9. public class MongoTemplateMain {
    10. public static void main(String[] args) {
    11. ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    12. ResumeDao resumeDao = applicationContext.getBean("resumeDao", ResumeDao.class);
    13. /* Resume resume = new Resume();
    14. // resume.setId("1010111"); // 如果我们这里设置了id值,那么MongoDB就不会在为我们产生id值了
    15. resume.setName("Jack");
    16. resume.setCity("chongqing");
    17. Date date = null;
    18. String dateStr = "yy-MM-dd hh:mm:ss";
    19. SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateStr);
    20. try {
    21. date = simpleDateFormat.parse("2022-9-13 17:20:15");
    22. } catch (ParseException e) {
    23. throw new RuntimeException(e);
    24. }
    25. resume.setBirthday(date);
    26. resume.setExpectSalary(28000);
    27. resumeDao.insertResume(resume); */
    28. Resume resume = resumeDao.findByName("Jack");
    29. System.out.println(resume);
    30. List list = resumeDao.findListByNameAndSalary("Jack", 200000);
    31. System.out.println(list.toString());
    32. }
    33. }

    (7)注意:如果我们想要保持某一字段的唯一性(也就是不能进行重复插入相同数据),可以给该字段创建索引,并添加属性unique

    db.集合名.createIndex({字段名:排序条件}, {unique:true})

    这样创建索引之后,如果我们重复插入相同数据时,则会报错。

    6、Spring Boot 访问 MongoDB

    方式一:MongoTemplate 的方式

    注意:使用这种方式大部分步骤都与spring方式访问MongoDB相同,因此下面我只介绍其不同的部分,两者相同的部分,就省略了

    (1)导入依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <groupId>com.lagougroupId>
    7. <artifactId>mongo_springboot_templateartifactId>
    8. <version>1.0-SNAPSHOTversion>
    9. <dependencies>
    10. <dependency>
    11. <groupId>org.springframework.bootgroupId>
    12. <artifactId>spring-boot-starter-data-mongodbartifactId>
    13. <version>2.2.2.RELEASEversion>
    14. dependency>
    15. dependencies>
    16. <build>
    17. <plugins>
    18. <plugin>
    19. <groupId>org.apache.maven.pluginsgroupId>
    20. <artifactId>maven-compiler-pluginartifactId>
    21. <version>3.5.1version>
    22. <configuration>
    23. <source>1.8source>
    24. <target>1.8target>
    25. configuration>
    26. plugin>
    27. plugins>
    28. build>
    29. project>

    (2)创建配置文件application.yml

    1. spring:
    2. data:
    3. mongodb:
    4. host: 8.142.8.105
    5. port: 27017
    6. database: lg_resume

    (3)启动类,进行方法测试

    1. package com.lagou;
    2. import com.lagou.bean.Resume;
    3. import com.lagou.dao.ResumeDao;
    4. import org.springframework.boot.SpringApplication;
    5. import org.springframework.boot.autoconfigure.SpringBootApplication;
    6. import org.springframework.context.ApplicationContext;
    7. import org.springframework.context.ConfigurableApplicationContext;
    8. import org.springframework.context.support.ClassPathXmlApplicationContext;
    9. import java.text.SimpleDateFormat;
    10. import java.util.Date;
    11. import java.util.List;
    12. @SpringBootApplication
    13. public class MongoTemplateMain {
    14. public static void main(String[] args) {
    15. /* ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");*/ // spring方式获取bean
    16. ApplicationContext applicationContext = SpringApplication.run(MongoTemplateMain.class, args); // SpringBoot方式获取bean
    17. ResumeDao resumeDao = applicationContext.getBean("resumeDao", ResumeDao.class);
    18. /* Resume resume = new Resume();
    19. // resume.setId("1010111"); // 如果我们这里设置了id值,那么MongoDB就不会在为我们产生id值了
    20. resume.setName("Jack");
    21. resume.setCity("chongqing");
    22. Date date = null;
    23. String dateStr = "yy-MM-dd hh:mm:ss";
    24. SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateStr);
    25. try {
    26. date = simpleDateFormat.parse("2022-9-13 17:20:15");
    27. } catch (Exception e) {
    28. throw new RuntimeException(e);
    29. }
    30. resume.setBirthday(date);
    31. resume.setExpectSalary(28000);
    32. resumeDao.insertResume(resume); */
    33. Resume resume = resumeDao.findByName("Jack");
    34. System.out.println(resume);
    35. List list = resumeDao.findListByNameAndSalary("Jack", 200);
    36. System.out.println(list.toString());
    37. }
    38. }

    方式二:MongoRepository 的方式

    (1)导入依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <groupId>com.lagougroupId>
    7. <artifactId>mongo_springboot_repositoryartifactId>
    8. <version>1.0-SNAPSHOTversion>
    9. <dependencies>
    10. <dependency>
    11. <groupId>org.springframework.bootgroupId>
    12. <artifactId>spring-boot-starter-data-mongodbartifactId>
    13. <version>2.2.2.RELEASEversion>
    14. dependency>
    15. dependencies>
    16. <build>
    17. <plugins>
    18. <plugin>
    19. <groupId>org.apache.maven.pluginsgroupId>
    20. <artifactId>maven-compiler-pluginartifactId>
    21. <version>3.5.1version>
    22. <configuration>
    23. <source>1.8source>
    24. <target>1.8target>
    25. configuration>
    26. plugin>
    27. plugins>
    28. build>
    29. project>

    (2)创建application.yml配置文件

    1. spring:
    2. data:
    3. mongodb:
    4. host: 8.142.8.105
    5. port: 27017
    6. database: lg_resume

    (3)编写实体类 并在实体类上打@Document(“集合名”)

    这个与上面的几种方式都不同

    1. package com.lagou.bean;
    2. import org.springframework.data.mongodb.core.mapping.Document;
    3. import java.util.Date;
    4. @Document("lg_resume") // 指定集合名
    5. public class Resume {
    6. private String id; // 注意这里的id等同于MongoDB中的 _id
    7. private String name;
    8. private String city;
    9. private Date birthday;
    10. private double expectSalary;
    11. public Resume() {
    12. }
    13. public Resume(String id, String name, String city, Date birthday, double expectSalary) {
    14. this.id = id;
    15. this.name = name;
    16. this.city = city;
    17. this.birthday = birthday;
    18. this.expectSalary = expectSalary;
    19. }
    20. public String getId() {
    21. return id;
    22. }
    23. public void setId(String id) {
    24. this.id = id;
    25. }
    26. public String getName() {
    27. return name;
    28. }
    29. public void setName(String name) {
    30. this.name = name;
    31. }
    32. public String getCity() {
    33. return city;
    34. }
    35. public void setCity(String city) {
    36. this.city = city;
    37. }
    38. public Date getBirthday() {
    39. return birthday;
    40. }
    41. public void setBirthday(Date birthday) {
    42. this.birthday = birthday;
    43. }
    44. public double getExpectSalary() {
    45. return expectSalary;
    46. }
    47. public void setExpectSalary(double expectSalary) {
    48. this.expectSalary = expectSalary;
    49. }
    50. @Override
    51. public String toString() {
    52. return "Resume{" +
    53. "id='" + id + '\'' +
    54. ", name='" + name + '\'' +
    55. ", city='" + city + '\'' +
    56. ", birthday=" + birthday +
    57. ", expectSalary=" + expectSalary +
    58. '}';
    59. }
    60. }

    (3)编写 Repository 接口 继承 MongoRepository

    1. package com.lagou.repository;
    2. import com.lagou.bean.Resume;
    3. import org.springframework.data.mongodb.repository.MongoRepository;
    4. import java.util.List;
    5. public interface ResumeRepository extends MongoRepository {
    6. // 指定根据名字进行查询
    7. List findByNameEquals(String name);
    8. }

            注:这种方式与JPA类似都是继承一个接口,然后就可以使用它里面自带的方法,如果内置方法不够用就自己定义 如:定义find|read|get 等开头的方法进行查询。

    详细定义格式:请点击

    (4)从Spring容器中获取Repository对象,进行测试

    1. package com.lagou;
    2. import com.lagou.bean.Resume;
    3. import com.lagou.repository.ResumeRepository;
    4. import org.springframework.boot.SpringApplication;
    5. import org.springframework.boot.autoconfigure.SpringBootApplication;
    6. import org.springframework.context.ApplicationContext;
    7. import java.util.List;
    8. @SpringBootApplication
    9. public class MongoRepositoryMain {
    10. public static void main(String[] args) {
    11. ApplicationContext applicationContext = SpringApplication.run(MongoRepositoryMain.class, args);
    12. ResumeRepository resumeRepository = applicationContext.getBean(ResumeRepository.class);
    13. List list = resumeRepository.findAll();
    14. System.out.println(list);
    15. System.out.println(resumeRepository.findByNameEquals("Jack"));
    16. }
    17. }
  • 相关阅读:
    Mac安装Mysql,并启动
    Ant design table实现单选和点击行选中
    太神了!开源大佬的SpringBoot+微服务架构笔记,一般人真肝不出来
    LeaRun.Java快速开发平台 高效代码自动化生成
    go-zero整合单机版ClickHouse并实现增删改查
    [操作系统笔记]基本分页存储管理
    python常用命令
    【Android 标题文字居中 快速实现】
    LLM推理入门指南②:深入解析KV缓存
    零售商贩mysql表设计:banner管理表
  • 原文地址:https://blog.csdn.net/weixin_52851967/article/details/126845269