1、什么是MongoDB
1、非关系型数据库
NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在处理web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,出现了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,特别是大数据应用难题。
2、非关系型数据库分类
键值(Key-Value)存储数据库
类似于HashMap的方式,例如redis
列存储数据库
以列为概念的,用于处理大数据量的数据,例如HBase
文档型数据库
是应用比较广泛的,以文档形式处理数据的数据,文档不是硬盘上直接对应的文件,是个概念,例如MongoDB
图形(Graph)数据库
Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。
3、MongoDB
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
2、MongoDB的优势
-
简单性,应用起来比较容易,易上手
-
扩展性,指的是mango本身的拓展,比如说可以做分片模式集群等等
-
高性能,在Wiretiger存储引擎的加持下,数据的读写可以做到更大的吞吐量
-
高可用,自身出现故障的情况很少,也可以通过集群的方式再提供高可用性,还支持故障转移
-
存文件,mongo天然支持文件存储,以桶的形式,用的对象是GridFS,文件会被切割成多个16M大小存储
3、MongoDB应用场景
它的应用场景非常广泛,存储数据、读写网站数据、文件存储、日志存储、缓存等。
从数据角度说,mongo关注是未来数据量。
从需求角度说,mongo关注是未来的拓展和维护。
4、术语
mongo | mysql |
---|---|
database | database |
collection | table |
field | column |
document | row |
primary key | primary key |
index | index |
multi-document transactions | transactions |
mongo从5版本对事务的支持更好,以后工作用的一定是5版本及以上的。
我们学习用4版本,是因为很多电脑安装不了5版本,受硬件影响。4版本和5版本在操作上没有什么大区别,学习不影响。
5、操作
1、安装MongoDB
基于docker的安装,版本号4.4.18
1、查询镜像文件(无需操作)
docker search mongo
2、拉取镜像文件
docker pull mongo:4.4.18
3、创建数据挂载目录
mkdir -p /usr/local/docker/mongodb/data
cd /usr/local/docker/mongodb
chmod 777 data
4、启动容器
docker run -d \
--name mongodb \
--privileged \
-p 27017:27017 \
-v /usr/local/docker/mongodb/data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=root \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
mongo:4.4.18 mongod --auth
--privileged:以真正的有权限方式启动
MONGO_INITDB_ROOT_USERNAME:设置账户
MONGO_INITDB_ROOT_PASSWORD:设置密码
2、验证安装成功
1、命令及说明
# 进入容器
docker exec -it mongodb /bin/bash
# 查看版本
mongo --version
# 以root用户登录mongo,-p是密码,--port是端口号,--authenticationDatabase是验证权限的数据库
mongo --port 27017 -u "root" -p "123456" --authenticationDatabase "admin"
# 展示所有的数据库
show dbs
# 切换到dz12b数据库
use dz12b
# 创建一个用户,用户名是user01,密码是123456,角色是读写角色,作用在dz12b数据库上
db.createUser({user:"user01", pwd:"123456",roles: [{role:"readWrite", db:"dz12b"}]})
# 查看所有的用户数据
show users
# 退出mongodb
exit
# 退出mongodb容器
exit
# 再次进入容器,以mongo命令进入,进入到dz12b数据库中
docker exec -it mongodb mongo dz12b
# 查看当前在那个数据库
db
# 查看数据库,发现没有其他数据库,我们已经再dz12b了,所以查询不到其他数据库
show dbs
# 授权
db.auth("user01", "123456")
# 查看数据库,发现没有,授权影响不到用户的作用范围
show dbs
# 因为没有权限报错了
show users
# 向dz集合插入了一个文档,数据是inser方法的参数。对照sql理解:向dz表插入一条记录
db.dz.insert({name:"zhangsan"})
# 查询dz集合下所有的数据
db.dz.find()
【第1,2,3步骤】
【第4-9步骤】
【第10-17步骤】
3、删除用户(无需操作)
1、命令及说明
# 进入docker容器
docker exec -it mongodb /bin/bash
# 以root用户登录mongo,-p是密码,--port是端口号,--authenticationDatabase是验证权限的数据库
mongo --port 27017 -u "root" -p "123456" --authenticationDatabase "admin"
# 切换到dz12b数据库
use dz12b
# 查看所有的用户数据
show users
# 切换到admin数据库
user admin
# 授权
db.auth("root", "123456")
# 删除用户,用户信息再system.users下,remove是一个命令
db.system.users.remove({user:"user01"})
# 重新进入mongo,验证删除成功
exit
mongo --port 27017 -u "root" -p "123456" --authenticationDatabase "admin"
use dz7b
show users
4、Navicat连接
5、insert
db.dz.insert({name:"lisi", age:20});
db.dz.save({name:"wangwu", age:25});
db.dz.save({name:"zhangsan", age:25});
db.dz.insert({_id:ObjectId("63e4c8bdd20e7cc75a36a700"),name:"zhangsan1",age:20})
db.dz.save({_id:ObjectId("63e4c8bdd20e7cc75a36a700"),name:"zhangsan1",age:20})
insert和save的区别:
如果设置了id字段,id不重复二者没有区别,都是新增一条数据,如果id重复,insert会报错,save执行修改操作。
【执行insert语句同时 创建集合“表”】
6、find
操作符 | 格式 | 实例 | 与 RDBMS where 语句比较 |
---|---|---|---|
等于(=) | {<key> : {<value>}} | db.test.find( {price : 24} ) | where price = 24 |
大于(>) | {<key> : {$gt : <value>}} | db.test.find( {price : {$gt : 24}} ) | where price > 24 |
小于(<) | {<key> : {$lt : <value>}} | db.test.find( {price : {$lt : 24}} ) | where price < 24 |
大于等于(>=) | {<key> : {$gte : <value>}} | db.test.find( {price : {$gte : 24}} ) | where price >= 24 |
小于等于(<=) | {<key> : {$lte : <value>}} | db.test.find( {price : {$lte : 24}} ) | where price <= 24 |
不等于(!=) | {<key> : {$ne : <value>}} | db.test.find( {price : {$ne : 24}} ) | where price != 24 |
与(and) | {key01 : value01, key02 : value02, ...} | db.test.find( {name : "《MongoDB 入门教程》", price : 24} ) | where name = "《MongoDB 入门教程》" and price = 24 |
或(or) | {$or : [{key01 : value01}, {key02 : value02}, ...]} | db.test.find( {$or:[{name : "《MongoDB 入门教程》"},{price : 24}]} ) | where name = "《MongoDB 入门教程》" or price = 24 |
db.dz.find({age : 25} )
db.dz.find({age : {$gt : 20}})
db.dz.find({age:{$gt:20},name:'zhangsan'})
7、delete
db.dz.deleteOne({age:20})
db.dz.deleteMany({age:20})
deleteOne是删除按照条件查询到的第一条数据
deleteMany是删除所有符合条件的记录
8、update
db.dz.updateOne(
{age:25},
{$set:{age:20}}
)db.dz.updateMany(
{age:25},
{$set:{age:20}}
)
updateOne是修改按照条件查询到的第一条数据
updateMany是修改所有符合条件的记录
9、其他操作(了解即可)
# 查看所有数据库
show dbs
# 应用到指定数据库
use databasename
# 查看数据库下的集合
show collections
# 创建集合
db.createCollection("test_collection")
# 删除集合,test_collection是集合的名字
db.test_collection.drop()
6、SpringBoot整合
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring:
data:
mongodb:
username: user01
password: '123456'
port: 27017
host: 192.168.1.101
database: dz12b
mongodb配置有两种方式,如果第一种不生效,可以用第二种尝试一下
spring:
data:
mongodb:
uri: mongodb://user01:123456@192.168.1.101:27017/dz12b
VO
import lombok.Data;
import org.springframework.data.annotation.Id;
@Data
public class User {
@Id
private String id;
private String name;
private String password;
}
DAO
import org.jsoft.demo.vo.User;
import java.util.List;
public interface IUserDao {
/**
* 新增
*
* @param user 目标对象
*/
void insert(User user);
/**
* 删除
*
* @param id 对象主键
*/
void delete(String id);
/**
* 修改
*
* @param user 目标对象
*/
void update(User user);
/**
* 通过主键查询
*
* @param id 主键
* @return user对象
*/
User findById(String id);
/**
* 查询
*
* @param user 条件对象
* @return user集合
*/
List<User> query(User user);
}
DAOImpl
import org.jsoft.demo.dao.IUserDao;
import org.jsoft.demo.vo.User;
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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class UserDaoImpl implements IUserDao {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public void insert(User user) {
mongoTemplate.insert(user);
}
@Override
public User findById(String id) {
return mongoTemplate.findById(id, User.class);
}
// @Override
public void delete1(String id) {
User user = findById(id);
if (user != null) {
mongoTemplate.remove(user);
} else {
System.out.println("没有找到要删除的数据!");
}
}
@Override
public void delete(String id) {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(id));
mongoTemplate.remove(query, User.class);
}
@Override
public void update(User user) {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(user.getId()));
Update update = new Update();
update.set("name", user.getName());
update.set("password", user.getPassword());
mongoTemplate.updateMulti(query, update, User.class);
}
@Override
public List<User> query(User user) {
Query query = new Query();
if(user.getId() != null){
query.addCriteria(Criteria.where("_id").is(user.getId()));
}
if(user.getName() != null){
query.addCriteria(Criteria.where("name").is(user.getName()));
}
if(user.getPassword() != null){
query.addCriteria(Criteria.where("password").is(user.getPassword()));
}
return mongoTemplate.find(query, User.class);
}
}
Test
import lombok.extern.slf4j.Slf4j;
import org.jsoft.demo.dao.IUserDao;
import org.jsoft.demo.vo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest(classes = DemoHelloworldApplication.class)
@SuppressWarnings("all")
public class MongoDbTest {
@Autowired
private IUserDao userDao;
@Test
public void testInsert() {
User user = new User();
user.setPassword("123");
user.setName("zhangsan");
userDao.insert(user);
}
@Test
public void testFindById() {
User byId = userDao.findById("661794efd775ee4bd7a6d069");
System.out.println(byId);
}
@Test
public void testDelete() {
userDao.delete("6617970547fbc57ef66a962f");
}
@Test
public void testUpdate() {
User user = new User();
user.setId("661797ee479a0c02f0dd9212");
user.setPassword("123456");
user.setName("lisi");
userDao.update(user);
}
@Test
public void testQuery() {
User user = new User();
// user.setId("661797ee479a0c02f0dd9212");
user.setPassword("123");
// user.setName("lisi");
System.out.println(userDao.query(user));
}
}
MongoDB可以实现文件上传下载,和上述代码稍有不同,同学们可以自己研究一下如何实现,咱再找时间检查。