当前位置: 首页 > news >正文

镇江企业网站建设西安汇友网站建设

镇江企业网站建设,西安汇友网站建设,商会网站建设方案书,中英文网站建站1.简介 Mongoose是一个让我们可以通过Node来操作MongoDB的模块。Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装#xff0c;并提供了更多的功能。在大多数情况下#xff0c;它被用来把结构化的模式应用到一个MongoDB集合#xff0c;并… 1.简介 Mongoose是一个让我们可以通过Node来操作MongoDB的模块。Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装并提供了更多的功能。在大多数情况下它被用来把结构化的模式应用到一个MongoDB集合并提供了验证和类型转换等好处mongoose中的对象 Schema 模式对象Schema对象定义约束了数据库中的文档结构Model 模型对象Model对象作为集合中的所有文档的表示相当于MongoDB数据库中的集合collectionDocument 文档对象Document表示集合中的具体文档相当于集合中的一个具体的文档 mongoose的好处 可以为文档创建一个模式结构(Schema)可以对模型中的对象/文档进行验证数据可以通过类型转换转换为对象模型可以使用中间件来应用业务逻辑挂钩比Node原生的MongoDB驱动更容易 安装 npm i -S mongoose2.连接数据库 config/db.config.js // 1.引入mongoose const mongoose require(mongoose);// 2.连接mongodb数据库 // 指定连接数据库后不需要存在当你插入第一条数据库后会自动创建数据库 /* mongoose.connect(mongodb://数据库地址:端口号/数据库名,{useMongoClient:true}) 如果端口号是默认端口号(27017)则可以省略不写 */ mongoose.connect(mongodb://127.0.0.1:27017/ds2, {useNewUrlParser: true,useUnifiedTopology: true,useCreateIndex: true, })// 3.监听mongodb数据库的连接状态 // 绑定数据库连接成功事件 mongoose.connection.once(open, function () {console.log(连接成功); }); // 绑定数据库连接失败事件 mongoose.connection.once(close, function () {console.log(数据库连接已经断开); });// 4.断开数据库连接(一般不用) mongooes.disconnect();注:MongoDB数据库一般情况下只需要连接一次连接一次后除非项目停止服务器关闭否则连接一般不会断开 在bin目录下的www文件中使用直接require(“…/config/db.config.js”)进行数据库连接的启动 3.创建模式对象和模型对象 数据库中的 Schema为数据库对象的集合。schema 是 mongoose 里会用到的一种数据模式可以理解为表结构的定义每个 schema会映射到 mongodb 中的一个 collection它不具备操作数据库的能力。 每个 schema 都会映射到一个 MongoDB collection 并定义这个collection里的文档结构支持的字段类型 类型作用String定义字符串Number定义数字Date定义日期Buffer定义二进制Boolean定义布尔值Mixed定义混合类型ObjectId定义对象IDArray定义数组 model/UserModel.js const mongoose require(mongoose) const Schemamongooes.Schema; //创建模式对象 const UserTypenew Schema({name:{type: string,//添加约束保证数据的完整性让数据按规矩统一require: true},age:Number,gender:{type:String,// 默认值default:female},address:String })//创建模型对象 //通过Schema来创建Model //Model代表的是数据库中的集合通过Model才能对数据库进行操作 //mongoose.model(modelName,schema) //建立映射关系students是集合,mongoose会自动将集合变成复数比如student会变成students //大写也会被自动转换为小写比如Users会变成users const UserModelmongoose.model(UserModel,UserTypeuser); //第一个参数表示创建的集合的名称第二个参数表示利用的模式对象第三个参数是强行指定集合名称module.exports UserModel 4.文档新增 4.1 save() 操作的是文档 案例 var mongoose require(mongoose) const UserModel require(../model/UserModel);//链式调用 通过new 一个Model创建一个 document new UserModel({name:小明,age:18}).save((err,docs) {if(!err){console.log(docs)res.send({code: 200,data: {id: docs._id,},})//{ _id: 6017bd1cf4cc8544d8ed2a8a, name: 小明, age: 18, __v: 0 }} }) 4.2 create() 操作模型Model.create(doc(s), [callback])参数 [doc(s)]文档对象或文档对象数组 [callback]回调函数 var mongoose require(mongoose) const UserModel require(../model/UserModel);UserModel.create({name:小明,age:18},{name:小红,age:10},(err,doc1,doc2) {if(!err){console.log(doc1)//{ _id: 6017be2d77c8dd01242624bb, name: 小明, age: 18, __v: 0 }console.log(doc2)//{ _id: 6017be2d77c8dd01242624bc, name: 小红, age: 10, __v: 0 }} })其它 //Model.createOne(doc, [callback]); 创建一个对象 //Model.createMany(doc, [callback]); 创建多个对象 // -doc是需要插入的文档 // -callback(err) 是回调函数可以用来提示是否创建成功了 4.3 insertMany() Model.insertMany(doc(s), [options], [callback]) 返回值为一个数组 案例 UserModel.insertMany({name:小明,age:18},{name:小芳,age:14},(err,docs) {if(!err){console.log(docs)/*[{ _id: 6017befb5c36d64d08b72576, name: 小明, grades: 68, __v: 0 },{ _id: 6017befb5c36d64d08b72577, name: 小芳, grades: 94, __v: 0 }]*/} })5.文档查询 _idnamegrades__v6017befb5c36d64d08b72576小明6806017befb5c36d64d08b72577小芳9406017c455ba09d355a49ec8eb小红5206017c455ba09d355a49ec8ec小刚460 5.1 find() Model.find(conditions, [projection], [options], [callback]) 参数 ​ conditions查询条件​ ​ [projection]控制返回字段​ ​ [options]配置查询参数​ ​ [callback]回调函数–function(err,docs){} 案例 var mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,(err) {if(!err){var schema new mongoose.Schema({name:String,grades:Number})var stuModel mongoose.model(grades,schema)//查询所有数据stuModel.find((err,docs) {if(!err){console.log(docs)}}) /* [{ _id: 6017befb5c36d64d08b72576, name: 小明, grades: 68, __v: 0 },{ _id: 6017befb5c36d64d08b72577, name: 小芳, grades: 94, __v: 0 },{ _id: 6017c455ba09d355a49ec8eb, name: 小红, grades: 52, __v: 0 },{ _id: 6017c455ba09d355a49ec8ec, name: 小刚, grades: 46, __v: 0 }]*///查询成绩大于60以上的数据stuModel.find({grades:{$gte:60}},(err,docs) {if(!err){console.log(docs)}})/*[{ _id: 6017befb5c36d64d08b72576, name: 小明, grades: 68, __v: 0 },{ _id: 6017befb5c36d64d08b72577, name: 小芳, grades: 94, __v: 0 }]*///查询成绩大于60以上且名字里存在‘芳’的数据stuModel.find({name:/芳/,grades:{$gte:60}},(err,docs) {if(!err){console.log(docs)}})/*[* { _id: 6017befb5c36d64d08b72577, name: 小芳, grades: 94, __v: 0 }* ]*///查询名字里存在‘明’的数据且只输出‘name’字段//_id默认会返回stuModel.find({name:/明/},{name:1,_id:0},(err,docs) {if(!err){console.log(docs)}})// [{name: 小明}]//跳过前两条数据并限制只输出一条数据stuModel.find(null,null,{skip:2,limit: 1},(err,docs) {if(!err){console.log(docs)}})/*[{ _id: 6017c455ba09d355a49ec8eb, name: 小红, grades: 52, __v: 0 }*/} })5.2 findById() Model.findById(id, [projection], [options], [callback])案例 var mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,(err) {if(!err){var schema new mongoose.Schema({name:String,grades:Number})var stuModel mongoose.model(grades,schema)//保存查询数据的_idvar aIDArr []//查询所有数据stuModel.find((err,docs) {if(!err){docs.forEach((item,index,arr){aIDArr.push(item._id)})//显示第 0 个元素的所有字段stuModel.findById(aIDArr[0],(err,doc){if(!err){console.log(doc)}})// { _id: 6017befb5c36d64d08b72576, name: 小明, grades: 68, __v: 0 }//显示第 0 个元素且只输出name字段stuModel.findById(aIDArr[0],{name:1,_id:0},(err,doc){if(!err){console.log(doc)}})// { name: 小明 }//显示第 0 个元素且输出最少的字段(_id默认输出)stuModel.findById(aIDArr[0],{lean:true},(err,doc){if(!err){console.log(doc)}})// { _id: 6017befb5c36d64d08b72576 }}})} })5.3 findOne() 返回查询到的数据的第一个Model.findOne([conditions], [projection], [options], [callback])案例 var mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,(err) {if(!err){var schema new mongoose.Schema({name:String,grades:Number})var stuModel mongoose.model(grades,schema)//找出age80的文档中的第一个文档stuModel.findOne({grades:{$gt:80}},(err,doc) {if(!err){console.log(doc)}})//{ _id: 6017befb5c36d64d08b72577, name: 小芳, grades: 94, __v: 0 }//找出age80的文档中的第一个文档且只输出name字段stuModel.findOne({grades:{$gt:80}},{name:1,_id:0},(err,doc) {if(!err){console.log(doc)}})//{ name: 小芳 }//找出age80的文档中的第一个文档且输出包含name字段在内的最短字段stuModel.findOne({grades:{$gt:80}},{lern:true},(err,doc) {if(!err){console.log(doc)}})//{ _id: 6017befb5c36d64d08b72577 }} })5.4 复杂查询【$where】 $where 可以使用任意的 JavaScript 作为查询的一部分包含JavaScript 表达式的字符串或者函数案例 var mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,(err) {if(!err){var schema new mongoose.Schema({name:String,grades:Number})//添加一个测试字段// schema.add({test:Number})var stuModel mongoose.model(grades,schema)//添加两条数据// stuModel.create({name:小花,grades:76,test:76},{name:小兰,grades:60,test:30},(err,docs){// console.log(docs)// })//字符串 es5中this与obj指向一样es6中只能用objstuModel.find({$where:this.grades this.test || obj.grades obj.test},(err,doc) {if(!err){console.log(doc)}})//[{_id: 6017d7cb8a95cb2a00aae3ae,name: 小花,grades: 76,test: 76,__v: 0}]//函数stuModel.find({$where:function() {return this.grades this.test || obj.grades obj.test*2}},(err,doc) {if(!err){console.log(doc)}})/*[{_id: 6017d7cb8a95cb2a00aae3ae,name: 小花,grades: 76,test: 76,__v: 0},{_id: 6017d7cb8a95cb2a00aae3af,name: 小兰,grades: 60,test: 30,__v: 0}]*/} })5.5 常用查询条件 $or     或关系$nor    或关系取反$gt     大于$gte    大于等于$lt     小于$lte    小于等于$ne     不等于$in     在多个值范围内$nin    不在多个值范围内$all    匹配数组中多个值$regex   正则用于模糊查询$size    匹配数组大小$maxDistance  范围查询距离基于LBS$mod     取模运算$near    邻域查询查询附近的位置基于LBS$exists   字段是否存在$elemMatch  匹配内数组内的元素$within    范围查询基于LBS$box     范围查询矩形范围基于LBS$center    范围醒询圆形范围基于LBS$centerSphere 范围查询球形范围基于LBS$slice     查询字段集合中的元素比如从第几个之后第N到第M个元素5.6 特定类型查询 _idnamegrades__vtest6017befb5c36d64d08b72576小明68016017befb5c36d64d08b72577小芳94036017c455ba09d355a49ec8eb小红52056017c455ba09d355a49ec8ec小刚46026017d7cb8a95cb2a00aae3ae小花76046017d7cb8a95cb2a00aae3af小兰6006 方法 方法作用sort排序skip跳过limit限制select显示字段exect执行count计数distinct去重 exec(和 then() 两者返回的都是 promise对象 exec一般用于独立的动作一次性执行 then则用于连续性的动作 从其方法名也可以区别它们的用法exec就是执行的意思then就是然后怎么怎么 exec和then的参数是有所不同的前者是 callback(err,doc)后者则是 resolved(doc),rejected(err) 案例 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}}) var stuModel mongoose.model(grades, Schema);// 按test从小到大排序 // 1是升序-1是降序 stuModel.find().sort({test:1}).exec((err,docs){console.log(docs) }) // 按test从大到小排列 stuModel.find().sort(-test).exec((err,docs){console.log(docs) }) // 跳过1个显示其他 stuModel.find().skip(1).exec((err,docs){console.log(docs) }) // 显示2个 stuModel.find().limit(2).exec((err,docs){console.log(docs) }) // 显示name、grades字段不显示id字段 stuModel.find().select(name grades -id).exec((err,docs){console.log(docs) }) // 跳过第1个后只显示2个数据按照grades由大到小排序且不显示id字段 stuModel.find().skip(1).limit(2).sort(-grades).select(-id).exec((err,docs){console.log(docs)/[{ name: 小明, grades: 78, v: 0, test: 1 },{ name: 小花, grades: 76, test: 4, v: 0 }]/ }) // 显示集合stuModel中的文档数量 stuModel.find().count((err,count){console.log(count)//6 }) // 返回集合stuModel中的grades的值 stuModel.find().distinct(grades,(err,distinct){console.log(distinct)//[ 46, 52, 60, 76, 78, 94 ] })6.文档更新 6.1 update() Model.update(conditions, doc, [options], [callback])参数 conditions查询条件doc需要修改的数据插入的数据[options]控制选项 safe (boolean) 默认为true。安全模式。 upsert (boolean) 默认为false。如果不存在则创建新记录。 multi (boolean) 默认为false。是否更新多个查询记录。 runValidators 如果值为true执行Validation验证。 setDefaultsOnInsert 如果upsert选项为true在新建时插入文档定义的默认值。 strict (boolean) 以strict模式进行更新。 overwrite (boolean) 默认为false。禁用update-only模式允许覆盖记录。 [callback]回调函数若设置了查询条件当数据库不满足时默认什么也不发生update() 方法中的回调函数不能省略否则数据不会更新当回调无有用信息时可以使用exec()简化 stuModel.update({name:小明},{$set:{test:34}}.exec())案例 //第一步引入mongoose const mongoose require(mongoose) //第二步连接数据库 mongoose.connect(mongodb://localhost:27017/student,err{if(!err){//第三步创建模板var Schema new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})// var Schema new Schema()//第四步将模板映射到集合并创建var stuModel mongoose.model(grades,Schema)//查询name为小明的数据并将其test更改为34//若有多个文档默认只更新第一个stuModel.update({name:小明},{$set:{test:34}},(err,raw){console.log(raw)})//{ n: 1, nModified: 1, ok: 1 }//6017befb5c36d64d08b72576 小明 68 0 34} })6.2 updateOne() Model.updateOne(conditions, doc, [options], [callback])与update()相似唯一区别为updateOne() 默认更新一个文档即使设置{multi:true}也无法只更新一个文档 6.3 updateMany() Model.updateMany(conditions, doc, [options], [callback])与update()相似唯一区别为updateMany() 默认更新多个文档即使设置{multi:false}也无法只更新一个文档 6.4 find()save() 用于复杂更新 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,err{if(!err){var Schema new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel mongoose.model(grades,Schema)//查询成绩小于60的数据并在其名字后添加‘差生’字段stuModel.find({grades:{$lt:60}},(err,docs){console.log(docs);/*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: 小红,grades: 52,__v: 0},{test: 0,_id: 6017c455ba09d355a49ec8ec,name: 小刚,grades: 46,__v: 0}]*/docs.forEach((item,index,arr) {item.name 差生//将修改后的数据保存item.save()})console.log(docs)/*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: 小红差生,grades: 52,__v: 0},{test: 0,_id: 6017c455ba09d355a49ec8ec,name: 小刚差生,grades: 46,__v: 0}]*/})} })6.5 findOne() save() 用于复杂更新findOne()返回值为文档对象 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,err{if(!err){var Schema new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel mongoose.model(grades,Schema)//查询成绩小于60的数据并在其名字后添加‘差生’字段stuModel.findOne({name:小明},(err,doc){console.log(doc);//{test: 34,_id: 6017c455ba09d355a49ec8eb,name: 小明,grades: 68,__v: 0},doc.age 10doc.save()console.log(docs)//{test: 34,_id: 6017c455ba09d355a49ec8eb,name: 小明,grades: 78,__v: 0}})} })6.6 fingOneAndUpdate() Model.findOneAndUpdate([conditions], [update], [options], [callback]) 6.7 findByIdAndUpdate() Model.findByIdAndUpdate([conditions], [update], [options], [callback]) 7.文档删除 7.1 deleteOne() 会删除符合条件的所有数据Model的deleteOne const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,err{if(!err){var Schema new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel mongoose.model(grades,Schema)//删除名字中包含‘差生’的数据stuModel.deleteOne({name:/差生/},function(err){})// 回调函数不能省略但可以使用exec() 简写//stuModel.deleteOne({name:/差生/}).exec()})} })文档的deleteOne const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student,err{if(!err){var Schema new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel mongoose.model(grades,Schema)//删除名字中包含‘差生’的数据stuModel.find({name:/差生/},function(err,docs){docs.forEach((item,index,arr){item.deleteOne((err,doc){//doc为被删除的值console.log(doc)})})})})} })7.2 findOneAndRemove() 删除符合条件的一条数据Model.findOneAndRemove(conditions, [options], [callback])回调不可省略但可以使用exec() 简写 stuModel.findOneAndRemove({name:/差生/}).exec()7.3 findByIdAndRemove() 通过id删除数据id是唯一的Model.findByIdAndRemove(conditions, [options], [callback])回调不可省略但可以使用exec() 简写 8.前后钩子 前后钩子即 pre() 和 post() 方法中间件中间件在schema上指定类似静态方法或实例方法等可以在执行以下操作时设置前后钩子 init validate save remove count find findOne findOneAndRemove findOneAndUpdate insertMany update 【pre()】在执行某些操作前执行 【post】在执行某些操作前后执行不可以使用next() 案例 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}}) Schema.pre(find,function(next){console.log(我是pre方法1);next(); }); Schema.pre(find,function(next){console.log(我是pre方法2);next(); }); Schema.post(find,function(docs){console.log(我是post方法1); }); Schema.post(find,function(docs){console.log(我是post方法2); }); var stuModel mongoose.model(grades, Schema); stuModel.find(function(err,docs){console.log(docs[0]); }) /* 我是pre方法1 我是pre方法2 我是post方法1 我是post方法2 {test: 34, _id: 6017befb5c36d64d08b72576,name: 小明,grades: 78,__v: 0} */9.文档验证 保证保存文档时可以按照Schema设置的字段进行设置 9.1 【required】数据必填 //将name设置为必填字段如果没有name字段文档将不被保存且出现错误提示 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({name:{type:String,required:true},age:Number }) var stuModel mongoose.model(students, Schema); new stuModel({age:20}).save((err,doc){if(err){return console.log(err)}console.log(doc) })//报错name: Path name is required.9.2 【default】默认值 //设置age字段的默认值为18如果不设置age字段则会取默认值 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({name:String,age:{type:Number,default:18} }) var stuModel mongoose.model(students, Schema); new stuModel({name:李雷}).save((err,doc){if(err){return console.log(err)}console.log(doc) })//{ age: 18, _id: 6018f3bd7e51343e6c4f212b, name: 李雷, __v: 0 }9.3 【min】【max】最小/大值 只适用于数字 //将age的取值范围设置为[0,10]。如果age取值为20文档将不被保存且出现错误提示 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({name:String,age:{type:Number,min:10,max:18} }) var stuModel mongoose.model(students, Schema); new stuModel({name:李雷,age:20}).save((err,doc){if(err){return console.log(err)}console.log(doc) })//age: Path age (20) is more than maximum allowed value (18).9.4 【match】正则匹配 只适用于字符串 //将name的match设置为必须存在01字符。如果name不存在01文档将不被保存且出现错误提示 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({name:{type:String,match:/01/},age:Number, }) var stuModel mongoose.model(students, Schema); new stuModel({name:李雷,age:20}).save((err,doc){if(err){return console.log(err)}console.log(doc) })//name: Path name is invalid (李雷).9.5【enum】枚举匹配 只适用于字符串 //将name的枚举取值设置为[zs,ls,ww]如果name不在枚举范围内取值文档将不被保存且出现错误提示 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({name:{type:String,enum:[zs,ls,ww]},age:Number, }) var stuModel mongoose.model(students, Schema); new stuModel({name:lss,age:20}).save((err,doc){if(err){return console.log(err)}console.log(doc) })//name: ValidatorError: lss is not a valid enum value for path name.9.6 【validate】自定义匹配 validate实际上是一个函数函数的参数代表当前字段返回true表示通过验证返回false表示未通过验证 //定义名字name的长度必须在4个字符以上 const mongoose require(mongoose) mongoose.connect(mongodb://localhost:27017/student) var Schema new mongoose.Schema({name:{type:String,validate:nameLength},age:Number, }) var stuModel mongoose.model(students, Schema); new stuModel({name:abcd,age:20}).save((err,doc){if(err){return console.log(err)}console.log(doc) })function nameLength(arg){if(arg.length4){return true}return false }//name: Validator failed for path name with value abcd
http://www.hkea.cn/news/14265220/

相关文章:

  • 网站前台需求文档wordpress创建数据库错误
  • asp.net 知名网站网络架构模拟器
  • 百度网站验证方法网络营销策划推广公司招聘
  • 专业网站建设服务东莞科技网站建设
  • 打开部分网站很慢sina邮箱登录入口
  • ?a品定制网站开发建筑企业资质加盟
  • 旅游网页设计模板网站免费wordpress archives页
  • 广州做网站建设的公司制作百度移动网站模板免费下载
  • 做网上贸易哪个网站好国内网站设计
  • 杭州seo相关网站自己找厂家做代理卖货
  • 海外网站怎么浏览哈尔滨云建站模板
  • 网站标题堆砌关键词网站开发用户登录前 登录后
  • 代理小企业网站建设做汤的网站有哪些
  • 公司刚做网站在那里找图片做如何把网站的文字编辑
  • 永兴网站开发网站模板怎样发布
  • 网站设计的必要性在广州开发一个营销网站多少钱
  • 北京市网站设计-推广公司苏州网站制作哪家好
  • 四川纵川建设机械有限公司网站网站怎么自适应屏幕
  • 网站优化 工具什么公司做网站出名
  • 苏州官方网站建站雅安公司做网站
  • wordpress网站生成app应用电子版简历怎么弄
  • 茂名市网站建设网站制作 成功案例
  • 布吉网站建设价格特产网站设计
  • 网站如何解除绑定域名网站备案怎么备案
  • 怎么仿别人的网站中国龙城室内设计联盟
  • 程序员给女朋友做的网站做公司网站有没有必要
  • 外贸网站多语言视频网站dedecms
  • 单位网站建设程序WordPress的FTP登录凭据
  • 做的网站怎么让百度收录免费网站模板html
  • 怎么做教育类型的网站网站 内容 制作