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)导入依赖



    4.0.0
    
    com.lagou
    mongo_java_demo
    1.0-SNAPSHOT
    
    
        
            org.mongodb
            mongo-java-driver
            3.12.11
        
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.5.1
                
                    1.8
                    1.8
                
            
        
    

(2)文档添加操作

package com.lagou.test;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

public class DocumentInsertTest {
    public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("127.0.0.1:27017");
        // 获取数据库对象
        MongoDatabase mongoDatabase = mongoClient.getDatabase("lg_resume");
        // 获取集合对象
        MongoCollection collection = mongoDatabase.getCollection("lg_resume_preview");
        // 构建Document对象,并插入到集合中
        Document document = Document.parse("{name:'lisi', city:'北京',birthday:new ISODate('2000-06-08'), expectSalary:19999}");
        collection.insertOne(document);
        mongoClient.close();
    }
}

(3)文档查询操作

package com.lagou.test;

import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

public class DocumentFindTest {
    public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("127.0.0.1:27017");
        // 获取数据库对象
        MongoDatabase mongoDatabase = mongoClient.getDatabase("lg_resume");
        // 获取集合对象
        MongoCollection collection = mongoDatabase.getCollection("lg_resume_preview");
        //按expectSalary降序排列
        Document sortDocument = new Document();
        // 塞入排序条件
        sortDocument.append("expectSalary", -1);
        // 直接调用find方法查询的是所有
        FindIterable findIterable = collection.find().sort(sortDocument);
        for (Document document : findIterable) {
            System.out.println(document);
        }
        mongoClient.close();
    }
}

(4)文档查询过滤

package com.lagou.test;

import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import org.bson.Document;

public class DocumentFiltersTest {
    public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("127.0.0.1:27017");
        // 获取数据库对象
        MongoDatabase mongoDatabase = mongoClient.getDatabase("lg_resume");
        // 获取集合对象
        MongoCollection collection = mongoDatabase.getCollection("lg_resume_preview");
        // 按expectSalary降序排列
        Document sortDocument = new Document();
        // 塞入排序条件
        sortDocument.append("expectSalary", -1);
        // FindIterable findIterable = collection.find(Document.parse("{expectSalary:{$gt:15000}}")).sort(sortDocument); // 这种方式使用的是mongo原生的过滤方式
        // 这种是Java给我们提供一个Filters过滤器类,通过调用里面的方法完成条件查询操作
        FindIterable findIterable = collection.find(Filters.gt("expectSalary", 15000)).sort(sortDocument);
        for (Document document : findIterable) {
            System.out.println(document);
        }
        mongoClient.close();
    }
}

5、Spring 访问MongoDB

(1)导入依赖



    4.0.0
    
    com.lagou
    mongo_spring_demo
    1.0-SNAPSHOT
    
    
        
            org.springframework.data
            spring-data-mongodb
            2.0.9.RELEASE
        
    
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.5.1
                
                    1.8
                    1.8
                
            
        
    

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



    
    
    
    
        
    
    
    

(3)创建映射实体类

package com.lagou.bean;

import java.util.Date;

public class Resume {
    private String id; // 注意这里的id等同于MongoDB中的 _id
    private String name;
    private String city;
    private Date birthday;
    private double expectSalary;

    public Resume() {
    }

    public Resume(String id, String name, String city, Date birthday, double expectSalary) {
        this.id = id;
        this.name = name;
        this.city = city;
        this.birthday = birthday;
        this.expectSalary = expectSalary;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public double getExpectSalary() {
        return expectSalary;
    }

    public void setExpectSalary(double expectSalary) {
        this.expectSalary = expectSalary;
    }

    @Override
    public String toString() {
        return "Resume{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", city='" + city + '\'' +
                ", birthday=" + birthday +
                ", expectSalary=" + expectSalary +
                '}';
    }
}

(4)创建接口

package com.lagou.dao;

import com.lagou.bean.Resume;

import java.util.List;

public interface ResumeDao {
    void insertResume(Resume resume);

    // 根据name获取resume对象
    Resume findByName(String name);

    // 根据name 和 expectSalary 进行多条件查询
    List findListByNameAndSalary(String name, int expectSalary);

}

(5)创建接口实现类

package com.lagou.dao.impl;

import com.lagou.bean.Resume;
import com.lagou.dao.ResumeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository("resumeDao")
public class ResumeDaoImpl implements ResumeDao {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void insertResume(Resume resume) { // 不指定集合名时,默认集合名就是类型名首字母小写,也就是这里的resume
        // mongoTemplate.insert(resume);
        mongoTemplate.insert(resume, "lg_resume"); // 插入数据并且指定集合名
    }

    @Override
    public Resume findByName(String name) {
        // 构建查询对象
        Query query = new Query();
        // 向查询对象中封装数据
        query.addCriteria(Criteria.where("name").is(name));
        return mongoTemplate.findOne(query, Resume.class, "lg_resume"); // 使用findOne方法查询某一字段时,必须要保证该字段唯一否则就会报错,若该字段不为一时,使用find方法
    }

    @Override
    public List findListByNameAndSalary(String name, int expectSalary) {
        Query query = new Query();
        // 封装条件,根据名字进行查询并且expectSalary大于传入的期望薪水,
        query.addCriteria(Criteria.where("name").is(name).andOperator(Criteria.where("expectSalary").gt(expectSalary)));
        return mongoTemplate.find(query, Resume.class, "lg_resume");
    }
}

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

package com.lagou;

import com.lagou.bean.Resume;
import com.lagou.dao.ResumeDao;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class MongoTemplateMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        ResumeDao resumeDao = applicationContext.getBean("resumeDao", ResumeDao.class);
      /*   Resume resume = new Resume();
        // resume.setId("1010111"); // 如果我们这里设置了id值,那么MongoDB就不会在为我们产生id值了
        resume.setName("Jack");
        resume.setCity("chongqing");
        Date date = null;
        String dateStr = "yy-MM-dd hh:mm:ss";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateStr);
        try {
            date = simpleDateFormat.parse("2022-9-13 17:20:15");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        resume.setBirthday(date);
        resume.setExpectSalary(28000);
        resumeDao.insertResume(resume); */

        Resume resume = resumeDao.findByName("Jack");
        System.out.println(resume);

        List list = resumeDao.findListByNameAndSalary("Jack", 200000);
        System.out.println(list.toString());
    }
}

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

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

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

6、Spring Boot 访问 MongoDB

方式一:MongoTemplate 的方式

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

(1)导入依赖



    4.0.0
    
    com.lagou
    mongo_springboot_template
    1.0-SNAPSHOT
    
    
        
            org.springframework.boot
            spring-boot-starter-data-mongodb
            2.2.2.RELEASE
        
    
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.5.1
                
                    1.8
                    1.8
                
            
        
    

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

spring:
  data:
    mongodb:
      host: 8.142.8.105
      port: 27017
      database: lg_resume

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

package com.lagou;

import com.lagou.bean.Resume;
import com.lagou.dao.ResumeDao;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@SpringBootApplication
public class MongoTemplateMain {
    public static void main(String[] args) {
        /*  ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");*/  // spring方式获取bean
        ApplicationContext applicationContext = SpringApplication.run(MongoTemplateMain.class, args); // SpringBoot方式获取bean
        ResumeDao resumeDao = applicationContext.getBean("resumeDao", ResumeDao.class);

       /*  Resume resume = new Resume();
        // resume.setId("1010111"); // 如果我们这里设置了id值,那么MongoDB就不会在为我们产生id值了
        resume.setName("Jack");
        resume.setCity("chongqing");
        Date date = null;
        String dateStr = "yy-MM-dd hh:mm:ss";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateStr);
        try {
            date = simpleDateFormat.parse("2022-9-13 17:20:15");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        resume.setBirthday(date);
        resume.setExpectSalary(28000);
        resumeDao.insertResume(resume); */

        Resume resume = resumeDao.findByName("Jack");
        System.out.println(resume);

        List list = resumeDao.findListByNameAndSalary("Jack", 200);
        System.out.println(list.toString());
    }
}

方式二:MongoRepository 的方式

(1)导入依赖



    4.0.0
    
    com.lagou
    mongo_springboot_repository
    1.0-SNAPSHOT
    
    
        
            org.springframework.boot
            spring-boot-starter-data-mongodb
            2.2.2.RELEASE
        
    
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.5.1
                
                    1.8
                    1.8
                
            
        
    

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

spring:
  data:
    mongodb:
      host: 8.142.8.105
      port: 27017
      database: lg_resume

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

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

package com.lagou.bean;

import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

@Document("lg_resume") // 指定集合名
public class Resume {
    private String id; // 注意这里的id等同于MongoDB中的 _id
    private String name;
    private String city;
    private Date birthday;
    private double expectSalary;

    public Resume() {
    }

    public Resume(String id, String name, String city, Date birthday, double expectSalary) {
        this.id = id;
        this.name = name;
        this.city = city;
        this.birthday = birthday;
        this.expectSalary = expectSalary;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public double getExpectSalary() {
        return expectSalary;
    }

    public void setExpectSalary(double expectSalary) {
        this.expectSalary = expectSalary;
    }

    @Override
    public String toString() {
        return "Resume{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", city='" + city + '\'' +
                ", birthday=" + birthday +
                ", expectSalary=" + expectSalary +
                '}';
    }
}

(3)编写 Repository 接口 继承 MongoRepository

package com.lagou.repository;

import com.lagou.bean.Resume;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

public interface ResumeRepository extends MongoRepository {
    // 指定根据名字进行查询
    List findByNameEquals(String name);
}

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

详细定义格式:请点击

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

package com.lagou;

import com.lagou.bean.Resume;
import com.lagou.repository.ResumeRepository;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import java.util.List;

@SpringBootApplication
public class MongoRepositoryMain {
    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(MongoRepositoryMain.class, args);
        ResumeRepository resumeRepository = applicationContext.getBean(ResumeRepository.class);
        List list = resumeRepository.findAll();
        System.out.println(list);
        System.out.println(resumeRepository.findByNameEquals("Jack"));

    }
}

你可能感兴趣的:(NoSQL,mongodb,nosql,spring,boot,spring,java)