MongoDB超详细教程(保姆级)
MongoDB
一、简介
1. 简单介绍
- MongoDB是一个基于分布式文件存储的数据库
- 由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。
- MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
- 它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。
- Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引
2. 业务应用场景
传统的关系型数据库(如MySQL),在数据操作的三高
需求以及应对Web2.0的网站需求面前,显得力不从心,而 MongoDB可应对“三高“需求
High performance:对数据库高并发读写的需求
Huge Storage:对海量数据的高效率存储和访问的需求
High Scalability && High Availability:对数据库的高可扩展性和高可用性的需求
具体应用场景:
- 社交场景,使用 MongoDB存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
- 游戏场景,使用 MongoDB存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、高效率存储和访问。
- 物流场景,使用 MongoDB存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来
- 物联网场景,使用 MongoDB存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。
视频直播,使用 MongoDB存储用户信息、点赞互动信息等。
这些应用场景中,数据操作方面的共同特点是:
(1)数据量大
(2)写入操作频繁(读写都很频繁)
(3)价值较低的数据,对事务性要求不高
对于这样的数据,我们更适合使用 MongoDB来实现数据的存储。
3. 什么时候选择MongoDB
应用不需要事务及复杂join支持
新应用,需求会变,数据模型无法确定,想快速迭代开发
应用需要2000-3000以上的读写QPS(更高也可以)
应用需要TB甚至PB级别数据存储
应用要求存储的数据不丢失
应用需要99.999%高可用
应用需要大量的地理位置查询、文本查
相对MySQL,在以上以用场景可以以更低的成本解决问题(包括学习、开发、运维等成本)
4. 体系机构
5. 数据类型
MongoDB的最小存储单位就是文档document对象。文档document对象对应于关系型数据库的行。数据在MongoDB中以BSON(Binary-JSON)文档的格式存储在磁盘上。
BSON(Binary Serialized Document Format)是一种类json的一种二进制形式的存储格式,简称 Binary JSON;BSON和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和Bin Data类型。
BSON采用了类似于C语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具有轻量性、可遍历性、高效性的三个特点,可以有效描述非结构化数据和结构化数据。这种格式的优点是灵活性高,但它的缺点是空间利用率不是很理想。
BSON中,除了基本JSON类型: string,integer,boolean,double,null,array和object,mongo还使用了特殊的数据类型。这些类型包括 date, object id, binary data, regular expression和code。每一个驱动都以特定语言的方式实现了这些类型,查看你的驱动的文档来获取详细信息
BSON数据类型参考列表:
提示:
shell默认使用64位浮点型数值。{“x”:3.14或{“x”:3}。对于整型值,可以使用NumberInt(4字节符号整数)或 NumberLong(8字节符号整数),{“x”:NumberInt(“3” ){“x”:NumberLong(“3”)}
6. 特点
- 高性能
MongoDB提供高性能的数据持久性。特别是,
对嵌入式数据模型的支持减少了数据库系统上I/O活动。
索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。(文本索引解决搜索的需求、TTL索引解决历史数据自动过期的需求、地理位置索引可用于构建各种O2O应用)
mmapv1、 wiredtiger、 mongorocks( rocks)、 In-memory等多引擎支持满足各种场景需求
Gridfs解决文件存储的需求
高可用性
MongoDB的复制工具称为副本集( replica set),它可提供自动故障转移和数据冗余高扩展性
MongoDB提供了水平可扩展性作为其核心功能的一部分。
分片将数据分布在一组集群的机器上。(海量数据存储,服务能力水平扩展)
从3.4开始,MoηgoDB支持基于片键创建数据区域。在一个平衡的集群中, MongoDB将一个区域所覆盖的读写只定向到该区域内的那些片。
丰富的查询支持
MongoDB支持丰富的査询语言,支持读和写操作(CRUD),比如数据聚合、文本搜索和地理空间查询等其他特点
如无模式(动态模式)、灵活的文档模型
二、Windows安装&启动&连接
1. 下载压缩包
下载地址:https://www.mongodb.com/try/download/community
这里以zip的格式进行下载
附加:mongodb的命名格式: x.y.z
- y为奇数表示当前版本为开发版,如:1.5.2、4.1.13
- y为偶数表示当前版本为稳定版,如:1.6.3、4.0.10
- z为修正版本号,越大越好
2. 解压
下载完成后得到压缩包,解压;其中的bin目录就存放着mongodb相关的命令
3. 安装服务
首先要在安装目录里创建两个目录:
- 数据目录:data
- 日志目录:logs
然后以管理员模式,切换到安装目录下的bin目录运行以下格式命令来指定mongdb的数据及日志目录
mongod --install --dbpath 数据目录 --logpath 日志目录\日志名称
注意整个文件的路径中不能包含中文,中文,中文!踩过坑!
具体的代码为如下所示:
mongod --install --dbpath D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\data --logpath D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\logs\mongodb.log
没有任何报错和提示,则代表MongoDB服务创建成功
我们可以进行验证,win+r输入services.msc
看到MongoDB服务即成功
补充一下:如果想要删除MongoDB服务的话
SC DELETE MongoDB
4. 启动服务
输入以下命令启动服务
net start mongodb
输入http://localhost:27017/
如果看到以下内容,代表启动成功
5. shell连接登录&退出
输入以下命令进行登录与退出
#登录
mongo
mongo --host=localhost --port=27017#退出
exit
相关语法:
mongod --install --dbpath 数据目录 --logpath 日志目录\日志名称 #创建服务
mongod --remove #卸载服务
net start mongodb #启动服务
net stop mongodb #关闭服务
mongod #是处理MongoDB系统的主要进程。它处理数据请求,管理数据存储,和执行后台管理操作。当我们运行mongod命令意味着正在启动MongoDB进程,并且在后台运行。
6. Compass图形化连接登录
MongoDB的GUI。直观地浏览您的数据。在几秒钟内运行查询。借助完整的CRUD功能与您的数据进行交互。查看和优化您的查询性能。在Linux,Mac或Windows上可用。Compass使您能够做出更明智的索引,文档验证等决策。
下载地址:https://www.mongodb.com/try/download/compass
点击Download
下载即可,下载完成后得到压缩包
解压,可以看到MongoDBCompass.exe
双击运行,直接Next,最后Get Stated,默认选项即可
然后直接点击CONNECT就会连接本地的数据库localhost:27017
可以看到所有的数据库及相关信息
三、Linux安装&启动&连接
环境:阿里云服务器Centos7
1. 下载压缩包
下载地址:https://www.mongodb.com/try/download/community
选择对应的系统版本(这里为Centos7),以tgz的格式进行下载
2. 上传到服务器&解压
将下载得到的压缩包上传到服务器,这里使用xftp工具进行上传
然后解压
tar -zxvf mongodb-linux-x86_64-rhel70-4.4.4.gz
然后将解压后的文件移至usr/local/mongodb目录下,这是我们一般存放文件的位置
mv mongodb-linux-x86_64-rhel70-4.4.4 /usr/local/mongodb
3. 创建数据/日志存放目录
mkdir -p /usr/local/mongodb/data /usr/local/mongodb/logs
4. 启动服务
/usr/local/mongodb/bin/mongod --dbpath=/usr/local/mongodb/data/ --logpath=/usr/local/mongodb/logs/mongodb.log --logappend --port=27017 --fork
5. 登录
登录
/usr/local/mongodb/bin/mongo
退出
exit
6. Compass图形化连接登录
利用Compass进行连接,Hostname为服务器的公网IP,其他默认
连接失败的原因:
- 未打开安全组策略
暴露给外部的端口需要打开对应的安全组设置
- 防火墙开放端口未设置
首先查看防火墙是否开启,结果为not running表示未开启,则不是防火墙的问题,跳过
查看防火墙是否开启
firewall-cmd --state
1
2
如果显示running,则继续排查,查看防火墙开放的端口
查看防火墙所开放的端口
firewall-cmd --list-ports[root@zsr ~]# firewall-cmd --list-ports
20/tcp 21/tcp 22/tcp 80/tcp 8888/tcp 39000-40000/tcp 3306/tcp 3306/udp 8080/tcp 8080/udp 3355/tcp
也可以用firewall-cmd --list-all查看防火墙的详细信息
我这里的问题就是防火墙未开放27017端口,所以要开放防火墙的对外暴露的端口
开放90端口(–premanent表示永久添加)
firewall-cmd --permanent --add-port=27017/tcp
重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
添加完成后再次查看就可以看到27017端口被开放
四、基本常用命令
1. 数据库相关
查看所有数据库
show databases
选择数据库(如果数据库不存在,不会报错;会隐式创建:当后期该数据库有数据时自动创建)
use 数据库名
删除数据库(先选中数据库)
db.dropDatabase()
2. 集合相关
查看所有集合
show collections
创建集合(插入数据会隐式创建)
db.createCollection('集合名')
删除集合
db.集合名.drop()
五、CURD
增:插入文档
db.集合名.insert(json数据)
1
集合存在则直接插入数据,不存在则隐式创建集合并插入数据
json数据格式要求key得加"“,但这里为了方便查看,对象的key统一不加”“;查看集合数据时系统会自动给key加”"
mongodb会自动给每条数据创建全球唯一的_id键(我们也可以自定义_id的值,只要给插入的json数据增加_id键即可覆盖,但是不推荐这样做)
测试:
插入一条数据
一次插入多条数据并指定_id
利用for循环插入数据
for(var i=1;i<10;i++){
db.student.insert({name:“a”+i,age:i})
}
1
2
3
删:删除文档
db.集合名.remove(条件 [,是否删除一条])
是否删除一条
- false删除多条,即全部删除(默认)
- true删除一条
1
2
3
4
5
改:修改文档
db.集合名.update(条件, 新数据 [,是否新增, 是否修改多条])
新数据
- 默认是对原数据进行替换
- 若要进行修改,格式为 {修改器:{key:value}}
是否新增
- 条件匹配不到数据时是否插入: true插入,false不插入(默认)
是否修改多条
- 条件匹配成功的数据是否都修改: true都修改,false只修改一条(默认)
1
2
3
4
5
6
7
8
9
10
11
修改器 作用
$inc 递增
$rename 重命名列
$set 修改列值
$unset 删除列
准备工作:插入十条数据
for(var i=1;i<=10;i++){
db.people.insert({name:“zsr”+i,age:i})
}
1
2
3
将{name:“zsr1”}更改为{name:“zsr2”}
db.people.update({name:“zsr1”},{name:“zsr2”})
1
发现问题:默认不是修改而是替换
解决问题:使用修改器将{name:“zsr3”}更改为{name:“zsr3333”}
db.people.update({name:“zsr3”},{$set:{name:“zsr3333”}})
1
给{name:“zsr10”}的年龄增加或减少2岁
增加两岁
db.people.update({name:“zsr10”},{$inc:{age:2}})
减少两岁
db.people.update({name:“zsr10”},{$inc:{age:-2}})
1
2
3
4
5
一次写多个修改器
首先插入一条数据
db.people.insert({username:“gcc”,age:20,sex:“女”,address:“unknown”})
1
任务:修改gcc的username为bareth,age+11,sex字段重命名为sexuality,删除address字段
db.people.update({username:“gcc”},{
$set:{username:“bareth”},
$inc:{age:11},
$rename:{sex:“sexuality”},
$unset:{address:true}
})
1
2
3
4
5
6
查:查询文档
db.集合名.find(条件 [,查询的列])
db.集合名.find(条件 [,查询的列]).pretty() #格式化查看
条件
- 查询所有数据 {}或不写
- 查询指定要求数据 {key:value}或{key:{运算符:value}}
查询的列(可选参数)
- 不写则查询全部列
- {key:1} 只显示key列
- {key:0} 除了key列都显示
- 注意:_id列都会存在
1
2
3
4
5
6
7
8
9
10
11
12
运算符 作用
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
$in in
$nin not in
查询指定列的所有数据
查询指定条件的数据
六、排序&分页
数据准备:
for(var i=1;i<5;i++){
db.person.insert({_id:i,name:“p”+i,age:10+i})
}
1
2
3
排序
db.集合名.find().sort(json数据)
json数据(key:value)
- key就是要排序的字段
- value为1表示升序,-1表示降序
1
2
3
4
5
按年龄降序排列
分页
db.集合名.find().sort().skip(数字).limit(数字)[.count()]
skip(数字)
- 指定跳过的数量(可选)
limit(数字)
- 限制查询的数量
count()
- 统计数量
1
2
3
4
5
6
7
8
9
10
测试:
实战:数据库有1~10条数据,每页显示2条,一共5页
skip计算公式: (当前页-1)*每页显示的条数
页数 起始 终止 跳过数
1页 1 2 0
2页 3 4 2
3页 5 6 4
4页 7 8 6
5页 9 10 8
1
2
3
4
5
6
7
8
数据准备
for(var i=1;i<11;i++){
db.page.insert({_id:i,name:“p”+i})
}
分5页,每页2条显示
for(var i=0;i<10;i=i+2){
db.page.find().skip(i).limit(2)
}
1
2
3
4
5
6
7
8
9
七、聚合查询
- 语法
db.集合名.aggregate([
{管道:{表达式}}
…
])
1
2
3
4
常用管道:
$group 将集合中的文档分组,用于统计结果
$match 过滤数据,只输出符合条件的文档
$sort 聚合数据进一步排序
$skip 跳过指定文档数
$limit 限制集合数据返回文档数
常用表达式:
sum总和(sum 总和(sum总和(num:1同count表示统计)
$avg 平均
$min 最小值
$max 最大值
2. 测试
数据准备:
db.people.insert({_id:1,name:“a”,sex:“男”,age:21})
db.people.insert({_id:2,name:“b”,sex:“男”,age:20})
db.people.insert({_id:3,name:“c”,sex:“女”,age:20})
db.people.insert({_id:4,name:“d”,sex:“女”,age:18})
db.people.insert({_id:5,name:“e”,sex:“男”,age:19})
1
2
3
4
5
统计男生、女生的总年龄
db.people.aggregate([
{KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"sex",age_sum:{sum:"sum:"sum:"age"}}}
])
1
2
3
统计男生女生的总人数
db.people.aggregate([
{KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"sex",sum:{$sum:1}}}
])
1
2
3
求学生总数和平均年龄
db.people.aggregate([
{KaTeX parse error: Expected '}', got 'EOF' at end of input: …ull,total_num:{sum:1},total_avg:{avg:"avg:"avg:"age"}}}
])
1
2
3
查询男生、女生人数,按人数升序
db.people.aggregate([
{KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"sex",rs:{KaTeX parse error: Expected 'EOF', got '}' at position 6: sum:1}̲}}, {sort:{rs:1}}
])
1
2
3
4
八、索引
- 简介
索引是一种排序好的便于快速查询数据的数据结构,用于帮助数据库高效的查询数据
优点:
提高数据查询的效率,降低数据库的IO成本
通过索引对数据进行排序,降低数据排序的成本,降低CPU的消耗
缺点:
占用磁盘空间
大量索引影响SQL语句的执行效率,因为每次插入和修改数据都要更新索引
2. 语法
创建索引语法:
创建索引
db.集合名.createIndex(待创建索引的列:方式 [,额外选项])
创建复合索引
db.集合名.createIndex({key1:方式,key2:方式} [,额外选项])
参数说明:
待创建索引的列:方式
:{key:1}/{key:-1}
1表示升序,-1表示降序; 例如{age:1}表示创建age索引并按照升序方法排列额外选项
:设置索引的名称或者唯一索引等
设置名称:{name:索引名}
唯一索引:{unique:列名}
1
2
3
4
5
6
7
8
9
10
11
删除索引语法:
删除全部索引
db.集合名.dropIndexes()
删除指定索引
db.集合名.dropIndex(索引名)
1
2
3
4
查看索引语法:
查看索引
db.集合名.getIndexes()
1
2
3. 练习
十万条数据准备:
选择数据库
use test
插入100000条数据
for(var i=0;i<100000;i++){
db.data.insert({name:“zsr”+i,age:i})
}
1
2
3
4
5
6
创建普通索引
给name添加普通升序索引
db.data.createIndex({name:1})
1
2
给age创建索引并起名age_up
db.data.createIndex({age:1},{name:“age_up”})
1
2
删除索引
删除name列的索引
db.data.dropIndex(“name_1”)
1
2
创建复合/组合索引:也就是一次给两个字段建立索引
给name和age添加组合索引
db.data.createIndex({name:1,age:1})
1
2
创建唯一索引
删除所有索引
db.data.dropIndexes()
给name创建唯一索引
db.data.createIndex({name:1},{unique:“name”})
1
2
3
4
5
- 分析索引(explain)
db.集合名.find().explain(‘executionStats’)
1
我们通过简单的案例来测试索引的好处
不加索引时查询age=500的数据
db.data.find({age:500}).explain(‘executionStats’)
{
“queryPlanner” : {
“plannerVersion” : 1,
“namespace” : “test.data”,
“indexFilterSet” : false,
“parsedQuery” : {
“age” : {
“KaTeX parse error: Expected 'EOF', got '}' at position 35: … }̲ …eq” : 500
}
},
“direction” : “forward”
},
“rejectedPlans” : [ ]
},
“executionStats” : { #执行计划相关统计信息
“executionSuccess” : true, #执行成功的状态
“nReturned” : 1, #返回结果集数目
“executionTimeMillis” : 37, #执行所需要的ms数
“totalKeysExamined” : 0, #索引检查的时间
“totalDocsExamined” : 100000, #检查文档总数
“executionStages” : {
“stage” : “COLLSCAN”, #索引扫描方式
“filter” : { #过滤条件
“age” : {
“$eq” : 500
}
},
“nReturned” : 1, #返回结果集数目
“executionTimeMillisEstimate” : 1, #预估执行时间(ms)
“works” : 100002, #工作单元数,一个查询会被派生为一个小的工作单元
“advanced” : 1, #优先返回的结果数
“needTime” : 100000,
“needYield” : 0,
“saveState” : 100,
“restoreState” : 100,
“isEOF” : 1,
“direction” : “forward”,
“docsExamined” : 100000 #文档检查数目
}
},
“serverInfo” : {
“host” : “LAPTOP-8J48VF43”,
“port” : 27017,
“version” : “4.4.2”,
“gitVersion” : “15e73dc5738d2278b688f8929aee605fe4279b0e”
},
“ok” : 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
给age添加一个升序索引后
给age添加升序索引
db.data.createIndex({age:1})
{
“createdCollectionAutomatically” : false,
“numIndexesBefore” : 2,
“numIndexesAfter” : 3,
“ok” : 1
}
性能分析
db.data.find({age:500}).explain(‘executionStats’)
{
“queryPlanner” : {
“plannerVersion” : 1,
“namespace” : “test.data”,
“indexFilterSet” : false,
“parsedQuery” : {
“age” : {
“$eq” : 500
}
},
“winningPlan” : {
“stage” : “FETCH”,
“inputStage” : {
“stage” : “IXSCAN”,
“keyPattern” : {
“age” : 1
},
“indexName” : “age_1”,
“isMultiKey” : false,
“multiKeyPaths” : {
“age” : [ ]
},
“isUnique” : false,
“isSparse” : false,
“isPartial” : false,
“indexVersion” : 2,
“direction” : “forward”,
“indexBounds” : {
“age” : [
“[500.0, 500.0]”
]
}
}
},
“rejectedPlans” : [ ]
},
“executionStats” : { #执行计划相关统计信息
“executionSuccess” : true, #执行成功的状态
“nReturned” : 1, #返回结果集数目
“executionTimeMillis” : 1, #执行所需要的ms数
“totalKeysExamined” : 1, #索引检查的时间
“totalDocsExamined” : 1, #检查文档总数
“executionStages” : {
“stage” : “FETCH”, #索引扫描方式
“nReturned” : 1, #返回结果集数目
“executionTimeMillisEstimate” : 0, #预估执行时间(ms)
“works” : 2, #工作单元数,一个查询会被派生为一个小的工作单元
“advanced” : 1, #优先返回的结果数
“needTime” : 0,
“needYield” : 0,
“saveState” : 0,
“restoreState” : 0,
“isEOF” : 1,
“docsExamined” : 1,
“alreadyHasObj” : 0,
“inputStage” : {
“stage” : “IXSCAN”,
“nReturned” : 1,
“executionTimeMillisEstimate” : 0,
“works” : 2,
“advanced” : 1,
“needTime” : 0,
“needYield” : 0,
“saveState” : 0,
“restoreState” : 0,
“isEOF” : 1,
“keyPattern” : {
“age” : 1
},
“indexName” : “age_1”,
“isMultiKey” : false,
“multiKeyPaths” : {
“age” : [ ]
},
“isUnique” : false,
“isSparse” : false,
“isPartial” : false,
“indexVersion” : 2,
“direction” : “forward”,
“indexBounds” : {
“age” : [
“[500.0, 500.0]”
]
},
“keysExamined” : 1,
“seeks” : 1,
“dupsTested” : 0,
“dupsDropped” : 0
}
}
},
“serverInfo” : {
“host” : “LAPTOP-8J48VF43”,
“port” : 27017,
“version” : “4.4.2”,
“gitVersion” : “15e73dc5738d2278b688f8929aee605fe4279b0e”
},
“ok” : 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
三种扫描方式
COLLSCAN:全盘扫描
INSCAN:索引扫描
FETCH:根据索引去检索指定document
5. 选择规则
如何选择合适的列创建索引?
为常做条件、排序、分组的字段建立索引
选择唯一性索引
选择较小的数据列,为较长的字符串使用前缀索引
九、权限机制
安装完Mongodb后,在命令行输入mongo命令即可登录数据库,这肯定是不安全的,我们需要使用权限机制,开启验证模式
创建账号语法
创建账号
db.createUser({
“user”:“账号”,
“pwd”:“密码”,
“roles”:[{
role:“角色”,
db:“所属数据库”
}]
})
1
2
3
4
5
6
7
8
角色种类
超级用户角色:root
数据库用户角色:read、readWrite
数据库管理角色:dbAdmin、userAdmin
集群管理角色: clusterAdmin、clusterManager、clusterMonitor、hostManager
备份恢复角色: backup、restore
所有数据库角色: readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
角色说明
root:只在admin数据库中可用。超级账号,超级权限;
read:允许用户读取指定数据库;
readWrite:允许用户读写指定数据库
开启验证模式
验证模式:值用户需要输入账号密码才能登录使用
- 添加超级管理员账号
必须使用admin数据库
use admin
创建超级用户
db.createUser({
“user”:“zsr”,
“pwd”:“123456”,
“roles”:[{
role:“root”,
db:“admin”
}]
})
1
2
3
4
5
6
7
8
9
10
11
12
然后查看admin数据库中的集合system.users可以查看详细信息
- 卸载服务
首先exit退出登录,然后以管理员模式打开终端输入如下命令卸载服务
卸载服务
mongod --remove
1
2
- 安装需要身份验证的服务
mongod --install --dbpath 数据目录 --logpath 日志目录\日志名称 --auth
1
这里为:
mongod --install --dbpath D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\data --logpath D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\logs\mongodb-zsr.log --auth
1
4. 启动服务
net start mongodb
1
登录测试
输入mongo命令登录,可以发现不再显示警告,且查看数据库看不到,这是因为还没有身份验证,没有通过账号登录通过超级管理员账号登录
方法一
mongo 服务器ip地址:端口号/数据库 -u 用户名 -p 密码
1
2
方法二
mongo #先登录
use admin #选择数据库
db.auth(用户名,密码)
1
2
3
4
练习
需求
添加用户shop1可以读shop数据库
添加用户shop2可以读写shop数据库
注意:必须在对应的数据库中创建用户
准备:创建测试数据
use shop
for(var i=1;i<=10;i++){
db.goods.insert({name:“goods”+i,price:i})
}
1
2
3
4
添加用户并设置权限
use shop
创建shop1用户
db.createUser({
“user”:“shop1”,
“pwd”:“123456”,
“roles”:[{
role:“read”,
db:“shop”
}]
})
创建shop2用户
db.createUser({
“user”:“shop2”,
“pwd”:“123456”,
“roles”:[{
role:“readWrite”,
db:“shop”
}]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
验证:shop1可读,shop2可读可写
验证shop1可读
C:\WINDOWS\system32>mongo localhost:27017/shop -u shop1 -p 123456
MongoDB shell version v4.4.2
connecting to: mongodb://localhost:27017/shop?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { “id” : UUID(“727ada5f-985f-4858-bb30-523d1777fa3a”) }
MongoDB server version: 4.4.2
show dbs
shop 0.000GB
db.goods.find() #可读
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f431”), “name” : “goods1”, “price” : 1 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f432”), “name” : “goods2”, “price” : 2 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f433”), “name” : “goods3”, “price” : 3 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f434”), “name” : “goods4”, “price” : 4 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f435”), “name” : “goods5”, “price” : 5 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f436”), “name” : “goods6”, “price” : 6 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f437”), “name” : “goods7”, “price” : 7 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f438”), “name” : “goods8”, “price” : 8 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f439”), “name” : “goods9”, “price” : 9 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f43a”), “name” : “goods10”, “price” : 10 }
db.goods.insert({name:“zsr”}) #不可写
WriteCommandError({
“ok” : 0,
“errmsg” : “not authorized on shop to execute command { insert: “goods”, ordered: true, lsid: { id: UUID(“727ada5f-985f-4858-bb30-523d1777fa3a”) }, $db: “shop” }”,
“code” : 13,
“codeName” : “Unauthorized”
})
验证shop2可读可写
C:\WINDOWS\system32>mongo localhost:27017/shop -u shop2 -p 123456
MongoDB shell version v4.4.2
connecting to: mongodb://localhost:27017/shop?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { “id” : UUID(“1fbca023-aeb3-4514-b2e4-700934000cc9”) }
MongoDB server version: 4.4.2
db.goods.find() #可读
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f431”), “name” : “goods1”, “price” : 1 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f432”), “name” : “goods2”, “price” : 2 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f433”), “name” : “goods3”, “price” : 3 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f434”), “name” : “goods4”, “price” : 4 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f435”), “name” : “goods5”, “price” : 5 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f436”), “name” : “goods6”, “price” : 6 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f437”), “name” : “goods7”, “price” : 7 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f438”), “name” : “goods8”, “price” : 8 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f439”), “name” : “goods9”, “price” : 9 }
{ “_id” : ObjectId(“60364ec9fd9e42c81a76f43a”), “name” : “goods10”, “price” : 10 }
db.goods.insert({name:“zsr”}) 可写
WriteResult({ “nInserted” : 1 })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
十、备份还原
下载MongoDB数据库工具
进行备份还原之前,首先要下载相关的工具
MongoDB Database Tools:https://www.mongodb.com/try/download/database-tools
MongoDB数据库工具是用于处理MongoDB部署的命令行实用程序的集合。这些工具独立于MongoDB Server计划发布,使您能够获得更频繁的更新,并在新功能可用时立即加以利用。有关更多信息,请参阅MongoDB数据库工具文档。
下载后得到压缩包
解压
然后点击进入bin目录,可以看到各种工具,接下来的备份还原就需要用到其中的mongodump和mongorestore
将其中的所有exe文件拷贝到MongoDB安装目录下的bin目录中
备份数据库mongodump
导出数据
mongodump -h -port -u -p -d -o
说明
-h 服务器ip地址(一般不写,默认本机)
-port 端口(一般不写,默认27017)
-u 账号
-p 密码
-d 数据库(不写则表示导出全部)
-o 备份到指定目录下
1
2
3
4
5
6
7
8
9
10
1️⃣ 备份所有数据:
在MongoDB安装目录下新建一个data_backup目录用于存放所有的备份数据
mongodump -u zsr -p 123456 -o D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\data_backup
1
然后再查看data_backup目录,可以看到备份的所有的数据库
2️⃣ 备份指定数据:
在MongoDB安装目录下新建一个data_backup2目录用于存放备份的shop数据库
用具有读权限的shop1/shop2用户都可以
mongodump -u shop1 -p 123456 -d shop -o D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\data_backup2
1
2
然后再查看data_backu2目录,可以看到备份的shop数据库
还原数据库mongorestore
mongostore -h -port -u -p -d --drop 备份数据目录
说明
-h 服务器ip地址(一般不写,默认本机)
-port 端口(一般不写,默认27017)
-u 账号
-p 密码
-d 数据库(不写则表示还原全部数据)
–drop 先删除数据库再导入,不写则覆盖
1
2
3
4
5
6
7
8
9
1️⃣ 还原所有数据:
首先删除几个数据库
然后输入如下命令从data_backup目录进行恢复
mongorestore -u zsr -p 123456 --drop D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\data_backup
1
然后再次登录查看数据库,可以发现已经恢复
2️⃣ 还原指定数据:
首先删除shop数据库
然后输入如下命令从data_backup2目录恢复shop数据库
用具有写权限的shop2用户
mongorestore -u shop2 -p 123456 -d shop --drop D:\JAVA_Environment\MongoDB\mongodb-win32-x86_64-windows-4.4.2\data_backup2\shop
1
2
然后再次登录查看shop数据库,可以发现已经恢复
十一、实战可视化管理Robo 3T
常见的可视化管理工具:
adminMongo:WEB/PC端口网页管理 https://github.com/mrvautin/adminMongo
Robo 3T *:客户端软件 https://robomongo.org/download/
MongoVUE :客户端软件
- 下载安装Robo 3T
下载地址:https://robomongo.org/download/
Studio 3T 和 Robo 3T 的区别:前者是商业付费软件,后者开源免费软件
这里选择仅仅下载Robo 3T
填写好信息后点击下载
这里选择下载.exe
下载后得到exe文件
双击运行进行安装,傻瓜式下一部安装完成即可
- 使用Robo 3T
安装完成后打开
点击Create创建一个链接,添加连接数据库的相关信息
我们开启了身份验证,因此需要填写身份验证的用户名和密码,最后Save
然后点击Connect进行连接
成功连接到数据库
然后就可以可视化进行各种操作
十二、mongoose
- 简介
mongoose.js是node中操作mongodb的模块,可以通过node语法实现MongoDB数据库的增删改查
中文网:http://www.mongoosejs.net/
英文网:https://mongoosejs.com/
核心概念:
schema:约束字段/列数据
model:对应集合,用它来实现数据增删改查
2. 安装
用Vscode新建并打开一个文件夹,在终端输入如下命令安装mongoose模块
安装
npm install mongoose
1
2
- CURD语法
新建一个.js文件,用来连接并操作mongodb数据库
// 一、导入模块
var mongoose = require(“mongoose”);
// 二、连接数据库
const db = mongoose.createConnection(‘mongodb://user:pass@localhost:port/database’,{useNewUrlParser:true,useUnifiedTopology:true},err=>{
if(err){
console.log(‘数据库连接失败’,err);
return;
}
console.log(‘数据库连接成功’);
})
// 三、设置数据类型(声明哪个是集合,限制字段个数和字段类型)
const model = db.model(‘user’,{
name:{type:String,default:“username”},
age:{type:Number},
sex:{type:String}
})
// 四、创建实例操作(CRUD)
// -----------------增--------------------
const insertObj = new model(数据对象)
方法一:inserObj.save((err)=>db.close())
方法二:(推荐)
insertObj.save()
.then(res=>{
return res
})
.catch(err=>{
console.log(‘插入失败’+err)
return false
})
// -----------------删--------------------
方法一:model.remove/deleteOne/deleteMany(条件对象,(err)=>db.close())
方法二:(推荐)
model.deleteOne(条件对象)
.then(res=>{
return res.deletedCount
})
.catch(err=>{
console.log(‘删除失败’+err)
return false
})
// -----------------改--------------------
方法一:model.update/updateOne/updateMany(条件对象,数据对象,(err)=>db.close())
方法二:(推荐)
model.updateOne(条件对象,数据对象)
.then(res=>{
return res.nModified
})
.catch(err=>{
console.log(‘修改失败’+err)
return false
})
// -----------------查--------------------
方法一:model.find/findOne(条件对象,要显示的字段数据对象,(err,result)=>db.close())
方法二:(推荐)
model.findOne(条件对象)
.then(res=>{
return res
})
.catch(err=>{
console.log(‘查询失败’+err)
return false
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
4. 测试
增
// 一、导入模块
var mongoose = require(“mongoose”);
// 二、连接数据库
const db = mongoose.createConnection(‘mongodb://shop2:123456@localhost:27017/shop’, {
useNewUrlParser: true,
useUnifiedTopology: true
}, err => {
if (err) {
console.log(‘数据库连接失败’, err);
return;
}
console.log(‘数据库连接成功’);
})
// 三、设置数据类型(声明哪个是集合,限制字段个数和字段类型)
const model = db.model(‘user’, {
name: {
type: String,
default: “username”
},
age: {
type: Number
},
sex: {
type: String
}
})
// 四、创建实例操作(CRUD)
// -----------------增--------------------
const insertObj = new model({
name: “zsr”,
age: 21,
sex: “男”
})
insertObj.save()
.then(res => {
console.log(res)
return res
})
.catch(err => {
console.log(‘插入失败’ + err)
return false
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
然后运行测试:
然后打开Robo 3T查看,可以看到成功插入数据
查
// -----------------查--------------------
model.findOne({})
.then(res=>{
console.log(res)
return res
})
.catch(err=>{
console.log(‘查询失败’+err)
return false
})
//分页
model.find({}).skip(0).limit(1)
.then(res=>{
console.log(res)
return res
})
.catch(err=>{
console.log(‘查询失败’+err)
return false
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
十三、接口
- 简介
随着移动互联网的发展,客户端层出不穷,微信端、 WEB/PC、APP等等,而后端业务逻辑基本是一致的,如
何做到业务逻辑一次编写,多次/随时接入呢?
就是定义接口,调用接口;
1️⃣ 什么是接口?
就是一个文件,主要响应JSON数据(操作方便,体积小)或XML数据
2️⃣ 接口能干嘛?
数据角度:让项目静态而数据动态
功能角度:短信接口,天气接口,股票接口
3️⃣ 去哪找?
通过node/go/java/php等语言去开发
使用第三方接口
4️⃣ 好处
实现一次编写,多次/随机接入,减小后端工作量,方便维护
- 接口开发规范(Restful API)
说明:RESTful是目前最流行的一种互联网软件架构
作用:声明/提供接口设计原则和约束条件
过程:
后端将资源发布到URL上 => 前端通过URL进行访问 => 并通过HTTP动词表示要对资源进行的操作
后端定义接口 => 前端请求接口 => HTTP动词表明操作目的(get获取 post新建 put更新)
1
2
举例:
列表页: 访问-/模块名 get
详情页: 访问-/模块名/编号 get
添加页: 访问-/模块名/create get
处理: 访问-/模块名 post
修改页: 访问-/模块名/编号/edit get
处理: 访问-/模块名/编号 put
删除: 访问-/模块名/编号 delete
好处:统一开发规范,便于团队协作
- 接口测试工具Postman
- 简介
Postman就是一个用来模拟http请求的工具,用于测试接口,查看接口返回数据
后端调试接口避免出现bug
前端查看接口是否使用并查看返回的数据内容
官网:https://www.postman.com/
- 下载安装
下载地址:https://www.postman.com/downloads/,选择合适的版本下载
下载后得到.exe文件,双击进行安装即可
安装完成自动打开,出现如下界面,我们可以在官网创建一个账户进行登录,然后即可使用
- 使用
新建一个request请求
填写相关信息,然后保存
然后填写请求信息,这里以get方式请求https://jsonview.com/example.json
在下面可以看到请求返回的数据
十四、express框架教学系统学生模块接口开发
- express快速入门
1️⃣ 简介:express是基于nodejs开发第一个框架(原理:基于nodejs内置的http模块进行封装),加快项目开发,便于团队协作
官网:https://www.expressjs.com.cn/
2️⃣ 下载:
npm install express --save
1
3️⃣ 简单使用:创建一个js文件
// 1.引入模块
const express = require(“express”);
// 2.创建app对象(底层原理是http模块的createServer)
const app = express()
// 3.编写路由
// 语法: app.HTTP请求方式(路径,回调函数)
app.get(‘/’,(req,res)=>{
//send是express用来响应数据
res.send(“hello”)
})
// 4.启动服务监听端口
app.listen(3000, () => {
console.log(‘http://localhost:3000’);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
运行该js文件测试,打开浏览器3000端口,可以看到效果
教学系统学生模块接口开发
项目总结构:安装模块依赖
新建一个空目录,用vscode打开,首先安装相关模块
npm install express --save
npm install mogoose
npm install body-parser
1
2
3
2 expree框架搭建,定义路由
新建入口文件student.js,首先快速搭建express框架web服务器,其中定义两个路由:
get方式请求/stu,用于添加学生,用stuController.add方法处理(后续编写)
post方式请求/stu,用于查询所有学生,用stuController.index方法处理(后续编写)
// 1.引入模块
const express = require(“express”);
const bodyparser = require(‘body-parser’)
// 2.创建app对象(底层原理是http模块的createServer)
const app = express()
app.use(bodyparser.urlencoded({extended:true}))
app.use(bodyparser.json())
// 3.编写路由
// ----------添加学生-----------
const stuController = require(process.cwd() + ‘/controller/stuController’)
app.post(‘/stu’, stuController.add)
// ----------查询学生-----------
app.get(‘/stu’,stuController.index)
// 4.启动服务监听端口
app.listen(3000, () => {
console.log(‘http://localhost:3000’);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
3. mongoose模块操作数据库
在项目目录下新建models包,其中新建stuModels.js,采用mongoose模块实现操作mongodb数据库,定义并暴露两个方法:
添加学生insert
查询所有学生query
// 一、导入模块
var mongoose = require(“mongoose”);
// 二、连接数据库
const db = mongoose.createConnection(‘mongodb://shop2:123456@localhost:27017/shop’, {
useNewUrlParser: true,
useUnifiedTopology: true
}, err => {
if (err) {
console.log(‘数据库连接失败’, err);
return;
}
console.log(‘数据库连接成功’);
})
// 三、设置数据类型(声明哪个是集合,限制字段个数和字段类型)
const model = db.model(‘stu’, {
name: {
type: String,
default: “zsr”
},
age: {
type: Number
},
sex: {
type: String
}
})
// insert添加方法
const insert = postData => {
const insertObj = new model(postData)
return insertObj.save()
.then(res => {
return res
})
.catch(err => {
console.log(‘插入失败’ + err)
return false
})
}
// query查询方法
const query = () => {
return model.find()
.then(res => {
return res
})
.catch(err => {
console.log(‘查询失败’ + err)
return false
})
}
// 导出insert方法
module.exports = {
insert,
query
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
3. 编写路由处理方法
在项目目录下新建controller包,其中新建stuController.js,用于处理路由,其中暴露两个方法:
add用于处理post请求/stu添加学生
index用于处理get请求/stu查询全部学生
//导入模型
const stuModel = require(process.cwd() + ‘/models/stuModel’)
//定义add添加学生方法
const add = async (req, res) => {
//1.接收数据
let postData = req.body
console.log(postData)
//2.过滤(忽略)
//3.操作数据库
let rs = await stuModel.insert(postData)
//4.判断返回
if (rs) {
res.send({
meta: {
state: 200,
msg: “添加成功”
},
data: null
})
} else {
res.send({
meta: {
state: 500,
msg: “添加失败”
},
data: null
})
}
}
//定义index查询学生方法
const index = async (req, res) => {
//1.获取数据
let data = await stuModel.query()
//2.响应数据
res.send({
meta: {
stage: 200,
msg: “查询成功”
},
data: data
})
}
//导出方法
module.exports = {
add,
index
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
4. 测试
运行入口文件student.js,然后打开postman进行测试
1️⃣ 首先进行 添加学生 测试,以post方式请求http://localhost:3000/stu
根据返回结果,可以看到成功添加,再回到Robo 3T查看数据库结果,成功添加学生
2️⃣ 然后进行 查询所有学生 测试,以get方式请求http://localhost:3000/stu
根据返回结果,成功查询到学生信息
- 接口文档开发apiDoc
- 简介
apiDoc就是nodejs中的一个模块,用于通过注释快速生成接口文档
官网:https://apidocjs.com/
- 使用
1️⃣ 下载模块,后期通过注释生成接口文档
npm install apidoc -g
1
2️⃣ 项目根目录下创建apidoc.json文件,格式如下:
{
“name”: “example”,
“version”: “0.1.0”,
“description”: “apiDoc basic example”,
“title”: “Custom apiDoc browser title”,
“url” : “https://api.github.com/v1”
}
1
2
3
4
5
6
7
3️⃣ 添加接口注释,在stuController.js处理路由方法中添加注释
//导入模型
const stuModel = require(process.cwd() + ‘/models/stuModel’)
//定义add添加学生方法
/**
- @api {post} /stu 添加学生
- @apiName add
- @apiGroup Stu
- @apiParam {String} name 学生姓名
- @apiParam {Number} age 学生年龄
- @apiParam {String} sex 学生性别
- @apiSuccess {String} meta 状态码&提示信息
- @apiSuccess {String} data 数据
*/
const add = async (req, res) => {
//1.接收数据
let postData = req.body
console.log(postData)
//2.过滤(忽略)
//3.操作数据库
let rs = await stuModel.insert(postData)
//4.判断返回
if (rs) {
res.send({
meta: {
state: 200,
msg: “添加成功”
},
data: null
})
} else {
res.send({
meta: {
state: 500,
msg: “添加失败”
},
data: null
})
}
}
//定义index查询学生方法
/**
- @api {get} /stu 查询学生列表
- @apiName index
- @apiGroup Stu
- @apiParam {Number} id Users unique ID.
- @apiSuccess {String} meta 状态码&提示信息
- @apiSuccess {String} data 数据
*/
const index = async (req, res) => {
//1.获取数据
let data = await stuModel.query()
//2.响应数据
res.send({
meta: {
stage: 200,
msg: “查询成功”
},
data: data
})
}
//导出方法
module.exports = {
add,
index
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
4️⃣ 生成接口文档
apidoc -i ./接口注释目录 -o ./接口文档存放目录
1
运行以上命令后,项目根目录下生成了doc目录,找到其中的index.html文件
用浏览器打开,就是生成的接口文档
————————————————
版权声明:本文为CSDN博主「Baret-H」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45173404/article/details/114260970
MongoDB超详细教程(保姆级)相关推荐
- k8s搭建(超详细,保姆级教程)
1.简介 这里就不赘述,想要了解的朋友直接去这里深入了解什么是K8S. 2.环境要求 2台以上机器,操作系统 CentOS7.7-64位系统 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘 ...
- 阿里云轻量级服务器部署springboot项目详细教程--保姆级入门
目录 一.服务器的配置与连接 1.配置服务器初始密码 2.进行远程连接 二. 项目部署相关的软件安装 1.JDK的安装 2.Tomcat的安装 3.MySQL的安装 三. 项目部署服务器 1.修改项目 ...
- 【2023最新】超详细图文保姆级教程:App开发新手入门(1)
1. 关于 『YonBuilder移动开发』 PS: 本段内容主要目的是去除官方语音描述,用通俗的语言来简单介绍一下『YonBuilder移动开发』,方便新手开发者判断是否适合自己上手学习. 简介: ...
- STM32移植LVGL8.0.2超详细的保姆级教程附移植好的工程文件
文章目录 前言 一.什么是LVGL? 二.先看效果 三.移植前准备工作 1.准备原有工程 2.下载LVGL源码 四.开始移植 1.把源码搬运到工程文件夹里 2.把搬运好的代码添加到keil工程 3.动 ...
- 【2023最新】超详细图文保姆级教程:App开发新手入门(5)
上文回顾,我们已经完成了一个应用的真机调试,本章我们来了解一下如何引入YonBuilder移动开发的(原生)移动插件, 并利用移动插件完成一个简单的视频播放器. 8. 「移动插件」的使用 8.1 什么 ...
- 【2023最新】超详细图文保姆级教程:App开发新手入门(4)
之前章节我们已经完成了一个应用项目的导入.代码更新和代码提交和应用打包编译,本章继续讲述一下,如何在开发过程中进行代码的同步联机调试. 7 代码真机调试 7.1 纯静态CSS页面样式查看 代码调试有多 ...
- 猿如意中的【ApiFox】工具的安装与使用教程,超详细,保姆级教程看这一篇文章就够了。
目录 一.什么是猿如意 二.猿如意中下载安装 ApiFox 2.1.如何下载和安装 2.2.什么是 ApiFox? 三.关于 ApiFox 的介绍以及使用 1.基本介绍 2.支持API文档导入 3.接 ...
- 【2023最新】超详细图文保姆级教程:App开发新手入门(2)
上章节我们已经成功的创建了一个 App 项目,接下来我们讲述一下,如何导入项目.编辑代码和提交项目代码. Let's Go! 4. 项目导入 当用户创建一个新的应用时,YonStudio 开发工具会自 ...
- 超详细图文保姆级教程:App开发新手入门(二)
上文我们已经成功的创建了一个项目,接下来我们讲述一下,如何导入.编辑.提交项目代码下面我们继续. 4. 开发调试 4.1 项目导入 当用户创建一个新的应用时,Studio3开发工具会自动导入项目代码, ...
最新文章
- Winform中实现Excel导入、表格展示、多选获取值、生成二维码、打印流程(附代码下载)
- 微软.Net开发中的多线程编程总结
- webbrowser 模块的 open()方法
- 灰狼优化算法与影响力最大化问题
- 关于PCB板设计中电阻电容等封装的选择
- layabox学习(一)·helloworld以及自定义路径
- Java相关脚本-排查最消耗CPU的线程\Jar冲突
- 当Analyzer 2007 遇上.Net 3.0时,可能会秀才爱上兵
- 二极管(四):齐纳二极管
- [洛谷P4118][Ynoi2016]炸脖龙I([洛谷P3934]Nephren Ruq Insania)
- 3060ti适配的cuda和cudnn
- UKF-MATLAB实现
- 项目4.1穷举法-百元买百鸡
- 2010最新会计科目表
- cbow和skip-gram比较
- 老年护理虚拟仿真解决方案
- 清分系统层即综合中央计算机,特种计算机在上海地铁AFC系统的应用.doc
- PDF工具中的铅笔工具要怎么使用?PDF铅笔工具使用教程
- 基于java电力设备管理系统
- bzoj 4349: 最小树形图 朱-刘算法