MongoDB的适用场景
● 网站数据:Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
● 缓存:由于性能很高,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
● 大尺寸、低价值的数据:使用传统的关系型数据库存储一些大尺寸低价值数据时会比较浪费,在此之前,很多时候程序员往往会选择传统的文件进行存储。
● 高伸缩性的场景:Mongo 非常适合由数十或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置支持以及集群高可用的解决方案。
● 用于对象及JSON 数据的存储:Mongo 的BSON 数据格式非常适合文档化格式的存储及查询。
MongoDB的行业具体应用场景
-
游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新。
-
物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
-
社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
-
物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。
-
直播,使用 MongoDB 存储用户信息、礼物信息等。
如何抉择是否使用MongoDB
满足第一项的时候可以考虑用MongoDB,这一项必须满足,如果后面的特征同时满足两条以上强烈建议使用MongoDB
应用特征 | Yes / No |
---|---|
应用不需要事务及复杂 join 支持必须 | Yes |
新应用,需求会变,数据模型无法确定,想快速迭代开发 | ? |
应用需要2000-3000以上的读写QPS(更高也可以) | ? |
应用需要TB甚至 PB 级别数据存储 | ? |
应用发展迅速,需要能快速水平扩展 | ? |
应用要求存储的数据不丢失 | ? |
应用需要99.999%高可用 | ? |
应用需要大量的地理位置查询、文本查询 | ? |
Java 访问MongoDB
插入测试
- 创建maven工程后添加maven依赖
<dependencies> <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.12.1</version> </dependency> </dependencies>
- 创建测试类
import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; /** * @program: MongoDB-study * @Description * @author Elvis * @date 2021-08-06 7:26 */ public class DocumentInsertTest { public static void main(String[] args) { MongoClient mongoClient = new MongoClient("192.168.31.10"); MongoDatabase articledb = mongoClient.getDatabase("articledb"); MongoCollection<Document> comment = articledb.getCollection("comment"); Document document = Document.parse("{'articleid':'102135','content':'蟹炒年糕怎么做。','userid':'1003','nickname':'凯撒','createdatetime':new ISODate('2021-08-06'),'likenum':NumberInt(6666),'state':'1'}"); comment.insertOne(document); mongoClient.close(); } }
- 执行测试后查看数据内容
这里注意一个点,之前的一些版本,在其他的客户端工具中使用ISODate生成时间会以格林威治时间生成,提现到本地东八区的时间会加上8个小时
查询测试
public class DocumentFindTest {
public static void main(String[] args) {
MongoClient mongoClient = new MongoClient("192.168.31.10");
MongoDatabase articledb = mongoClient.getDatabase("articledb");
MongoCollection<Document> comment = articledb.getCollection("comment");
Document document = new Document();
// 要根据articleid 降序排列
document.append("articleid",-1);
FindIterable<Document> documents = comment.find().sort(document);
for (Document document1: documents) {
System.out.println(document1);
}
mongoClient.close();
}
}
过滤测试
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;
/**
* @program: MongoDB-study
* @Description
* @author Elvis
* @date 2021-08-06 19:43
*/
public class DocumentFindFilterTest {
public static void main(String[] args) {
MongoClient mongoClient = new MongoClient("192.168.31.10");
MongoDatabase articledb = mongoClient.getDatabase("articledb");
MongoCollection<Document> comment = articledb.getCollection("comment");
// 要根据articleid 降序排列
Document document = new Document();
document.append("articleid",-1);
//通过Filters进行过滤
FindIterable<Document> documents = comment.find(Filters.gt("likenum", 1000)).sort(document);
for (Document document1: documents) {
System.out.println(document1);
}
mongoClient.close();
}
}
Spring 访问MongoDB
- 创建工程后导入maven依赖
这里有个注意点,spring-data-mongodb尽量选用2.x版本的,3.x以上的版本需要引入其他的依赖后才可以使用
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.2.13.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<testTarget>11</testTarget>
<testSource>11</testSource>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
- 创建applicationContext.xml配置文件
<?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">
<mongo:db-factory id="mongoDbFactory" client-uri="mongodb://192.168.31.10:27017/articledb"></mongo:db-factory>
<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.elvis"></context:component-scan>
</beans>
- 创建实体类
public class Comment {
private String articleid;
private String content;
private String userid;
private String nickname;
private Date createdatetime;
private Integer likenum;
private String state;
public String getArticleid() {
return articleid;
}
public void setArticleid(String articleid) {
this.articleid = articleid;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Date getCreatedatetime() {
return createdatetime;
}
public void setCreatedatetime(Date createdatetime) {
this.createdatetime = createdatetime;
}
public Integer getLikenum() {
return likenum;
}
public void setLikenum(Integer likenum) {
this.likenum = likenum;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public String toString() {
return "Comment{" +
"articleid='" + articleid + '\'' +
", content='" + content + '\'' +
", userid='" + userid + '\'' +
", nickname='" + nickname + '\'' +
", createdatetime=" + createdatetime +
", likenum=" + likenum +
", state='" + state + '\'' +
'}';
}
}
- 创建Dao接口和实现类
package com.elvis.dao;
import com.elvis.pojo.Comment;
import java.util.List;
/**
* @author Elvis
* @create 2021-08-06 22:01
*/
public interface CommentDao {
void insertComment(Comment comment);
/** 根据name 获取Resume 对象 */
Comment findByUserId(String userid);
List<Comment> findList(String userid);
/** 根据name 和 expectSalary 查询 */
List<Comment> findByUserIdAndLikeNum(String userid, Integer like);
}
package com.elvis.dao.impl;
/**
* @author Elvis
* @create 2021-08-06 22:04
*/
import com.elvis.dao.CommentDao;
import com.elvis.pojo.Comment;
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;
/**
* @program: MongoDB-study
* @Description
* @author Elvis
* @date 2021-08-06 22:04
*/
@Repository("CommentDao")
public class CommentDaoImpl implements CommentDao {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public void insertComment(Comment comment) {
mongoTemplate.insert(comment);
}
@Override
public Comment findByUserId(String userid) {
Query query = new Query();
query.addCriteria(Criteria.where("userid").is(userid));
List<Comment> comments = mongoTemplate.find(query, Comment.class);
return comments.isEmpty()?null:comments.get(0);
}
@Override
public List<Comment> findList(String userid) {
Query query = new Query();
query.addCriteria(Criteria.where("userid").is(userid));
List<Comment> comments = mongoTemplate.find(query, Comment.class);
return comments;
}
@Override
public List<Comment> findByUserIdAndLikeNum(String userid, Integer like) {
Query query = new Query();
query.addCriteria(Criteria.where("userid").is(userid).andOperator(Criteria.where("likenum").gt(like)));
List<Comment> comments = mongoTemplate.find(query, Comment.class, "comment");
return comments;
}
}
- 创建测试类
/**
* @author Elvis
* @create 2021-08-06 22:16
*/
import com.elvis.dao.CommentDao;
import com.elvis.pojo.Comment;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @program: MongoDB-study
* @Description
* @author Elvis
* @date 2021-08-06 22:16
*/
public class MongoTest {
ClassPathXmlApplicationContext applicationContext;
CommentDao commentDao;
@Before
public void before() {
applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
commentDao = (CommentDao) applicationContext.getBean("CommentDao");
}
@Test
public void testInsert() {
Comment comment = new Comment();
comment.setArticleid("1102155");
comment.setContent("早上不要睡懒觉");
comment.setUserid("1004");
comment.setNickname("杰克船长");
comment.setLikenum(1234);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = null;
try {
date = simpleDateFormat.parse("2021-08-06 12:32:56" );
} catch (ParseException e) {
e.printStackTrace();
}
comment.setCreatedatetime(date);
comment.setState("1");
commentDao.insertComment(comment);
}
@Test
public void testFind(){
Comment comment = commentDao.findByUserId("1004");
System.out.println(comment);
System.out.println("***************************************");
List<Comment> comments = commentDao.findList("1004");
for (Comment comment1: comments) {
System.out.println(comment1);
}
}
@Test
public void testFindMulti() {
List<Comment> comments = commentDao.findByUserIdAndLikeNum("1004", 1000);
for (Comment comment1: comments) {
System.out.println(comment1);
}
}
}
插入测试后查看数据库
查询测试
Spring Boot 访问 MongoDB
MongoTemplate 的方式
- 基于maven新建springboot工程
<parent>
<artifactId>spring-boot-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.2.9.RELEASE</version>
</parent>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<testTarget>11</testTarget>
<testSource>11</testSource>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
- 配置application.yaml
spring:
data:
mongodb:
host: 192.168.31.10
port: 27017
database: articledb
- 启动类
package com.elvis;
/**
* @author Elvis
* @create 2021-08-07 8:39
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @program: MongoDB-study
* @Description
* @author Elvis
* @date 2021-08-07 8:39
*/
@SpringBootApplication
public class RunBoot {
public static void main(String[] args) {
SpringApplication.run(RunBoot.class,args);
}
}
-
DAO 实现类 ,把上面部分的DAO层和实现类拷贝过来
-
注入 MongoTemplate 完成增删改查
/**
* @author Elvis
* @create 2021-08-06 22:16
*/
import com.elvis.RunBoot;
import com.elvis.dao.CommentDao;
import com.elvis.pojo.Comment;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @program: MongoDB-study
* @Description
* @author Elvis
* @date 2021-08-06 22:16
*/
@SpringBootTest(classes = RunBoot.class)
public class MongoTest {
@Autowired
CommentDao commentDao;
@Test
public void testInsert() {
Comment comment = new Comment();
comment.setArticleid("1102155");
comment.setContent("早上不要睡懒觉");
comment.setUserid("1004");
comment.setNickname("杰克船长");
comment.setLikenum(1234);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = null;
try {
date = simpleDateFormat.parse("2021-08-06 12:32:56" );
} catch (ParseException e) {
e.printStackTrace();
}
comment.setCreatedatetime(date);
comment.setState("1");
commentDao.insertComment(comment);
}
@Test
public void testFind(){
Comment comment = commentDao.findByUserId("1004");
System.out.println(comment);
System.out.println("***************************************");
List<Comment> comments = commentDao.findList("1004");
for (Comment comment1: comments) {
System.out.println(comment1);
}
}
@Test
public void testFindMulti() {
List<Comment> comments = commentDao.findByUserIdAndLikeNum("1004", 1000);
for (Comment comment1: comments) {
System.out.println(comment1);
}
}
}
MongoRepository 的方式
在上面工程基础上创建 CommentRepository
接口,具体参考官网
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
如果内置方法不够用 就自己定义 如:定义find|read|get 等开头的方法进行查询
package com.elvis.repository;
/**
* @author Elvis
* @create 2021-08-07 8:48
*/
import com.elvis.pojo.Comment;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
/**
* @program: MongoDB-study
* @Description
* @author Elvis
* @date 2021-08-07 8:48
*/
public interface CommentRepository extends MongoRepository<Comment, String> {
List<Comment> findByUseridEquals(String userid);
List<Comment> findByUseridAndLikenum(String name, Integer likenum);
}
编写测试类
/**
* @author Elvis
* @create 2021-08-06 22:16
*/
import com.elvis.RunBoot;
import com.elvis.dao.CommentDao;
import com.elvis.pojo.Comment;
import com.elvis.repository.CommentRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @program: MongoDB-study
* @Description
* @author Elvis
* @date 2021-08-06 22:16
*/
@SpringBootTest(classes = RunBoot.class)
public class MongoRepositoryTest {
@Autowired
CommentRepository commentRepository;
@Test
public void testInsert() {
Comment comment = new Comment();
comment.setArticleid("1102166");
comment.setContent("三餐规律才健康");
comment.setUserid("1004");
comment.setNickname("杰克船长");
comment.setLikenum(1234);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = null;
try {
date = simpleDateFormat.parse("2021-08-08 12:32:56" );
} catch (ParseException e) {
e.printStackTrace();
}
comment.setCreatedatetime(date);
comment.setState("1");
commentRepository.save(comment);
}
@Test
public void testFind(){
List<Comment> comments = commentRepository.findByUseridEquals("1004");
for (Comment comment1: comments) {
System.out.println(comment1);
}
}
@Test
public void testFindMulti() {
List<Comment> comments = commentRepository.findByUseridAndLikenum("1004", 1000);
for (Comment comment1: comments) {
System.out.println(comment1);
}
}
}