一 node-mysql
/* 1.如何在Node程序中操作MySQL数据库? 我们都知道操作MySQL数据库就是连接MySQL服务器, 给MySQL服务器发送指令 在NodeJS中我们可以借助第三方库来连接MySQL服务器, 给MySQL服务器发送指令 1.1 mysql驱动库 https://www.npmjs.com/package/mysql npm install mysql 1.2 mysql2驱动库 https://www.npmjs.com/package/mysql2 npm install mysql 2.由于node第三方库还不支持最新的mysql加密, 所以我们需要修改为旧版本加密方式 2.1、更改加密方式: mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; 2.2、更改密码 mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root'; * */ // 1.导入MySQL第三方驱动库 const mysql = require('mysql2'); // 2.进行连接配置 var connection = mysql.createConnection({ host : '127.0.0.1', // MySQL服务器地址 port : 3306, user : 'root', // MySQL服务用户名 password : 'root', // MySQL服务密码 database : 'day17' // 需要操作的那个数据库的名称 }); // 3.连接MySQL服务器 connection.connect(); // 4.给MySQL服务器发送指令 connection.query('select * from person where id=1', (error, results, fields) => { if (error){ console.log(error); return } console.log(results); }); // 5.释放连接 connection.end();
二 orm-Sequelize
/* 1.什么是Sequelize? Sequelize是一个基于Promise的NodeJS ORM模块 2.什么是ORM? ORM(Object-Relational-Mapping)是对象关系映射 对象关系映射可以把JS中的类和对象, 和数据库中的表和数据进行关系映射 映射之后我们就可以直接通过类和对象来操作数据表和数据了, 就不用编写SQL语句了 ORM有效的解决了直接在NodeJS中编写SQL不够直观, 不够高效, 容易出错等问题 3.如何映射? 在Sequelize中JS中的一个类(一个模型)就对应数据库中的一张表 在Sequelize中JS中的一个对象就对应表中的一条数据(一条记录) 在Sequelize中JS中的一个对象的属性就对应一条数据的一个字段 |---------------------------| | id | name | age | | 1 | zs | 18 | | 2 | ls | 19 | |---------------------------| // 1.创建一张表 cosnt 模型名称 = Sequelize.define('表名', { id: int, name: varchar(255), age: int }) // 2.创建一条记录 let zs = 模型名称.build({ id: 1, name: zs, age: 18 }) zs.id // 3.操作表和数据 只要是通过Sequelize定义的模型(类), 那么Sequelize就会自动给这个模型添加很多操作表和数据的方法 以后我们就可以直接通过模型操作表, 通过模型创建出来的对象操作数据 * */
三 Sequelize-连接数据库
/* 1.Sequelize基本使用 https://sequelize.org/ */ /* 2.什么是数据库连接池? 默认情况下有一个人要使用数据库, 那么就必须创建一个连接 默认情况下有一个人不用数据库了, 为了不占用资源, 那么就必须销毁一个连接 但是频繁的创建和销毁连接是非常消耗服务器性能的, 所以为了提升服务器性能就有了连接池 数据库连接池是负责分配、管理和释放数据库连接, 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个 * */ // 1.导入Sequelize const Sequelize = require('sequelize'); // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('demo', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.测试配置是否正确 sequelize.authenticate() .then(()=>{ console.log('ok'); }) .catch((err)=>{ console.log(err); });
四 创建表
// 1.导入Sequelize const Sequelize = require('sequelize'); // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('demo', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); /* 1.字段说明常用属性 type: 字段类型 primaryKey: 是否是主键 autoIncrement: 是否自动增长 allowNull: 是否允许为空 unique: 是否必须唯一 defaultValue: 默认值 * */ /* 2.额外配置常用属性 timestamps: 是否自动添加createdAt/updateAt字段 freezeTableName: 是否禁止自动将表名修改为复用 tableName: 是否自定义表名 indexes: [ // 指定索引 { name: '', // 索引名称 fields: [''], // 索引字段名称 } ] * */ /* 第一个参数: 用于指定表的名称 第二个参数: 用于指定表中有哪些字段 第三个参数: 用于配置表的一些额外信息 * */ /* 注意点: 1.sequelize在根据模型创建表的时候, 会自动将我们指定的表的名称变成复数 2.sequelize在根据模型创建表的时候, 会自动增加两个字段 createAt/updateAt * */ let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false, // 不需要自动创建createAt/updateAt这两个字段 indexes: [ // 指定索引 { name: 'idx_age', // 索引名称 fields: ['age'], // 索引字段名称 } ] }); // 注意点: 默认定义好一个模型之后并不会自动创建对应的表 // 我们需要通过调用连接对象的sync方法来执行同步 // 只有同步之后才会自动根据模型创建对应的表 sequelize.sync();
五 创建数据
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('day17', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false, // 不需要自动创建createAt/updateAt这两个字段 indexes: [ // 指定索引 { name: 'idx_age', // 索引名称 fields: ['age'], // 索引字段名称 } ] }); sequelize.sync(); // 4.创建一条数据(一条记录) // let u = new User(); // u.name = 'zs'; // u.age = 33; // u.gender = '男'; /* 注意点: 创建好一条数据之后, 默认情况下不会立即同步到表中 如果想立即同步到表中, 那么必须调用对象的save方法 注意点: 本质上让MySQL执行SQL语句是一个异步的操作, 所以在sequelize中大部分的方法都是异步方法 注意点: 通过模型类创建出来的对象中有一个dataValues的属性, 这个属性就保存了一条记录所有的信息 调用save方法保存完数据之后, sequelize会自动更新对应的对象, 将最新的数据更新进去 * */ // console.log('保存之前:', u); // await u.save(); // console.log('保存之后:', u); // 下面这段代码 = 创建对象 + save(); let u = await User.create({ name: 'ww', age: 18, gender: '女' }); console.log('保存之后:', u); console.log(u.dataValues); })();
六 操作数据
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('day17', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false, // 不需要自动创建createAt/updateAt这两个字段 indexes: [ // 指定索引 { name: 'idx_age', // 索引名称 fields: ['age'], // 索引字段名称 } ] }); // sequelize.sync(); // 4.创建一条数据(一条记录) // let u = new User(); // u.name = 'zs'; // u.age = 33; // u.gender = '男'; // await u.save(); // 下面这段代码 = 创建对象 + save(); // let u = await User.create({ // name: 'ls', // age: 18, // gender: '男' // }); //console.log(u.dataValues); // 5.查询数据 // let u = await User.findByPk(2); // console.log(u); // // 6.修改数据 // u.name = 'it666'; // await u.save(); User.update({ name: 'zs' },{ where: { id: 2 } }) // 7.删除数据 // await u.destroy(); User.destroy({ where: { id: 3 } }); })();
七 条件查询
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('day17', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false, // 不需要自动创建createAt/updateAt这两个字段 indexes: [ // 指定索引 { name: 'idx_age', // 索引名称 fields: ['age'], // 索引字段名称 } ] }); // sequelize.sync(); // 4.查询 // 4.1查询多条数据 // let us = await User.findAll(); // console.log(us); // console.log(us.map(u => u.dataValues)); //4.2查询指定列数据 // let us = await User.findAll({ // attributes: ['name', 'age'] // }); // console.log(us.map(u => u.dataValues)); // 4.3条件查询 let us = await User.findAll({ where: { // id: 1 // age: { // [Sequelize.Op.gte] : 33 // }, // id: 7 [Sequelize.Op.or]: { age: 33, id: 7 } } }); console.log(us.map(u => u.dataValues)); })();
八 分页和排序
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('day17', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false, // 不需要自动创建createAt/updateAt这两个字段 indexes: [ // 指定索引 { name: 'idx_age', // 索引名称 fields: ['age'], // 索引字段名称 } ] }); // sequelize.sync(); // 4.分页 // let us = await User.findAll({ // offset: 2 // 跳过多少条数据 // }); // console.log(us.map(u => u.dataValues)); // let us = await User.findAll({ // limit: 2 // 取多少条数据 // }); // console.log(us.map(u => u.dataValues)); // let us = await User.findAll({ // offset: 2, // 跳过多少条数据 // limit: 2 // 取多少条数据 // }); // console.log(us.map(u => u.dataValues)); // 5.排序 let us = await User.findAll({ order: [ // ['id', 'desc'] ['age', 'desc'], ['id', 'desc'] ] }); console.log(us.map(u => u.dataValues)); })();
九 关联查询一(一对一)
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('day17', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); let Book = sequelize.define('book', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, price: { type: Sequelize.DOUBLE, defaultValue: 66 }, uId: { type: Sequelize.INTEGER, allowNull: false } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); //sequelize.sync(); // 4.建立查询关系 /* 注意点: 只要建立了人和书的关系, 那么在查询人的时候, 就可以把拥有的那本书也查询出来 只要建立了书和人的关系, 那么在查询书的时候, 就可以把书属于哪个人也查询出来 如果没有建立相关的关系, 那么就不能查询出相关的内容 * */ User.hasOne(Book, { // hasOne 谁拥有一个谁/ 一个人拥有一本书 foreignKey: 'uId', sourceKey: 'id' }); Book.belongsTo(User, { // belongsTo 谁属于一个谁 / 一本书属于一个人 foreignKey: 'uId', sourceKey: 'id' }); // 5.关联查询 /* let u = await User.findOne({ where: { id: 1 }, // 注意点: 只要建立了表与表之间的关系, 那么在查询人的时候,就可以把这个人拥有的那本书也查询出来了 include: { model: Book } }); console.log(u.dataValues.book.dataValues); */ let b = await Book.findOne({ where: { id: 1 }, // 注意点: 只要建立了表与表之间的关系, 那么在查询书的时候,就可以把这本书属于哪一个人也查询出来了 include: { model: User } }); console.log(b.dataValues.user.dataValues); })();
十 关联查询二(一对多)
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('day17', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); let Book = sequelize.define('book', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, }, price: { type: Sequelize.DOUBLE, defaultValue: 66 }, uId: { type: Sequelize.INTEGER, allowNull: false } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); // sequelize.sync(); // 4.建立查询关系 User.hasMany(Book, { // 一个人拥有多本书 foreignKey: 'uId', sourceKey: 'id' }); Book.belongsTo(User, { // 一本书属于一个人 foreignKey: 'uId', sourceKey: 'id' }) // 5.关联查询 /* let u = await User.findOne({ where: { id: 1 }, include: { model: Book } }); console.log(u.dataValues.books.map(b=>b.dataValues)); */ let b = await Book.findOne({ where: { id: 3 }, include: { model: User } }); console.log(b.dataValues.user.dataValues); })();
十一 建立表关系的另一种方式
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('demo', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let User = sequelize.define('user', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true }, age: { type: Sequelize.TINYINT, defaultValue: 66 }, gender: { type: Sequelize.ENUM(['男', '女', '妖']), defaultValue: '妖' } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); let Book = sequelize.define('book', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, }, price: { type: Sequelize.DOUBLE, defaultValue: 66 }, userId: { type: Sequelize.INTEGER, allowNull: false, references: { model: User, key: 'id' } } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); // 4.建立查询关系 /* User.hasMany(Book, { // 一个人拥有多本书 foreignKey: 'uId', sourceKey: 'id' }); Book.belongsTo(User, { // 一本书属于一个人 foreignKey: 'uId', sourceKey: 'id' }); */ User.hasMany(Book); Book.belongsTo(User); // 注意点: 想要sequelize自动创建外键, 那么就必须在写完上述的两句代码之后再执行同步方法, 才会自动创建对应的外键 sequelize.sync(); // 5.关联查询 /* let u = await User.findOne({ where: { id: 1 }, include: { model: Book } }); console.log(u.dataValues.books.map(b=>b.dataValues)); */ /* let b = await Book.findOne({ where: { id: 3 }, include: { model: User } }); console.log(b.dataValues.user.dataValues); */ })();
十二 关联查询三(多对多)
// 1.导入Sequelize const Sequelize = require('sequelize'); (async ()=>{ // 2.配置连接信息 /* 第一个参数: 要操作的数据库名称 第二个参数: 数据库用户名 第三个参数: 数据库密码 第四个参数: 其它的配置信息 * */ const sequelize = new Sequelize('demo', 'root', 'root', { host: '127.0.0.1', // MySQL服务器地址 port: 3306, // MySQL服务器端口号 // 注意点: Sequelize不仅仅能操作MySQL还能够操作其它类型的数据库 dialect: 'mysql', // 告诉Sequelize当前要操作的数据库类型 pool: { max: 5, // 最多有多少个连接 min: 0, // 最少有多少个连接 idle: 10000, // 当前连接多久没有操作就断开 acquire: 30000, // 多久没有获取到连接就断开 } }); // 3.创建模型 let Student = sequelize.define('student', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); let Teacher = sequelize.define('teacher', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.STRING, // varchar(255) allowNull: false, unique: true } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); let Relation = sequelize.define('relation', { studentId: { type: Sequelize.INTEGER, allowNull: false, references: { model: Student, key: 'id' } }, teacherId: { type: Sequelize.INTEGER, allowNull: false, references: { model: Student, key: 'id' } } }, { freezeTableName: true, // 告诉sequelize不需要自动将表名变成复数 // tableName: 'student', // 自定义表名 timestamps: false // 不需要自动创建createAt/updateAt这两个字段 }); // 4.建立查询关系 Student.belongsToMany(Teacher, { // 一个学生属于多个老师 through: Relation }); Teacher.belongsToMany(Student, { // 一个老师属于多个学生 through: Relation }); sequelize.sync(); // 5.关联查询 /* let s = await Student.findOne({ where: { id: 1 }, include: { model: Teacher } }); console.log(s.dataValues.teachers.map(t=>t.dataValues)); */ let t = await Teacher.findOne({ where: { id: 1 }, include: { model: Student } }); console.log(t); })();