在 Node.js 项目中可以使用Sequelize
这个ORM
(对象关系映射)库来将项目中的 Model 和数据库表进行映射以及可以让我们可以使用 JavaScript 的对象和方法来操作数据库(CRUD),而不必编写原生 SQL 语句。
安装 安装 Sequelize bash 1 npm install -S sequelize
安装对应数据库驱动 bash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 npm install -S mysql2 npm install -S pg pg-hstore npm install -S sqlite3 npm install -S tedious npm install -S mariadb npm install -S oracledb
使用 Sequelize提供的大多数方法都是异步的,会返回Promise
,所以可以使用Promise API。
创建 Sequelize 实例 创建一个Sequelize实例并连接到数据库:
models/index.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const { Sequelize } = require ("sequelize" );const sequelize = new Sequelize("database_name" , "username" , "password" , { host: "localhost" , dialect: "mysql" , }); sequelize .authenticate() .then(() => { console .log("Connection has been established successfully." ); }) .catch((err ) => { console .error("Unable to connect to the database:" , err); }); module .exports = sequelize;
定义模型(Model) 在 Sequelize 中,模型代表数据库中的表。 可以通过定义模型来映射数据库表及其字段。
models/user.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const { DataTypes } = require ("sequelize" );const sequelize = require ("./index" );const User = sequelize.define( "User" , { username: { type: DataTypes.STRING, allowNull: false , unique: true , }, password: { type: DataTypes.STRING, allowNull: false , }, email: { type: DataTypes.STRING, allowNull: false , unique: true , }, }, { tableName: "users" , timestamps: true , } ); module .exports = User;
同步模型与数据库 在项目启动时同步模型和数据库。
在项目入口 js 文件中添加:
index.js 1 2 3 4 5 6 7 8 9 10 11 12 const sequelize = require ("./models/index" );const User = require ("./models/user" );sequelize .sync({ force : false }) .then(() => { console .log("Database & tables created!" ); }) .catch((err ) => { console .error("Failed to sync database:" , err); });
CRUD 操作 可以调用模型的 CRUD 方法操作数据库。
js 1 2 3 4 5 6 7 8 9 10 11 User.create({ username: "john_doe" , password: "secret123" , email: "john@example.com" , }) .then((user ) => { console .log("User created:" , user.toJSON()); }) .catch((err ) => { console .error("Failed to create user:" , err); });
js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 User.findOne({ where : { username : "john_doe" } }) .then((user ) => { if (user) { console .log("User found:" , user.toJSON()); } else { console .log("User not found" ); } }) .catch((err ) => { console .error("Failed to find user:" , err); }); User.findAll() .then((users ) => { console .log("All users:" , JSON .stringify(users, null , 2 )); }) .catch((err ) => { console .error("Failed to find users:" , err); });
js 1 2 3 4 5 6 7 User.update({ password : "newpassword123" }, { where : { username : "john_doe" } }) .then((rowsUpdated ) => { console .log("Number of rows updated:" , rowsUpdated); }) .catch((err ) => { console .error("Failed to update user:" , err); });
js 1 2 3 4 5 6 7 User.destroy({ where : { username : "john_doe" } }) .then((rowsDeleted ) => { console .log("Number of rows deleted:" , rowsDeleted); }) .catch((err ) => { console .error("Failed to delete user:" , err); });
记录日志 默认情况下,Sequelize将记录控制台执行的每个SQL查询。可以使用options.logging
参数来自定义每次 Sequelize记录某些内容时将执行的函数。默认值为console.log
,使用该值时仅显示日志函数调用的第一个参数。例如,对于查询日志记录,第一个参数是原始查询,第二个参数(默认情况下是隐藏的)是Sequelize对象。
js 1 2 3 4 5 6 7 8 const sequelize = new Sequelize('sqlite::memory:' , { logging: console .log, logging: (...msg ) => console .log(msg), logging: false , logging: msg => logger.debug(msg), logging: logger.debug.bind(logger) });
关系映射 Sequelize 支持定义表之间的关系(一对一、一对多、多对多)。
定义User
和Post
之间为一对多的关系:
js 1 2 3 4 5 6 7 8 9 10 11 const Post = sequelize.define("Post" , { title: DataTypes.STRING, content: DataTypes.TEXT, }); User.hasMany(Post); Post.belongsTo(User); sequelize.sync();
查询生成器 Sequelize 支持复杂的查询构建与聚合操作,可以轻松实现分页、排序、分组等操作。
js 1 2 3 4 5 6 7 8 9 10 11 12 User.findAll({ where: { email : { [Op.like]: "%@example.com" } }, order: [["createdAt" , "DESC" ]], limit: 10 , offset: 20 , }) .then((users ) => { console .log("Paged users:" , JSON .stringify(users, null , 2 )); }) .catch((err ) => { console .error("Failed to retrieve users:" , err); });
事务处理(Transactions) 通过sequelize.transaction()
来管理事务,确保操作的原子性。
js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 sequelize .transaction(async (t) => { const user = await User.create( { username: "jane_doe" , password: "password123" , email: "jane@example.com" , }, { transaction : t } ); await Post.create( { title: "Jane's first post" , content: "This is Jane's first post" , userId: user.id, }, { transaction : t } ); }) .then(() => { console .log("Transaction has been committed" ); }) .catch((err ) => { console .error("Transaction has been rolled back:" , err); });
验证与钩子(Hooks) Sequelize 提供内置的验证机制,并允许你定义生命周期钩子,在模型操作前后执行代码。
js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 const User = sequelize.define( "User" , { username: { type: DataTypes.STRING, allowNull: false , unique: true , validate: { len: [4 , 20 ], }, }, password: { type: DataTypes.STRING, allowNull: false , }, }, { hooks: { beforeCreate: (user ) => { user.password = hashPassword(user.password); }, }, } );
配置与环境变量 可以通过环境变量或配置文件管理不同环境下的数据库连接配置:
js 1 2 3 4 5 6 7 8 9 const sequelize = new Sequelize( process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, { host: process.env.DB_HOST, dialect: "mysql" , } );
迁移与种子数据 Sequelize CLI工具支持数据库迁移和种子数据管理。可以通过命令行生成和应用迁移来管理数据库的演进。
bash 1 2 3 npx sequelize-cli init npx sequelize-cli model:generate --name User --attributes username:string,email:string npx sequelize-cli db:migrate
参考
https://www.sequelize.cn/