ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mongodb基础操作

2022-08-28 00:30:08  阅读:176  来源: 互联网

标签:name ObjectId mongodb age 基础 操作 total true id


前言

本文主要针对的是mongoDB的基本操作,以及使用python语言对mongodb的接口调用。
使用工具为pycharme
robot 3T【已经被收购,推出了收费版。robot 3T还是免费的】

简单的curd

mongDB终端的调用
添加
单条插入,再插入的时候会自动创建集合。但是没有插入数据mongodb是不会给该数据库创建集合的
db.basic.insert({"banner":
              {"version":"1.5.10",
                "name":"banana",
"url":"https://d8adcj2p1hmcm.2a5af24a944943436.png",
                "start_time":1656604800,
                "end_time":1656604800}})

多条批量插入
db.basic.insertMany([
{
   "banner": {
       "version": "1.5.10",
       "name": "rabbit",
       "url": "https://d8adc72f2dda2a5af24a944943436.png",
       "start_time": 1656604800,
       "end_time": 1656604800
  },
   "total":2,
   "category_id": "d6e3af40-3d42-315d-a983-ce745277593f"
},
{
   "banner": {
       "version": "1.5.11",
       "name": "oppo",
       "url": "https://d8adcj22dda2a5af24a944943436.png",
       "start_time": 1656604800,
       "end_time": 1656604800
  },
   "total":5,
   "category_id": "d6eeaf40-3c42-315d-a983-ce745277593f"
},
{
   "banner": {
       "version": "1.5.12",
       "name": "huawei",
       "url": "https://d8adcj2p12dda2a5af24a944943436.png",
       "start_time": 1656604800,
       "end_time": 1656604800
  },
   "total":10,
   "category_id": "d6e33440-3c42-315d-a983-ce745277593f"
},
{
   "banner": {
       "version": "1.5.13",
       "name": "xiaomi",
       "url": "https://f40c06c8071321a872f2dda2a5af24a944943436.png",
       "start_time": 1656604800,
       "end_time": 1656604800
  },
   "total":20,
   "category_id": "06e3af40-3c42-315d-a983-ce745277593f"
},
{
   "banner": {
       "version": "1.5.13",
       "name": "apple",
       "url": "https://f40c06c8071321a872f2dda2a5af24a944943436.png",
       "start_time": 1656604800,
       "end_time": 1656604800
  },
   "total":7,
   "category_id": "d6e3af40-3c42-315d-a983-ce745277593f"
}
])
               
注意insert是insertOne于insertMany的并集,insert是很老的版本使用不建议再使用
查看

条件查询

查看所有的数据
db.basic.find({})
查看total值大于10
db.basic.find({"total":{"$gt":10}})
查看total为空,即不存在total的字段的文档
db.basic.find({"total":{"$ne":null}})

查询total>10,定义展示的字段banner,total,但是默认还会展示_id
db.basic.find({"total":{"$gt":10}},{"banner":true,"total":true})
查询total>10,定义展示的字段banner的version字段,total,不展示_id;
db.basic.find({"total":{"$gt":10}},{"banner.version":true,"total":true,"_id":0})
如果没有total,将不展示total
db.basic.find({"total":{"$eq":null}},{"banner.version":true,"total":true,"_id":0})

db.basic.count({})
修改
db.basic.updateOne({"total":{"$eq":2}},
                  {"$set":{"banner.version":"1.8.1"}}
                  )

db.basic.updateMany({"total":{"$gt":10}},
                  {"$set":{"banner.version":"1.6.1"}}
                  )

注意
update 已被弃用,返回{n:1, nModified:1}
返回{n:1, nModified:1}
更新一个就用updateOne,是对update的封装,不支持{multi:true}属性,加了也没用,返回{n:1, nModified:1}
返回{n:1, nModified:1}
更新多个就用updateMany,是对update的封装,自动加入了{multi:true}属性,设为false也不行,返回{n:1, nModified:1}
返回{n:1, nModified:1}
删除
db.basic.deleteOne({"total":{"$eq":7}})
db.basic.deleteMany({"total":{"$eq":7}})
python的调用
"""
@author:taipi
desc:处理一次增删改查
"""
from bson import ObjectId
from pymongo import MongoClient
from mongo.config import host,port,username,password
client = MongoClient(host=host,port=port,username=username,password=password)
collection = client.mongo_basic.mongo_basic

data_list = [
  {'name': '朱小三', 'age': 20, 'address': '北京'},
  {'name': '刘小四', 'age': 21, 'address': '上海'},
  {'name': '马小五', 'age': 22, 'address': '山东'},
  {'name': '夏侯小七', 'age': 23, 'address': '河北'},
  {'name': '公孙小八', 'age': 24, 'address': '广州'},
  {'name': '慕容小九', 'age': 25, 'address': '杭州'},
  {'name': '欧阳小十', 'age': 26, 'address': '深圳'},

]
# 插入操作
collection.insert_many(data_list)

# 更新操作
result = collection.update_many(
  {'name': '马小五'},
  {'$set': {'address': '鞍山', 'age': 32}}
)

result = collection.update_one({'name': '隐身人'},
                              {'$set': {'name': '隐身人','age': 0,'address': '里世界'}},
                              upsert=True)

# 3. 删除
result = collection.delete_many({'age': 0})
print(result)

# 4. 查询
rows = collection.find({})
# 条件查询
rows = collection.find({'age': {'$lt': 25, '$gt': 21},
                       'name': {'$ne': '夏侯小七'}})
# 1. 空值
rows = collection.find({'grade': None})

# 2. 布尔值
rows = collection.find({'student': True}, {'_id': 0})

# 3. 排序参数
rows = collection.find({}, {'_id': 0}).sort('age', -1)

# 4. 查询_id
rows = collection.find({'_id': ObjectId('5b2f75d26b78a61364d09f45')},
                      {'_id': 0})
for row in rows:
   print(row)

高级查询

aggregate一般聚合查询

edcation集合
/* 1 */
{
  "_id" : ObjectId("630807cc0337dacc9a895997"),
  "name" : "李大娃",
  "age" : 10,
  "grade" : "五年级",
  "student" : true,
  "interest" : "唱歌"
}

/* 2 */
{
  "_id" : ObjectId("630807cc0337dacc9a895998"),
  "name" : "张二娃",
  "age" : 12,
  "grade" : "六年级",
  "student" : true,
  "interest" : "跳舞"
}

/* 3 */
{
  "_id" : ObjectId("630807cc0337dacc9a895999"),
  "name" : "马三娃",
  "age" : 14,
  "grade" : "八年级",
  "student" : true,
  "interest" : "下棋"
}

/* 4 */
{
  "_id" : ObjectId("630807cc0337dacc9a89599a"),
  "name" : "刘四娃",
  "age" : 16,
  "grade" : null,
  "student" : false,
  "interest" : "无"
}

/* 5 */
{
  "_id" : ObjectId("630807cc0337dacc9a89599b"),
  "name" : "朱五娃",
  "age" : 18,
  "grade" : "高三",
  "student" : true,
  "interest" : "写字"
}

/* 6 */
{
  "_id" : ObjectId("630807cc0337dacc9a89599c"),
  "name" : "高六娃",
  "age" : 8,
  "grade" : "一年级",
  "student" : true,
  "interest" : "学习"
}

/* 7 */
{
  "_id" : ObjectId("630807cc0337dacc9a89599d"),
  "name" : "赵气娃",
  "age" : 10,
  "grade" : "五年级",
  "student" : true,
  "interest" : "乐高"
}

/* 8 */
{
  "_id" : ObjectId("630807cc0337dacc9a89599e"),
  "name" : "葫芦娃",
  "age" : 100,
  "grade" : null,
  "student" : false,
  "interest" : "喷火"
}

/* 9 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499d5"),
  "name" : "李大娃",
  "age" : 10,
  "grade" : "五年级",
  "student" : true,
  "interest" : "唱歌"
}

/* 10 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499d6"),
  "name" : "张二娃",
  "age" : 12,
  "grade" : "六年级",
  "student" : true,
  "interest" : "跳舞"
}

/* 11 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499d7"),
  "name" : "马三娃",
  "age" : 14,
  "grade" : "八年级",
  "student" : true,
  "interest" : "下棋"
}

/* 12 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499d8"),
  "name" : "刘四娃",
  "age" : 16,
  "grade" : null,
  "student" : false,
  "interest" : "无"
}

/* 13 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499d9"),
  "name" : "朱五娃",
  "age" : 18,
  "grade" : "高三",
  "student" : true,
  "interest" : "写字"
}

/* 14 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499da"),
  "name" : "高六娃",
  "age" : 8,
  "grade" : "一年级",
  "student" : true,
  "interest" : "学习"
}

/* 15 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499db"),
  "name" : "赵气娃",
  "age" : 10,
  "grade" : "五年级",
  "student" : true,
  "interest" : "乐高"
}

/* 16 */
{
  "_id" : ObjectId("630a0c6bfd4705dee45499dc"),
  "name" : "葫芦娃",
  "age" : 100,
  "grade" : null,
  "student" : false,
  "interest" : "喷火"
}

/* 17 */
{
  "_id" : ObjectId("630a0ca0f831c4217f439fd7"),
  "name" : "李大娃",
  "age" : 110,
  "grade" : "五年级",
  "student" : true,
  "interest" : "唱歌"
}

/* 18 */
{
  "_id" : ObjectId("630a0ca0f831c4217f439fd8"),
  "name" : "张二娃",
  "age" : 132,
  "grade" : "六年级",
  "student" : true,
  "interest" : "跳舞"
}

/* 19 */
{
  "_id" : ObjectId("630a0ca0f831c4217f439fd9"),
  "name" : "高六娃",
  "age" : 28,
  "grade" : "一年级",
  "student" : true,
  "interest" : "学习"
}

/* 20 */
{
  "_id" : ObjectId("630a0ca0f831c4217f439fda"),
  "name" : "赵气娃",
  "age" : 190,
  "grade" : "五年级",
  "student" : true,
  "interest" : "乐高"
}

/* 21 */
{
  "_id" : ObjectId("630a0ca0f831c4217f439fdb"),
  "name" : "葫芦娃",
  "age" : 1100,
  "grade" : null,
  "student" : false,
  "interest" : "喷火"
}
basic集合
/* 1 */
{
  "_id" : ObjectId("630979f17b63fa7fc2f1d687"),
  "banner" : {
      "version" : "1.5.10",
      "name" : "banana",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  }
}

/* 2 */
{
  "_id" : ObjectId("63097c877b63fa7fc2f1d688"),
  "banner" : {
      "version" : "1.8.1",
      "name" : "rabbit",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 2.0,
  "category_id" : "d6e3af40-3d42-315d-a983-ce745277593f"
}

/* 3 */
{
  "_id" : ObjectId("63097c877b63fa7fc2f1d689"),
  "banner" : {
      "version" : "1.5.11",
      "name" : "oppo",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 5.0,
  "category_id" : "d6eeaf40-3c42-315d-a983-ce745277593f"
}

/* 4 */
{
  "_id" : ObjectId("63097c877b63fa7fc2f1d68a"),
  "banner" : {
      "version" : "1.5.12",
      "name" : "huawei",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 10.0,
  "category_id" : "d6e33440-3c42-315d-a983-ce745277593f"
}

/* 5 */
{
  "_id" : ObjectId("63097c877b63fa7fc2f1d68b"),
  "banner" : {
      "version" : "1.6.1",
      "name" : "xiaomi",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 20.0,
  "category_id" : "06e3af40-3c42-315d-a983-ce745277593f"
}

/* 6 */
{
  "_id" : ObjectId("630989b37b63fa7fc2f1d68d"),
  "banner" : {
      "version" : "1.5.10",
      "name" : "rabbit",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 2.0,
  "category_id" : "d6e3af40-3d42-315d-a983-ce745277593f"
}

/* 7 */
{
  "_id" : ObjectId("630989b37b63fa7fc2f1d68e"),
  "banner" : {
      "version" : "1.5.12",
      "name" : "huawei",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 10.0,
  "category_id" : "d6e33440-3c42-315d-a983-ce745277593f"
}

/* 8 */
{
  "_id" : ObjectId("630989b37b63fa7fc2f1d68f"),
  "banner" : {
      "version" : "1.5.13",
      "name" : "xiaomi",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 20.0,
  "category_id" : "06e3af40-3c42-315d-a983-ce745277593f"
}

/* 9 */
{
  "_id" : ObjectId("630989b37b63fa7fc2f1d690"),
  "banner" : {
      "version" : "1.5.13",
      "name" : "apple",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 7.0,
  "category_id" : "d6e3af40-3c42-315d-a983-ce745277593f"
}

/* 10 */
{
  "_id" : ObjectId("630989dc7b63fa7fc2f1d691"),
  "banner" : {
      "version" : "1.5.10",
      "name" : "rabbit",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 2.0,
  "category_id" : "d6e3af40-3d42-315d-a983-ce745277593f"
}

/* 11 */
{
  "_id" : ObjectId("630989dc7b63fa7fc2f1d692"),
  "banner" : {
      "version" : "1.5.12",
      "name" : "huawei",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 10.0,
  "category_id" : "d6e33440-3c42-315d-a983-ce745277593f"
}

/* 12 */
{
  "_id" : ObjectId("630989dc7b63fa7fc2f1d693"),
  "banner" : {
      "version" : "1.5.13",
      "name" : "xiaomi",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 20.0,
  "category_id" : "06e3af40-3c42-315d-a983-ce745277593f"
}

/* 13 */
{
  "_id" : ObjectId("630989dc7b63fa7fc2f1d694"),
  "banner" : {
      "version" : "1.5.13",
      "name" : "apple",
      "url" : "https://d8adcj2p1hmcm.cloudfront.net/thumbnail/f40c06c8071321a872f2dda2a5af24a944943436.png",
      "start_time" : 1656604800.0,
      "end_time" : 1656604800.0
  },
  "total" : 7.0,
  "category_id" : "d6e3af40-3c42-315d-a983-ce745277593f"
}
具体实操
aggregate在很多场景都是可以被find实现的,但其的优势在于组合
1)match用法
db.edcation.aggregate(
  [{"$match":{"age":{"$gte":10}}}])
  其本质和find没有什么区别
  db.edcation.find({"age":{"$gte":10}})
2)返回一部分字段project的用法
db.edcation.aggregate(
[{"$match":{"age":{"$gte":10}}},
{"$project":{"_id":0,"name":true,"interest":true}}])
其本质与find的第二括号一致
db.edcation.find({"age":{"$gte":10}},{"_id":0,"name":true,"interest":true})
3)临时添加固定字段"hello",find实现不了
db.edcation.aggregate(
[{"$match":{"age":{"$gte":10}}},
{"$project":{"_id":0,"name":true,"interest":true,"hello":"world"}}])
4)给新字段动态赋值,find实现不了
db.edcation.aggregate(
[{"$match":{"age":{"$gte":10}}},
{"$project":{"_id":0,"name":true,"hobby":"$interest"}}])
5)给现有字段"student"重新赋值,但是这是一个查询性赋值不会修改数据库中真实的内容
db.edcation.aggregate(
[{"$match":{"age":{"$gte":10}}},
{"$project":{"_id":0,"name":true,"hobby":"$interest","student":"true"}}])
6)可以将嵌套的内容取到第一级
db.basic.aggregate({"$match":{"total":{"$ne":null}}},
{"$project":{"total":true,"version":"$banner.version","url":"$banner.url"}})
find取到的依然是分级的
db.basic.find({"total":{"$ne":null}},
{"total":true,"banner.version":true,"banner.url":true})
7)如果固定字段有含有$符号,那么就要使用$literal来解决,这也算是aggregate的bug吧
db.edcation.aggregate(
[{"$match":{"age":{"$gte":10}}},
{"$project":{"_id":0,"name":true,"interest":true,"hello":{"$literal":"$world"}}}])
8)分组去重,与find的distinct还是有本质的区别的;group
db.edcation.aggregate(
        [{"$group":{"_id":"$name"}}])
min,max,avg,sum统计函数的使用
db.edcation.aggregate(
        [{"$group":{"_id":"$name"
            ,"min_age":{"$min":"$age"}
            ,"max_age":{"$max":"$age"}
            ,"sum_age":{"$sum":"$age"}
            }}])

aggregate复杂聚合查询

拆分数组

unwind,但是每次只能拆一个字段

元数据
db.getCollection('clothes').find({}).limit(2)
/* 1 */
{
  "_id" : ObjectId("6308e0edf8fcab402f1c8cae"),
  "name" : "帽子",
  "size" : [
      "L",
      "S"
  ],
  "price" : [
      300,
      100
  ]
}

/* 2 */
{
  "_id" : ObjectId("6308e0eef8fcab402f1c8caf"),
  "name" : "鞋子",
  "size" : [
      "M",
      "L"
  ],
  "price" : [
      800,
      600
  ]
}
实操
db.getCollection('clothes').aggregate(
[{"$unwind":"$size"},{"$unwind":"$price"}
])
/* 1 */
{
  "_id" : ObjectId("6308e0edf8fcab402f1c8cae"),
  "name" : "帽子",
  "size" : "L",
  "price" : 300
}

/* 2 */
{
  "_id" : ObjectId("6308e0edf8fcab402f1c8cae"),
  "name" : "帽子",
  "size" : "L",
  "price" : 100
}
注意这里的操作是限制不了展示的条数返回的

aggregate联合多个集合查询

lookup操作

db.example_user.aggregate(
[{"$lookup":{
  "from":"example_post",
  "localField":"id",
  "foreignField":"user_id",
  "as":"weibo_info"}}
]
)
其格式可以表示为
example_user集合
example_post集合
"localField":"id",example_user集合的id
"foreignField":"user_id",example_post集合的user_id
"as"联合后example_post集合嵌套在example_user集合中且名字为weibo_info,这个as是必须的操作

检验

db.example_user.aggregate(
[
{"$match":{"age":{"$gt":20}}},
{"$lookup":{
  "from":"example_post",
  "localField":"id",
  "foreignField":"user_id",
  "as":"weibo_info"},
  },
{"$unwind":"$weibo_info"},
{"$project":{"work":true,"age":true,"name":true,"content":"$weibo_info.content"}
  }
]
)
元数据

example_post

{
  "_id" : ObjectId("630966fc926011d7763697a5"),
  "user_id" : 1002,
  "content" : "考试完了,好无聊啊啊",
  "post_time" : "2018-06-11 12:23:12"
}

/* 2 */
{
  "_id" : ObjectId("630966fc926011d7763697a6"),
  "user_id" : 1003,
  "content" : "大家看我今天吃得什么[图片]",
  "post_time" : "2018-06-11 12:27:12"
}

example_user

{
  "_id" : ObjectId("630966fd926011d7763697b3"),
  "age" : 17,
  "id" : 1001,
  "name" : "王小一",
  "register_date" : "2018-06-09",
  "work" : "学生"
}

/* 2 */
{
  "_id" : ObjectId("630966fd926011d7763697b4"),
  "age" : 18,
  "id" : 1002,
  "name" : "张小二",
  "register_date" : "2018-06-09",
  "work" : "学生"
}

安全问题

安装
1、下载 https://www.mongodb.com/try/download/community
2、可以创建一下单独文件夹来解压
tar -zxvf mongodb-linux-x86_64-rhel70-4.2.5.tgz -C /usr/local/
3.在/usr/local/mongodb设置mongodb.conf
[root@VM-4-3-centos mongodb]# cat mongodb.conf
  port=27017 #端口
  bind_ip=0.0.0.0 #默认是127.0.0.1
  dbpath=/usr/local/mongodb/data #数据库存放
  logpath=/usr/local/mongodb/logs/mongodb.log #日志文件
  fork=true #设置后台运行
  auth=true #开启认证
4.配置环境变量/etc/profile
export PATH=/usr/local/mongodb/bin:$PATH
5.使配置生效
source /etc/profile
6.在mongodb的根目录下,创建如下文件
mkdir logs data
7.启动服务
mongod --config mongodb.conf
8.查看服务
[root@VM-4-3-centos mongodb]# netstat -tlpn|grep 27017
tcp       0     0 0.0.0.0:27017           0.0.0.0:*               LISTEN  
设置密码
注意密码还是要加上的,尽量还是复杂一些吧。我刚部署的项目,还没来得急上密码就被黑客搞了。很没意思
登录:
/usr/local/mongodb/bin
mongo --port 27017 -u username -p password
mongo --port 27017 将不会查到有效的消息
1)查看所有库
show dbs
2)use admin
3)db.createUser({ user: "admin", pwd: "xx", roles: [{ role: "userAdminAnyDatabase", db: "admin" }] })
4)db.createUser({user: "root",pwd: "xxx", roles: [ { role: "root", db: "admin" } ]})
5)查看集合
show collections;
6)
 

标签:name,ObjectId,mongodb,age,基础,操作,total,true,id
来源: https://www.cnblogs.com/topass123/p/16631863.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有