安装
Object Relational Mapping 对象关系映射 通过ORM框架,可以自动的把程序中的对象和 数据库关联。
ORM框架会隐藏具体的数据库底层细节,让开发者使用同样的数据操作接口,完成对不同数据库的操作。
npm install --save sequelize
安装驱动程序:
npm install --save mysql2
连接到数据库
要连接到数据库,必须创建一个 Sequelize 实例. 这可以通过将连接参数分别传递到 Sequelize 构造函数或通过传递一个连接 URI 来完成:
const {Sequelize} = require("sequelize");
// 创建数据库连接
const sequelize = new Sequelize('jingmao', 'root', 'root', {
host: 'localhost',
dialect: 'mysql',
logging: false, // 生成的sql语句不在控制台打印
})
// 测试连接
async function MyFn() {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (error) {
console.error('Unable to connect to the database:', error);
}
}
MyFn();
Sequelize 构造函数接受很多参数. 它们记录在 API 参考中.
在 app.js 中引入文件,执行测试。
require('./dao/dbConnect')
Express 中使用 Sequelize
连接和初始化数据库
dbConnect.js
const {Sequelize} = require("sequelize");
// 创建数据库连接
const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, {
host: process.env.DB_HOST,
dialect: 'mysql',
logging: false, // 生成的sql语句不在控制台打印 默认值 logging: console.log
})
// 以对象的形式暴露
module.exports = sequelize;
这里使用了 dotenv 这个库 将一些环境变量写到 .env 中,将 .env 添加到 precess.env ,便于管理。
db.js
// 初始化数据库
const sequelize = require('./dbConnect'); // 数据库连接实例
const adminModel = require('./model/adminModel');// 管理员模型
const bannerModel = require('./model/bannerModel');
const md5 = require("md5");
const blogTypeModel = require("./model/blogTypeModel");
const blogModel = require('./model/blogModel');
const messageModel = require('./model/messageModel');
(async function () {
// 定义模型之间的关联关系
// 文章与文章分类之间的关联
blogTypeModel.hasMany(blogModel, {foreignKey: 'categoryId', targetKey: 'id'})
blogModel.belongsTo(blogTypeModel, {foreignKey: 'categoryId', targetKey: 'id', as: 'category'})
// 文章和评论之间的关联
blogModel.hasMany(messageModel, {foreignKey: 'blogId', targetKey: 'id'})
messageModel.belongsTo(blogModel, {foreignKey: 'blogId', targetKey: 'id', as: 'blog'})
// 同步模型和数据表(一次性同步所有模型)
await sequelize.sync({
alter: true
})
// 如果没有数据,则初始化管理员数据
const adminCount = await adminModel.count()
if (!adminCount) {
await adminModel.create({
loginId: 'admin',
name: '超级管理员',
loginPwd: md5('123456'),
})
console.log('初始化管理员数据成功')
}
// banner 初始化操作
const bannerCount = await bannerModel.count()
if (!bannerCount) {
await bannerModel.bulkCreate([{
"midImg": "/static/images/bg1_mid.jpg",
"bigImg": "/static/images/bg1_big.jpg",
"title": "塞尔达旷野之息",
"description": "2017年年度游戏,期待续作"
}, {
"midImg": "/static/images/bg2_mid.jpg",
"bigImg": "/static/images/bg2_big.jpg",
"title": "塞尔达四英杰",
"description": "四英杰里面你最喜欢的又是谁呢"
}, {
"midImg": "/static/images/bg3_mid.jpg",
"bigImg": "/static/images/bg3_big.jpeg",
"title": "日本街道",
"description": "动漫中经常出现的日本农村街道,一份独特的恬静"
}])
console.log('初始化首页标语数据成功')
}
console.log('数据库初始化完成')
})()
模型同步:
当然除了一次性同步所有模型,也可以同步单个模型。
User.sync()- 如果表不存在,则创建该表(如果已经存在,则不执行任何操作)User.sync({ force: true })- 将创建表,如果表已经存在,则将其首先删除User.sync({ alter: true })- 这将检查数据库中表的当前状态(它具有哪些列,它们的数据类型等),然后在表中进行必要的更改以使其与模型匹配.
表关联:
A.hasOne(B) 关联意味着 A 和 B 之间存在一对一的关系,外键在目标模型(B)中定义.
A.belongsTo(B)关联意味着 A 和 B 之间存在一对一的关系,外键在源模型中定义(A).
A.hasMany(B) 关联意味着 A 和 B 之间存在一对多关系,外键在目标模型(B)中定义.
这三个调用将导致 Sequelize 自动将外键添加到适当的模型中(除非它们已经存在).
A.belongsToMany(B, { through: 'C' }) 关联意味着将表 C 用作联结表,在 A 和 B 之间存在多对多关系. 具有外键(例如,aId 和 bId). Sequelize 将自动创建此模型 C(除非已经存在),并在其上定义适当的外键.
app.js
// 捕获异步错误
require("express-async-errors")
// 默认读取项目根目录下的 .env 环境变量文件
require('dotenv').config()
// 引入数据库连接
require('./dao/db')
adminModel.js
const {DataTypes} = require("sequelize")
const sequelize = require("../dbConnect")
// 定义数据表
module.exports = sequelize.define("admin", {
// id 自动生成 无需手动定义
loginId: {
type: DataTypes.STRING,
allowNull: false,
},
loginPwd: {
type: DataTypes.STRING,
allowNull: false,
},
name: {
type: DataTypes.STRING,
allowNull: false
}
}, {
freezeTableName: true, // 禁止默认的自动复数化
createdAt: false, // 创建表的时间,关闭默认字段
// 或者也可以自定义名称 createdAt: "create_time"
updatedAt: false, // 修改表的时间,关闭默认字段
// tableNameL "administrators", // 手动定义表名
// paranoid: true, // 该表的数据不会真正删除,而是增加一列deletedAt记录删除时间(逻辑删除时间)
})
自动复数化,比如给出模型名称为 user,那么表名自动为 users 。
操作数据库
const adminModel = require('./model/adminModel')
module.exports.loginDao = async function(loginInfo) {
return await adminModel.findOne({
where: {
loginId: loginInfo.loginId,
loginPwd: loginInfo.loginPwd
}
})
}