mongoDB 入门

MongoDB

概念

以下内容复制即用

从本机拷贝文件夹到其他机器上面去  scp -r 本地路径 用户名@ip:路径

从远程拷贝文件夹到本机上去  scp -r 用户名@ip:路径  本地路径

下载地址:https://www.mongodb.com/download-center#community

1.简述MongoDB

MongoDB[1]  是一个基于分布式文件存储的数据库。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

 

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

在高负载的情况下,添加更多的节点,可以保证服务器性能。

MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

 

2.什么是分布式

 

2.1分布式计算的优点

可靠性(容错)

分布式计算系统中的一个重要的优点是可靠性。一台服务器的系统崩溃并不影响到其余的服务器。

可扩展性:

在分布式计算系统可以根据需要增加更多的机器。

资源共享:

共享数据是必不可少的应用,如银行,预订系统。

灵活性:

由于该系统是非常灵活的,它很容易安装,实施和调试新的服务。

更快的速度:

分布式计算系统可以有多台计算机的计算能力,使得它比其他系统有更快的处理速度。

开放系统:

由于它是开放的系统,本地或者远程都可以访问到该服务。

更高的性能:

相较于集中式计算机网络集群可以提供更高的性能(及更好的性价比)。

 

2.2分布式计算的缺点

故障排除:

故障排除和诊断问题。

软件:

更少的软件支持是分布式计算系统的主要缺点。

网络:

网络基础设施的问题,包括:传输问题,高负载,信息丢失等。

安全性:

开发系统的特性让分布式计算系统存在着数据的安全性和共享的风险等问题。

 

 

3.MongoDB特点

 

它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:

*面向集合存储,易存储对象类型的数据。

*模式自由。

*支持动态查询

*支持完全索引,包含内部对象。

*支持查询。

*支持复制和故障恢复。

*使用高效的二进制数据存储,包括大型对象(如视频等)。

*自动处理碎片,以支持云计算层次的扩展性。

*支持RUBYPYTHONJAVAC++PHPC#等多种语言。

*文件存储格式为BSON(一种JSON的扩展)。

*可通过网络访问。

 

 

4.oracle mysql 的对比

 

4.1 MongoDB 术语与SQL术语

SQL术语/概念

MongoDB术语/概念

解释/说明

database

database

数据库

table

collection

数据库表/集合

row

document

数据记录行/文档

column

field

数据字段/域

index

index

索引

table joins

 

表连接,MongoDB不支持

primary key

primary key

主键,MongoDB自动将_id字段设置为主键

 

4.2 数据存储格式比较

 

5.PDNMS,NOSQL简述

 

MongoDB使用的是NoSql

5.1 RDBMS

 - 高度组织化结构化数据 
- 结构化查询语言(SQL) (SQL) 
- 数据和关系都存储在单独的表中。 
- 数据操纵语言,数据定义语言 
- 严格的一致性
- 基础事务

5.2 NOSQL 

- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
-键 - 值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- CAP定理 
- 高性能,高可用性和可伸缩性

 

6.MongoDB可以使用的数据类型

 

类型

数字

备注

Double

1

 

String

2

 

Object

3

 

Array

4

 

Binary data

5

 

Undefined

6

已废弃。

Object id

7

 

Boolean

8

 

Date

9

 

Null

10

 

Regular Expression

11

 

JavaScript

13

 

Symbol

14

 

JavaScript (with scope)

15

 

32-bit integer

16

 

Timestamp

17

 

64-bit integer

18

 

Min key

255

Query with -1.

Max key

127

 

 

操作MongoDB

1.Linux 安装MongoDB

Centos or RedHat 下安装都可

拷贝tar.gz文件到 /root/software/mongoDB 文件夹下

 

 

 

 

解压 tar -zxvf ....

 

移动解压文件到 /usr/local/mongodb 目录下

 

 

cd /usr/local/mongodb查看

 

 

mkdir db 创建数据库存放的路径

mkdir logs 创建存放的日志的路径

 

 

bin目录下创建一个名为mongodb.conf的配置文件加入以下内容:

 

#数据库的存放路径

dbpath = /usr/local/mongodb/db

#日志文件的存放路径

logpath = /usr/local/mongodb/logs/mongodb.log

#使用追加的方式记录日志

logappend = true

#端口

port = 27017

#后台运行

fork = true

#是否开启权限验证

#auth = true

#pid File的完整路径,如果没有设置则没有pid文件

pidfilepath=/usr/local/mongodb/mongo.pid

#声明这是一个集群的分片,默认端口是28017

shardsvr=true

#设置简单的rest Api,即打开的28017端口

rest=true

 

mongoDB设置系统服务

 

vim /etc/rc.d/init.d/mongod

Chmod -R 777 /etc/rc.d/init.d/mongod( 要赋权限,否则启动报权限不够 )

 

根据自己安装的实际情况配置,我的配置如下:

 

mit -SHn 655350

          #!/bin/sh

          # chkconfig: - 64 36

          # description:mongod

          case $1 in

          start)

          /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/bin/mongodb.conf

         ;;

 

         stop)

         /usr/local/mongodb/bin/mongo 127.0.0.1:27017/admin --eval "db.shutdownServer()"

         ;;

 

         status)

         /usr/local/mongodb/bin/mongo 127.0.0.1:27017/admin --eval "db.stats()"

         ;;

         esac

 

关闭防火墙

Centos:  service iptables stop

RedHat:  systemctl stop firewalld

 

开启mongodb 服务,因为我们为mongoDB配置了系统服务,固如此即可

service mongod start

 

 

 

若出现下面这中情况,则是因为没有正常关闭导致的

 

 

 

ps -ef |grep mongod 查看所有进程

 

 

lsof -i:27017 查看指定端口的进程

 

 

cd /usr/local/mongodb/bin

 

 

进入mongo shell界面:

./mongo

如此成功:

 

 

exit quit 都可以退出 mongo shell

关闭mongodb 服务:

service mongod stop

2.一些简单的 mongo shell 命令

可以到菜鸟教程中去看

提供一个网址:http://www.cnblogs.com/cswuyg/p/4595799.html

 

查看所有数据库: show dbs

显示当前用户: show users

得到当前数据库版本:db.version()

得到当前数据库状态: db.stats()

得到数据库的链接地址:db.getMongo()

修复当前数据库: db.repairDatabase();

从指定机器上复制数据库到本地数据库: db.copyDatabase("mydb", "temp", "127.0.0.1");

查看当前使用的数据库: db

切换数据库: use 数据库名

查看数据库下的所以集合: show collections

查看集合下的所有文件:db.集合名.find()  #db就指当前使用的数据库

查看帮助文档: help

在数据库级别查看帮助信息:db.help()

在集合级别查看帮助信息:db.集合名.help()

删除指定集合:db.集合名.drop or db.集合名.remove({}) 删除集合中的所有内容推荐使用第一种,因为remove删除方式需要进行一个全局的查询,速度效率都比较慢

删除数据库 db.dropDatabase() #需要删除哪个数据库就要先切换到哪个数据库

清屏: cls

创建数据库:use 数据库名 #注意,此时我们是没用创建mongodb数据库的,因为该数据库中还未存在有集合,mongodb会监测到该数据库内容为空,并在我们退出该数据库的时候自动清除该数据库

创建集合:db.createCollection(“集合名称”)  #db.createCollection(“message”)

创建一条数据:xiao = {"name":"肖亮亮","age":18,"sex":"男","createTime":new Date()}

向集合中插入一条数据: db.集合名.insert(数据名称)

查询该集合下的所有数据: db.集合名.find() #当查询的数据过多的时候你可以用it 来查看下一页的信息

得到该集合下的一条数据: db.集合名.findOne()

关键字:$exists 小于:$lt  大于:$gt  小于等于:$lte  大于等于:$gte  不等于:$ne  And用,分隔就好了 or : $or  print("输出到shell")  in:$in  not in :$nin

函数: count()

分页:db.message.find().limit(1).skip(1) #即表示显示第一条数据后面的一条数据

排序:db.message.find().sort({字段名:1}) #1表示升序 -1表示降序

删除用户:db.system.users.remove({user:"haha"})

 

3.实际操作

相信仔细看过文档的已经知道了mongodb存储数据的格式了

3.1插入

1.首先创建两个变量用来装载数据 , 注意这里有内嵌函数:xiao = {"name":"肖亮亮","age":18,"sex":"男","createTime":new Date(),desc:{"a":"a","b":"b"}}#这里只是举个例子

xiao = {"name":"肖亮亮","age":18,"sex":"男","createTime":new Date()}

luo = {"name":"罗玲红","age":18,"sex":"女","createTime":new Date()}

#上面有没有看到new Date()操作,不错,在mongodb中不仅可以使用一些函数,而且还支持javascript函数的使用

2.向集合中插入数据

 这里的message是一个集合,如果数据库里没有这个集合,MongoDB会自动创建该集合并插入文档(也就是那一行数据)

 db.message.insert(xiao) 或者 db.message.insert({"name":"肖亮亮","age":18,"sex":"男","createTime":new Date()}) 也可以用save() 方法,

 插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据

 不过一般用insert

 

 

db.message.insert(luo)

3.批量插入 #在3.0.2之前是有批量插入的方法: batchInsert(),后更新融入到Insert方法当中去了

现在直接for循环就好了例:for (var i = 0; i < 100; i++) db.users.save({name:"u_" + i, age: 22 + i, sex: i % 2});

这样就一次性添加进了100条记录

 

4.相信细心的同学以及看到了,创建一条数据时会默认创建一个_id,这个_id和我们数据库中的主键一样是唯一的,可以通过他得到唯一的一条数据,如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据

3.2查询

5.查询数据 #({name:"肖亮亮","age":18})相当于数据库中的 where 后面带的东西  -- where  name = “肖亮亮”and  age = 18 的意思

 

 

简述一下大于小于的使用 #  $lt 小于 $gt大于 上面有表明

 

 

上面是and 的使用 现在讲下or的使用

 

 

相当于 where age = 18 and (name="肖亮亮" or name="罗玲红") 的SQL

 

游标查询:  #当数据一页显示不完的时候 it下一页

var cursor = db.集合名称.find();

while(cursor.hasNext()){

printjson(cursor.next())

}

 

 

forEach循环,同样for循环也可以用

db.集合名称.find().forEach(printjson);

 

 

find游标转化为数组

var arr = db.集合名称.find().toArray();

printjson(arr[1]);

 

这里当然也可以用循环给它输出

 

并且支持where 条件后面带javascript函数:

db.集合名称.find({"$where" : "function() { return this.sex == 0; }"})

 

 

 

模糊查询

db.集合名称.find({name:{$regex:/joe/}})

db.集合名称.find({name:/joe/})

 

Group by

db.集合名称.aggregate([{$group : {_id : "$sex",num_total:{$sum:1}}}])  #表示根据性别分组,并统计总数

Order by

db.集合名称.find().sort({字段名:1}) #1表示升序,-1表示降序

Limit

db.集合名称.find().limit(条数)   如果是0,查出所有  

 

3.3修改

$set

query : update的查询条件,类似sql update查询内where后面的。

update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的

upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。

multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

writeConcern :可选,抛出异常的级别。

 

db.集合名称.update({name:"xiao"},{$set:{name:"liang"}})  #表示将name="xiao" 改为 name="liang"

 

因为_id是唯一的,所以可以根据_id来更新数据例如: 先有一条数据{_id:xxx,name:"xiao"} 现可以 插入一条db.集合名称.insert({_id:xxx,name:"liang"}) 如此便也能修改

3.4 删除

query :(可选)删除的文档的条件。

justOne : (可选)如果设为 true 或 1,则只删除一个文档。

writeConcern :(可选)抛出异常的级别

 

db.集合名称.remove({name:"liu"})

如果只想删除找到的第一条记录如此就好 db.集合名称.remove({name:"liu"},1)

3.5函数,聚合表达式

count():  db.集合名.find().count()

distinct():  db.集合名.distinct("addr",{age:{$gt:18}})  #addr 是去从字段,后面的是条件

表达式

描述

实例

$sum

计算总和。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])

$avg

计算平均值

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])

$min

获取集合中所有文档对应值得最小值。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])

$max

获取集合中所有文档对应值得最大值。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])

$push

在结果文档中插入值到一个数组中。

db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])

$addToSet

在结果文档中插入值到一个数组中,但不创建副本。

db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])

$first

根据资源文档的排序获取第一个文档数据。

db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])

$last

根据资源文档的排序获取最后一个文档数据

db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

 

4.关于用户和权限问题

 

创建用户:

db.createUser(

...   {

...     user: "dba",

...     pwd: "dba",

...     roles: [ { role: "readWrite", db: "luo" } ]

...   }

... )

 

注意,若你想要配置的用户权限验证起作用,将 mongodb.conf 里面的auth解开即可

 

重启mongod 再次./mongo 进入shell的时候 use admin  db.auth("dba","dba")即可验证成功

 

roles:指定用户的角色,可以用一个空数组给新用户设定空角色;在roles字段,可以指定内置角色和用户定义的角色。role里的角色可以选:

 

1.数据库用户角色:readreadWrite;

    2.数据库管理角色:dbAdmindbOwneruserAdmin

    3.集群管理角色:clusterAdminclusterManagerclusterMonitorhostManager

    4.备份恢复角色:backuprestore

    5.所有数据库角色:readAnyDatabasereadWriteAnyDatabaseuserAdminAnyDatabasedbAdminAnyDatabase

    6.超级用户角色:root  

    // 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwneruserAdminuserAdminAnyDatabase

    7.内部角色:__system

 

Read:允许用户读取指定数据库readWrite:允许用户读写指定数据库

dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问

system.profileuserAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。

readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限

readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。

root:只在admin数据库中可用。超级账号,超级权限

5.java代码的链接与调用

 

<dependencies>

    <dependency>

        <groupId>org.mongodb</groupId>

        <artifactId>mongodb-driver</artifactId>

        <version>3.4.1</version>

    </dependency>

    <dependency>

        <groupId>org.mongodb</groupId>

        <artifactId>bson</artifactId>

        <version>3.4.1</version>

    </dependency>

</dependencies>

 

 

 

package com;

 

import java.util.ArrayList;

import java.util.List;

 

import org.bson.Document;

 

import com.mongodb.MongoClient;

import com.mongodb.MongoCredential;

import com.mongodb.ServerAddress;

import com.mongodb.client.FindIterable;

import com.mongodb.client.MongoCollection;

import com.mongodb.client.MongoDatabase;

import com.mongodb.client.result.DeleteResult;

import com.mongodb.client.result.UpdateResult;

 

public class MongoDBJDBC {

 

// MongoDB链接

private static MongoClientmongoClient;

// 得到的数据库对象

private static MongoDatabasemongoDatabase;

// 操作的集合名称

private static final StringCOLLECTION_NAME ="message";

// 集合链接对象

private static MongoCollection<Document>collection;

 

public static void main(String[]args) {

getMogoClient();

createCollection();

insert();

select();

delete();

update();

select();

deleteCollection();

}

 

public static void getMogoClient() {

try {

// ServerAddress()两个参数分别为 服务器地址 和 端口

ServerAddress serverAddress =new ServerAddress("192.168.1.120", 27017);

List<ServerAddress> addrs =new ArrayList<ServerAddress>();

addrs.add(serverAddress);

// MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码

MongoCredential credential = MongoCredential.createScramSha1Credential("dba","xiao", "dba".toCharArray());

List<MongoCredential> credentials =new ArrayList<MongoCredential>();

credentials.add(credential);

// 通过连接认证获取MongoDB连接

mongoClient =new MongoClient(addrs,credentials);

// 连接到数据库

mongoDatabase =mongoClient.getDatabase("xiao");

System.out.println("Connect to database successfully");

} catch (Exceptione) {

System.err.println(e.getClass().getName() +": " + e.getMessage());

}

}

 

public static void createCollection() {

collection =mongoDatabase.getCollection(COLLECTION_NAME);

if (null ==collection) {

mongoDatabase.createCollection(COLLECTION_NAME);

collection =mongoDatabase.getCollection(COLLECTION_NAME);

}

System.out.println("得到的条数: " + collection.count());

}

 

private static void insert() {

System.out.println("向数据集中插入数据开始:");

Document document =new Document();

List<Document> dbList =new ArrayList<Document>();

document.put("name","小李");

document.put("age", 30);

document.put("address","北京");

dbList.add(document);

 

Document document2 =new Document();

document2.put("name","小张");

document2.put("age", 25);

document2.put("address","天津");

dbList.add(document2);

 

collection.insertMany(dbList);

System.out.println("向数据集中插入数据完成!");

System.out.println("------------------------------");

}

 

public static void delete() {

System.out.println("删除【小张】!");

Document document =new Document();

document.put("name","小张");

DeleteResult result =collection.deleteMany(document);

long lo =result.getDeletedCount();

System.out.println("删除成功,共删除 :" +lo);

System.out.println("现数据总条数:  "+collection.count());

}

 

public static void update() {

Document document =new Document();

document.put("age",30);

Document document2 =new Document();

document2.put("name","小罗");

UpdateResult result =collection.replaceOne(document,document2);

System.out.println("修改所影响的行数:     "+result.getModifiedCount());

}

 

public static void select() {

System.out.println("现数据总条数:  "+collection.count());

FindIterable<Document>  find =collection.find();

System.out.println("得到剩余的数据总条数: "+collection.count());

for (Documentdocument : find) {

System.out.println("id:  "+document.get("_id")+"  name:  "+document.getString("name")+"  age:  "+document.getInteger("age",0)+"  address:  "+document.getString("address"));

}

}

public static void deleteCollection(){

collection.drop();

System.out.println("最后操作,删除该集合!!");

}

 

}

 

 

6.MongoDB集群配置Replica Set方式

 

Mongodb的三种集群方式的搭建:Replica Set / Sharding / Master-Slaver

 

使用三个虚拟机  192.168.1.120  192.168.1.121  192.168.1.122 配置如上

 

 

SECONDARY是不允许读写的, 在写多读少的应用中,使用Replica Sets来实现读写分离。

通过在连接时指定或者在主库指定slaveOk,由Secondary来分担读的压力,Primary只承担写操作。对于replica set 中的secondary 节点默认是不可读的,

 

 

vim /etc/rc.d/init.d/mongod

 

只要把为mongoDB设置系统服务的文件改为如下:

   

mit -SHn 655350

          #!/bin/sh

          # chkconfig: - 64 36

          # description:mongod

          case $1 in

          start)

          /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/bin/mongodb.conf--replSet repset

         ;;

 

         stop)

         /usr/local/mongodb/bin/mongo 127.0.0.1:27017/admin --eval "db.shutdownServer()"

         ;;

 

         status)

         /usr/local/mongodb/bin/mongo 127.0.0.1:27017/admin --eval "db.stats()"

         ;;

         esac

 

其他配置和上面完全一样

 

分别开启三个mongod 并关闭防火墙

随便./mongo 进入一个shell

定义一个变量:

 

config = { _id:"repset",

  members:[

      {_id:0,host:"192.168.1.120:27017"},

      {_id:1,host:"192.168.1.121:27017"},

      {_id:2,host:"192.168.1.122:27017"}

      ]}

初始化副本集: rs.initiate(config)

 

查看集群点状态: rs.status()

 

找到主节点./mongo进入shell

 

测试集群db.testdb.insert({"demo":"demo"})

 

登陆从属节点:rs.slaveOk() 设置secondary 为可读

 

之后db.testdb.find() 则可得到信息

 

如此,集群搭建完毕

7.与Spring整合

外部已经提供了zip

 

注意事项:

 

误区 、文档顺序和插入顺序一致?

单线程情况

ObjectId中的timestamp、machine、pid、inc都可以保证唯一,因为在同一台机器,同一个进程。

这里有一个问题,mongodb的操作时多线程的。a、b、c...几个线程进行入库操作时,不能保证哪一条可以在另外一条之前,所以会是乱序的。

多线程、多机器或多进程情况

再看下ObjectId中mache、pid不能保证唯一。那么则数据更加会是乱序的。

解决办法:

由于collection集合中数据是无序的(包括capped collection),那么,最简单的办法是对ObjectId进行排序。

对于 MongoDB入门,你可以按照以下步骤进行学习: 1. 下载并安装 MongoDB:在 MongoDB 的官方网站上下载适合你操作系统的安装程序,并按照提示进行安装。 2. 启动 MongoDB 服务:安装完成后,启动 MongoDB 服务。在 Windows 上,你可以通过运行 `mongod` 命令启动服务。在 macOS 或 Linux 上,可以打开终端并运行 `mongod` 命令。默认情况下,MongoDB 会在本地的 27017 端口上启动。 3. 连接到 MongoDB:在另一个终端窗口或命令提示符中,使用 `mongo` 命令连接到 MongoDB。默认情况下,它会连接到本地的 MongoDB 服务器。 4. 创建数据库:在 `mongo` shell 中,可以使用 `use <database_name>` 命令创建一个新数据库,例如 `use mydb`。 5. 创建集合(表):集合类似于关系数据库中的表。你可以使用 `db.createCollection("<collection_name>")` 命令创建一个新集合,例如 `db.createCollection("mycollection")`。 6. 插入数据:使用 `db.<collection_name>.insertOne(<document>)` 命令将数据插入到集合中。例如,`db.mycollection.insertOne({ name: "John", age: 30 })`。 7. 查询数据:使用 `db.<collection_name>.find()` 命令查询集合中的所有数据。例如,`db.mycollection.find()`。 8. 更新数据:使用 `db.<collection_name>.updateOne(<filter>, <update>)` 命令更新集合中的数据。例如,`db.mycollection.updateOne({ name: "John" }, { $set: { age: 35 } })`。 9. 删除数据:使用 `db.<collection_name>.deleteOne(<filter>)` 命令删除集合中的数据。例如,`db.mycollection.deleteOne({ name: "John" })`。 这是一个 MongoDB 入门的基本流程。你可以根据需要进一步学习和探索 MongoDB 的更多功能和用法。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值