③ database数据库操作

一 mySQL

1 mySQL 的安装配置

请自行查找相关资料

2 在 NodeJs 中使用 mySQL

2.1 安装 mysql 模块

  npm install mysql

2.2 连接数据库

1. 使用连接对象方式

  var mysql = require('mysql');

  //创建连接对象,并配置参数
  var connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '',
    database: 'edusys'
  });
      
  // 连接数据库
  connection.connect();
      
  // 查询数据库
  connection.query('select * from student', function (error, results, fields) {
      if (error) throw error;
      console.log('The solution is: ', results);
  });
      
  // 关闭连接,释放资源
  connection.end();

2. 使用连接池方式(官方是推荐)

  • 使用连接池,默认会在连接池中创建10个连接对象(connectionLimit),使用完成自动放回连接池,不需要手动关闭
  var mysql = require('mysql');

  //创建连接池
  var pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: '',
    port: 3306,
    database: 'edusys',
    multipleStatements: true
  });

  pool.query('select * from student', function(error, rows) {
    console.log(rows);
  });

3. 封装模块

  // 配置参数
  // ...
  module.exports = {
    query: sql => {
      return new Promise((resolve,reject) => {
        pool.query(sql, function(err, rows) {
          if(err) return reject(err);
          resolve(rows);
        });
      })
    }
  }

2.3 数据库操作

1. query(sql,callback)

  • insert into <表名> [(<字段名1>[,..<字段名n > ])] values ( 值1 )[, (值n )];
  insert into MyGuests (firstname, lastname, email) values ('John', 'Doe', 'john@example.com');
  • delete from <表名> where <条件>
  --删除MyGuests表中id为1的数据
  DELETE FROM MyGuests where id=1;

  --删除所有数据
  DELETE FROM MyGuests
  • update <表名> set 字段=新值, … where 条件
 update MyGuests set name='Mary' where id=1;
  • select <字段1, 字段2, ...> from <表名> where <表达式>
  --查看表 MyGuests 中所有数据
  select * from MyGuests;

  --查看表 MyGuests 中前10行数据:
  select * from MyGuests order by id limit 0,10;

2. 条件控制语句: WHERE

  • SELECT * FROM tb_name WHERE id=3;

  • 相关条件控制符:

    • =、>、<、<>、IN(1,2,3......)、BETWEEN a AND b

    • AND、OR、NOT

    • LIKE 用法中

      • % 匹配任意

      • _ 匹配一个字符(可以是汉字)

    • LIMIT idx, qty:数量控制

      • SELECT * FROM goods LIMIT 2,5
    • IS NULL 空值检测

    • 排序 ORDER BY

      • asc 升序(默认)

      • desc 降序

二 MongoDB

  • MongoDB 是一个基于分布式文件存储的数据库,由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 jsonbson 格式

  • bson: 是一种类 json 的一种二进制形式的存储格式,简称 Binary JSON

1 下载与安装

2 配置数据库(V3.6)

  1. 配置环境变量

  2. 安装 mongodb 默认自动配置环境变量,方便在命令行中使用相关命令

  3. 配置数据库保存目录

  • mongod.exe --dbpath D:\data\mongodb\db
  1. 启动成功后,可通过 http://127.0.0.1:27017 访问,但关闭后每次访问都必须重复以上操作

配置为 windows 服务,实现开机自动启动 Mongodb

  1. 创建 mongod.cfg 文件,并写入以下内容
 systemLog:
  destination: file
  path: d:\data\mongodb\log\mongod.log
 storage:
  dbPath: d:\data\mongodb\db
  1. 执行以下命令,安装 windows 服务
  mongod.exe --config c:\mongodb\mongod.cfg --service --serviceName MongoDB --install

PS: MongoDB4.0 后默认安装 windows 服务

3 命令行操作

3.1 连接数据库

  • mongo 连接到数据库并进行操作

  • mongod 显示数据库信息

3.2 常用命令(命令行)

  • 输入 help 可以看到基本操作命令

1. 数据库操作(Database)

  • 查看所有数据库: show dbs

  • 创建/切换数据库: use DBNAME

    • 如果数据库不存在,则创建数据库,否则切换数据库
  • 查看当前使用的数据库: db

  • 显示当前db状态: db.stats()

  • 查看当前db的链接地址: db.getMongo()

  • 删除当前使用数据库: db.dropDatabase()

2. 集合操作(Collection)

use DBNAME 切换到当前数据库后,可以进行集合与文档的操作

  • 创建集合:

    • db.createCollection(NAME)

    PS:只有创建了集合,数据库才能真正成功创建

  • 查询所有集合:

    • show collections
  • 删除集合:

    • db.NAME.drop();

3. 文档操作(Document)

文档就是数据,这里的所有操作都是针对数据,格式:db.NAME.方法()

  • 增(插入数据):

    • insertOne(document)

    • inertMany([document,...])

  db.user.insertOne({ username: 'laoluo' });
  db.user.insertMany([{ "username": 'laoluo' }, { 'username': 'jingjing' }]);

当你插入一些文档时,MongoDB 会自动创建集合 NAME

  • 删(删除数据)

    • deleteOne(query)

    • deleteMany(query)

  • 改(更新数据)

    • updateOne(query,newData)

    • updateMany(query,newData)

  //更新指定字段
  //查找name属性为tiantian的数据,并更新age属性为27
  db.user.updateOne({name:'tiantian'},{$set:{age:27}})

  // 找到所有年龄大于18的数据,并设置description为成年
  db.user.updateMany( { age: { $gt : 18 } } , { $set : { description : "成年"} } );
  • 查(查询数据):

    • 查询所有:db.NAME.find()

    • 按条件查询(支持多条件):db.NAME.find(query)

    • 查询第一条(只获取第一条):db.NAME.findOne(query)

    find() 方法一般后一般使用 toArray() 方法把结果转成数组

      //查询user下所有数据
      db.user.find().toArray((err,result)=>{});
      
      // 查询user下年龄为38的
      db.user.find({age:38}).toArray()
    
      // 查询user下年龄大于38的
      db.user.find({age:{$gt:38}}).toArray()
    
      //利用pretty()方法格式化结果
      db.user.find().toArray().pretty();
    

3.3 查询条件

1. 比较查询

  • 大于:$gt

  • 小于:$lt

  • 大于等于:$gte

  • 小于等于:$lte

  • 非等于:$ne

2. 包含/不包含:$in/$nin

  db.goods.find({ id: { $in: [10,18,26,13] }})

3. 或:$or

  db.user.find({ $or: [{ name: 'laoxie' }, { name: 'jingjing' }]})
  db.user.find({ $or: [{ age: { $gt: 18 }}, { description:"成年" }]})

4. 匹配所有:$all

5. 判断文档属性是否存在:$exists

  db.user.find({ password: { $exists: true }})   //查找属性password存在的用户
  db.user.find({ password: { $exists: false }})  //查找属性password不存在的数据
  db.user.find({ age: { $in: [null], $exists: true }}) //查找age属性存在但值为null的数据

6. 正则表达式

  db.user.find({ "name": /jack/i });//查找name属性包含jack的数据(不区分大小写)

3.4 筛选

1. 限制数量:db.表名.find().limit(数量)

2. 跳过指定数量:db.表名.find().skip(数量)

3. 排序:sort({ key: 1 })

  • 1 : 升序

  • -1 : 降序

三个放在一起使用的时候,执行的顺序是先 sort(), 然后是 skip(),最后是 limit()

  // 把类型为字String的价格按数字排序
  db.goods.find().collation({ numericOrdering: true }).sort({ price: 1 })

  // 根据某个值修改文档中的另一个值(把price的值改成sale_price的8折)
  db.goods.find({ price: 0 }).forEach(item => {                
    db.goods.updateOne({ _id: item._id }, { $set: { price: item.sale_price*0.8 }})
  })

4 NodeJS 中使用 mongodb

4.1 安装 mongodb 模块

  npm install mongodb --save

4.2 数据库操作

  • 连接 mongoDB
  const mongodb = require('mongodb');
  const MongoClient = mongodb.MongoClient;

  //连接mongoDB
  MongoClient.connect("mongodb://localhost:27017", function(err, client) {
    if(err) throw err;
      // 连接数据库,无则自动创建
      let db = client.db('laoxie');
  });

4.3 集合操作

  • 创建集合:createCollection()

    • 格式:db.createCollection(name, options)
  • 使用集合:collection()

    • db.collection(name)
  • 删除集合:drop()

    • 格式:db.COLLECTION_NAME.drop(callback)
  db.createCollection('site', function (err, res) {
    if (err) throw err;
    console.log("创建集合!");
    db.close();
  });

2.4.4 文档操作

同上命令行操作 <文档操作(Document)>

5 MongoDB 的导入导出

5.1 导出 mongoexport

把一个 collection 导出成 JSON 格式或 CSV 格式的文件。可以通过参数指定导出的数据项,也可以根据指定的条件导出数据

  • 格式:mongoexport -d dbname -c collectionname -o file --type json/csv -f field

  • 参数说明:

    • -d :数据库名

    • -c :collection名

    • -o :输出的文件名

    • --type : 输出的格式,默认为json

    • -f :输出的字段,如果-type为csv,则需要加上-f "字段名"

  mongoexport -d mytest -c goods -o D:/data/goods.json --type json -f  "_id,name,price,img_url,add_time"

5.2 导入 mongoimport

  • 格式:mongoimport -d dbname -c collectionname --file filename --headerline --type json/csv -f field

  • 参数说明:

    • -d :数据库名

    • -c :collection名

    • --type :导入的格式默认json

    • -f :导入的字段名

    • --headerline :如果导入的格式是csv,则可以使用第一行的标题作为导入的字段

    • --file :要导入的文件

  mongoimport -d mongotest -c goods --file D:/data/goods.json --type json

6 MongoDB 备份与恢复

6.1 备份

  • 格式:mongodump -h dbhost -d dbname -o dbdirectory

  • 参数说明:

    • -h: MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017

    • -d: 需要备份的数据库实例,例如:test

    • -o: 备份的数据存放位置,例如:D:/mongodump/

    当然该目录需要提前建立,这个目录里面存放该数据库实例的备份数据。

  mongodump -h 127.0.0.1:27017 -d mytest -o D:/mongodump/

6.2 恢复

  • 格式:mongorestore -h dbhost -d dbname --dir dbdirectory

  • 参数或名:

    • -h: MongoDB所在服务器地址

    • -d: 需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2

    • --dir: 备份数据所在位置,例如:D:/mongodump/

    • --drop: 恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用!

  mongorestore -h 192.168.17.129:27017 -d mytest --dir D:/mongodump/

三 service 开发

1 mongodb 安装完配置 path

  1. 【我的电脑】右击

  2. 【高级系统设置】

  3. 【环境变量(N)】

  4. 【系统变量(S)】

  5. 【path】

  6. 【编辑(I)】

  7. 添加mongodb所在路径 D:\mongodb\bin D:\mongodb

  8. 【确定】

1.2 在 MongoDB 安装目录下文件

  • data 文件夹

  • log 文件夹

1.3 在 MongoDB 安装目录下新建 mongo.config 配置文件并配置以下内容

dbpath=D:\mongodb\data
logpath=D:\mongodb\log\mongo.log

1.4 跑起配置文件

D:\mongodb\bin\mongod.exe --config D:\mongodb\mongo.config

2 NodeJS 中使用 mongodb

2.1 搭建服务器

  • server.js
// 引入第三方模块
const express = require('express');

// 利用express创建一个服务器
const app = express();
const { PORT } = require('./config.json');

// 引入路由总中间件
const allRouter = require('./routers');

// 搭建静态资源服务器
app.use(express.static('/'));

// 使用路由总中间件
app.use(allRouter);

// 监听服务器开启
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
})
  • routers/index.js
const express = require('express');
let Router = express.Router();

let classifyRouter = require('./classify');

// 跨域解决方案CORS
Router.use((req,res,next) => {
    let currentOrigin = req.get('Origin');
    let allowOrigin = ['http://localhost:8080', 'http://localhost:8081', 'http://localhost:8082', 'http://localhost:8083'];
    if(allowOrigin.includes(currentOrigin)) {
        res.set({
            'Access-Control-Allow-Origin': currentOrigin,
            'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTION',
            'Access-Control-Allow-HEADERS': 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With'
        })
    }
    // 跨域请求CORS中的预请求
    if(req.method == 'OPTIONS') {
        res.sendStatus(200); // 让option请求快速返回
    } else {
        next();
    }
})

// 格式化请求体中的参数
Router.use(express.json(), express.urlencoded({extended:false}));

// 关联中间件
Router.use('/classify', classifyRouter);

module.exports = Router;

2.2 数据库连接

1. 连接 mongodb

const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;

//连接mongoDB
MongoClient.connect('mongodb://localhost:27017',(err,client) => {
  if(error) throw error;

  //连接数据库,无则自动创建
  let db = client.db('pleaseAnswer');
})

2. connect() + close()

const {MongoClient, ObjectId} = require('mongodb');

const {dbUrl, dbName} = require('../config.json');

async function connect() {
  const client = await MongoClient.connect(dbUrl, {
    useUnifiedTopology: true
  })
  const db = client.db(dbName);
  return {
    client,
    db
  }
}
  • 在自定义方法中,调用 connect() 方法连接数据池,使用 client.close() 方法关闭数据池

四 插件开发-数据自动填充

1 工具说明

  1. node
  2. anyproxy
  3. mongodb

1.1 node

程序的运行环境

1.2 anyproxy

anyproxy 是一个客户端代理服务器【正向代理】,浏览器通过设置全局代理后,所有的 http 服务请求均要通过它来进行代理请求

1.2.1 安装

  1. 执行命令全局安装 > npm i anyproxy -g

  2. 执行命令检查是否正确安装 > anyproxy

1.2.2 代理设置

  1. 进入【控制面板】

  2. 找到【Internet选项】

  3. 点击【连接】选项

  4. 点击【局域网设置】会弹出局域网(LAN)设置窗口

  5. 找到代理服务器

  6. 选中【为LAN使用代理服务器】,在地址输入:127.0.0.1 端口:8001

  7. 确定,保存代理

1.2.3 启动

  1. 启动里需带规则文件,在本地搭建的服务器存放符合 anyproxy 编写规范的"缓存修改规则js文件 proxy_rule.js"

  2. 执行命令 > anyproxy --rule proxy_rule.js

Http proxy started on port 8001
Web interface started on port 8002

  1. 浏览器打开 http://127.0.0.1:8002 显示管理页面说明启用成功

1.3 mongodb

mongodb 是对象数据库,用来存储补充录入的数据

2 数据处理

2.1 数据处理服务器

使用 nodejs 搭建本地服务器--用于读取本地服务器,并配合写入页面的脚本文件做字段数据填充

2.2 数据处理后台

数据处理后台用来把已经处理好的 excel 数据导入 mongodb 中
运行环境为 node

  1. 进入 server 目录位置

  2. 执行命令启动本地服务:> npm start

五 实操

1 搭建本地服务器

  • server.js
  // 001 引入第三方模块
  const express = require('express');

  // 002 利用express创建一个服务器
  const app = express();
  // 003 搭建静态资源服务器
  app.use(express.static('/'))

  const {PORT} = require('./config.json');

  // 004 引入路由总中间件
  const allRouter = require('./routers');
  // 005 使用路由总中间件
  app.use(allRouter);

  // 006 监听服务器开启
  app.listen(PORT,() => {
    console.log(`Server is running on port ${PORT}`);
  })

2 配置请求路径

  • router/index.js
  const express = require('express');
  let Router = express.Router();

  let loginRouter = require('./login');
  let goodsRouter = require('./goods');
  let userRouter = require('./user');
  let regRouter = require('./reg');
  
  Router.use(express.json(), express.urlencoded({extended: true}));
  Router.use('./login', loginRouter);
  Router.use('./goods', goodsRouter);
  Router.use('./user', userRouter);
  Router.use('./reg', regRouter);
  
  module.exports = Router;

3 统一前后端的数据格式

  • utils/index.js
  // 解构默认值
  function formatData({status = 1, data = [], msg = 'success'} = {}) {
    if(status === 0) {
      msg = "fail";
    } 
    return {
      status,
      data,
      msg
    }
  }
  module.exports = {
    formatData
  }

4 连接数据库

4.1 src/db/mongodb.js -- 初版

  const { MongoClient } = require('mongodb');
  
  const { dbUrl, dbName } = require('../config.json');
  // 连接MongoDB数据库
  async function connect() {
    const client = await MongoClient.connect(dbUrl);
    const db = client.db(dbName);
    return {
      client,
      db
    }
  }
  
  /**
   * 增 -- 注册
   * @param {String} colName 集合名称
   * @param {Array|Object} data 插入的数据
   * return {Object} 返回写入的结果
   */
   async function create(coleName, data) {
    const { db, client } = await connect();
    let collection = db.collection(colName);
     
    // 判断传入的Data是否为数组
    if(!Array.isArray(data)) {
      data = [data]
    }
    let result = await collection.insertMany(data);
    client.close();
    return result;
   }
   
  /**
   * 删除
   * @param {String} colName 集合名称
   * @param {Object} query 查询条件
  */
  async function remove(colName, query) {
    const { db, client } = await connect();
    let collection = db.collection(colName);
    let result = await collection.deleteMany(query);
    client.close();
    return result;
  }
  
  /**
   * 更新
   * @param {String} colName 集合名称
   * @param {Object} query 查询条件
   * @param {Object} data 更新字段数据
  */
  async function update(colName, query, data) {
    const { db, client } = await connect();
    let collection = db.collection(colName);
    let result = await collection.updateMany(query, { $set: data });
    client.close();
    return result;
  }

  /**
   * 查
   * @param {String} colName 集合名称
   * @param {Object} query 查询条件
  */
  async function find(colName, query) {
    const { db, client } = await connect();
    let collection = db.collection(colName);
    // promise对象--.toArray()才能拿到结果
    let result = await collection.find(query).toArray();
    client.close();
    return result;
  }
  
  // 模块开发思想--导出模块
  module.exports = {
    create,
    remove,
    update,
    find
  }

4.2 增强版查找 --查询条件

  /**
   * 查
   * @param {String} colName 集合名称
   * @param {Object} query 查询条件
  */
  async function find(colName, query) {
    const {db, client} = await connect();
    let collection = db.collection(colName);
    // 处理id查询 {_id: 'xxx'} -> {_id: ObjectId('xxx')}
    if(query._id && typeof query._id === 'string') {
      query._id = Object(query._id);
    }
    // promise对象--.toArray()才能拿到结果
    let result = await collection.find(query).toArray();
    client.close();
    return result;
  }

4.3 增强版查找--过滤

  /**
   * 查
   * @param {String} colName 集合名称
   * @param {Object} query 查询条件
   * @param   fields 过滤字段
  */
  async function find(colName, query = {}, { fields } = {}) {
    const {db, client} = await connect();
    let collection = db.collection(colName);
    if(query._id && typeof query._id === 'string') {
      query._id = Object(query._id);
    }
    // promise对象--.toArray()才能拿到结果
    let result = await collection.find(query, {fields}).toArray();
    client.close();
    return result;
  }

5 请求路径模块--方法编写

user.js

const express = require('express');
const Router = express.Router();
const { find, remove, update } = require('../db/mongodb');
const { formatData } = require('../utils');
const colName = 'user';

// 查询所有用户
Router.get('/', async (req, res) => {
  // 查询数据库
  let result = await find(colName); 
  res.send(formatData({ data: result }))
})
// 查询单个用户信息
Router.get('/:id', async (req, res) => {
  let { id } = req.params;
  let result = await find(colName, {_id: id}, {fields: {password: false, _id: false}});
  res.send(formatData({ data: result }));
})
// 删除用户
Router.delete('/:id', async (req, res) => {
  let { id } = req.params;
  let result = await remove(colName, { _id: id });
  if(result.deleteCount > 0) {
    res.send(formatData());
  } else {
    res.send(formateData({ status: 0 }));
  }
})
// 修改用户信息
Router.patch('/:id', async (req, res) => {
  let { id } = req.params;
  let { password, age, gender } = req.body;
  let result = await update(colName, { _id: id }, { password, age, gender });
  if(result.modifiedCound > 0) {
    res.send(formatData());
  } else {
    res.send(formateData({status: 0}));
  }
})

module.exports = Router;

6 实现分页

6.1 mongodb.js

   /**
   * 查
   * @param {String} colName 集合名称
   * @param {Object} query 查询条件
   * @param   dptions 可选参数
  */
  async function find(colName, query = {}, options = {}) {
    // fields: 用于过滤某些字段
    let { fields: attr, skip, limit, sort } = options;
    const {db, client} = await connect();
    
    let collection = db.collection(colName);
    
    if(query._id && typeof query._id === 'string') {
      query._id = Object(query._id);
    }
    // promise对象--.toArray()才能拿到结果
    let result = await collection.find(query, { attr });
    
    // 跳过数量
    if(skip) {
      result = result.skip(skip);
    }
    // 限制数量
    if(limit) {
      result = result.limit(limit * 1);
    }
    // 排序 1-->升序   -1-->降序
    if(sort) {
      let arr = sort.split(',')
      let key = arr[0];
      let value = arr[1] ? arr[1] * 1 : -1;
      
      result = result.sort({
        [key]: value
      })
    }
    client.close();
    return result;
  }

6.2 goods.js

  // 编写接口数据
  const colName = 'goods';
  // 查询所有商品
  Router.get('/', async (req, res) => {
    let { page = 1, size = 10, sort } = req.query;
    let index = (page - 1) * size;
    let data = await mongodb.find(colName, {}, { skip: index, limit: size, sort });
    res.send(formatData({ data }));
  })
posted on 2021-07-12 10:39  pleaseAnswer  阅读(54)  评论(0编辑  收藏  举报