NodeJS里的MySQL操作(原生操作+sequelize框架操作)

256 阅读5分钟

连接数据库

    1. cnpm i mysql -S
    1. 引入mysql模块
    1. 创建mysql链接
    • mysql.createConnection({})
    1. 链接数据库
    • connect()
    1. 操作数据库
    • conn.query('操作语句',[参数],(错误,结果,fields)=>())
    1. 断开连接
    • end()

代码例子

const mysql = require('mysql')

//创建连接对象
const conn = mysql.createConnection({
  host:'localhost',
  user:'root',
  password:'',
  database:'db2'
});
conn.connect(err=>{
  if(err) console.log(err);
  console.log('连接成功');
})

//增删改查
const CREATE_SQL = `CREATE TABLE IF NOT EXISTS test(id INT NOT NULL PRIMARY KEY auto_increment,name VARCHAR(20))`;
const SELECT_SQL = `SELECT * FROM test WHERE id=?`;
//参数用?作为占位符

const INSERT_SQL = `INSERT INTO test(name) VALUES(?),(?)`;
const DELETE_SQL = `DELETE FROM test WHERE id=?`;
conn.query(CREATE_SQL,(err,results,fields)=>{
  if(err) throw err;
  conn.query(INSERT_SQL,['qlq','yyy'],(err,results,fields)=>{
    if(err) throw err;
    conn.query(SELECT_SQL,[1],(err,results,fields)=>{
      if(err) throw err;

      console.log(results[0].name);
      //断开连接
      conn.end();//如果query语句有嵌套 end需要在最后一个query断开链接
    })
  })
})
/*conn.query(DELETE_SQL,[2],(err,results,fields)=>{
  if(err) throw err;
  console.log(results);
  conn.end();
})*/

ps:如果query语句有嵌套 end需要在最后一个query断开链接

这样的方式会形成回调地狱 可以用async/await的方式

用async/await方式来操作数据库

1.async/await一个操作数据库的函数 并且创建一个mysql模块来操作数据库

const CREATE_SQL = `CREATE TABLE IF NOT EXISTS test(id INT NOT NULL PRIMARY KEY auto_increment,name VARCHAR(20))`;
const SELECT_SQL = `SELECT * FROM test WHERE id=?`;
const INSERT_SQL = `INSERT INTO test(name) VALUES(?),(?)`;
const DELETE_SQL = `DELETE FROM test WHERE id=?`;

const db = require('./db1/mysql')
async function asyncQuery(){
  try {
    // const res1 = await db.query(CREATE_SQL);
    const res2 = await db.query(INSERT_SQL,['张三','李四']);
    console.log(res2);
  } catch (error) {
    console.log(error);
  }
}
asyncQuery();

2.抛出的对象有query方法,并且是返回Promise(在('./db1/mysql')模块里)

2.1 在Promise做数据库操作 需要引入mysql

2.2 创建数据库连接 这里可以用mysqlConfig模块来引入数据库的接口数据

2.3 链接数据库

2.4 mysql.format(操作数据库语句,参数)可以自动将参数填到操作数据库语句的占位符里 得到一条完整的操作数据库语句

2.5 conn.query()操作数据库 返回对应的reject、resolve

./db1/mysql的完整代码

const mysql = require('mysql')
const config = require('./mysqlConfig')
module.exports = {
  query:function(sql,parmars){
    return new Promise((resolve,reject)=>{
      const conn = mysql.createConnection(config);
      conn.connect(err => {
        if (err) console.log(err);
        console.log('连接成功');
      })
      sql = mysql.format(sql,parmars);
      console.log(sql);
      //查询
      conn.query(sql,(err,results,fields)=>{
        if(err) throw reject(err);
        resolve(results);
        conn.end();
      })
    })
  }
}

附上'./mysqlConfig'模块的代码

module.exports = {
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'db2'
}

使用sequelize框架操作数据库

Sequelize 是一个基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, MariaDB, SQLite 以及 Microsoft SQL Server. 它具有强大的事务支持, 关联关系, 预读和延迟加载,读取复制等功能.

1. 下载Sequelize

cnpm i sequelize -S

2. 链接到数据库

2.1 引入模块,创建链接

new Sequelize('数据库名','用户名','密码',{host:'host名',dialect:'数据库类型'}

const { Sequelize, DataTypes } = require('sequelize')

const sequelize = new Sequelize('db2','root','',{
  host:'localhost',
  dialect: 'mysql'
});

3. 定义模型

sequelize是先创建一个表的模型,然后将模型映射到数据库里
例子:做一个书的数据库

sequelize.define('要创建的表名',{要创建的属性},{其他模型参数})

数据类型的用法参考 github.com/demopark/se…

const Books = sequelize.define('books',{
  id:{
    type:DataTypes.INTEGER, //数据类型
    primaryKey:true,  //主键
    autoIncrement: true, //自增长
    comment: '自增长id' //注释
  },
  name:{
    type:DataTypes.STRING(20),
    allowNull:false //不允许为空
  },
  price:{
    type:DataTypes.FLOAT,
    allowNull: false //不允许为空
  },
  count:{
    type:DataTypes.INTEGER,
    defaultValue: 0
  }
},{
  freezeTableName: true, //表名冻结  Model对应的表名将于model相同
  timestamps: false //是否创建createAt和updateAt 默认true创建
})

4. 迁移模型映射到数据库

User.sync();

  • User.sync(); 如果表不存在,则创建该表(如果已经存在,则不执行任何操作)
  • User.sync({ force: true }) - 将创建表,如果表已经存在,则将其首先删除
  • User.sync({ alter: true }) - 这将检查数据库中表的当前状态(它具有哪些列,它们的数据类型等),然后在表中进行必要的更改以使其与模型匹配. 这里是Books.sync();

5.插入数据

User.create({}) 插入一条数据

User.bulkCreate([{}]) 插入多条数据

ps: 要记得加return
Books.sync({alter:true}).then(()=>{

  // 插入一条数据用create
  /*return Books.create({
    name:'你不知道的javascript',
    price:12.9
  })*/

  // 插入多条数据bulkCreate
  return Books.bulkCreate([
    {
      name:'高级程序设计javascript',
      price: 99,
      count: 10
    },
    {
      name: 'Vue实战教学',
      price: 199,
      count: 10
    }, {
      name: 'React实战教学',
      price: 299,
      count: 10
    }, {
      name: 'Nodejs实战教学',
      price: 399,
      count: 10
    },
  ])
})

6. 删除数据

User.destory({删除条件})

Books.destroy({
  where:{
    id:1
  }
})

7. 更改数据

User.update({要更改的属性及值},{更改条件})

Books.update({price:50},{where:{id:1}});//将id为1的那条数据的price改成50

8. 查找数据

查找多个数据Books.findAll( { 查找条件或者是数据如何返回} )

  • 如果要查找价格大于100的值 需要用到操作符 where
  • order:['控制返回数据是依据哪个属性','倒序还是正序']
  • limit: 返回数字对应的几条数据
  • offset: 跳过数字对应的几条数据
  • attributes: ['返回数据的属性']
    • attributes:{ exclude:['返回除了这些数据属性的数据属性']}
const { Op } = require("sequelize");
Books.findAll({
  where:{
    price:{
      [Op.gt] : 100
    }
  },
  order:[
    ['id','DESC'], //根据id倒序 
  ],
  limit:2 ,//返回几条数据
  // attributes:['name','price'] //返回数据的属性
  attributes:{
    exclude:['id','count'] //不包含哪些属性
  },
  offset: 5 //跳过几个实例
}).then(books=>{
  // console.log(JSON.stringify(books,null,4));
})

查找单个数据User.findOne({查找条件})

9. 聚合函数

聚合函数的用法多样 详情可参考 github.com/demopark/se…

Books.count('id').then(count=>console.log(count));//获取id的个数
Books.max('price').then(maxPrice=>console.log(maxPrice));//获取最大价格

10. 实例扩展&模型扩展

实例扩展

Books.prototype

定义实例上的方法

Books.prototype.totalPrice = function(count){
  return this.price * count;
}

 Books.findAll().then((books)=>{
   console.log(books[0].totalPrice(50));
 })

打印的结果是该条数据的价格 * 50

模型扩展

Books.

定义模型上的方法

Books.classify = function(name){
  const qingHuabooks = ['Nodejs实战教学', '高级程序设计javascript'];
  return qingHuabooks.includes(name) ? '清华出版社' : '其他出版社'
}
const arr = ['Nodejs实战教学', 'React实战教学'];
arr.forEach(n=>console.log(Books.classify(n)));

打印出来的结果是 '清华出版社' '其他出版社'