In the world of Node.js development, managing databases effectively can be a significant challenge, especially when dealing with relational databases. Writing raw SQL queries while maintaining clean code architecture is difficult, and this is where Object-Relational Mapping (ORM) tools like Sequelize come to the rescue. Let’s explore how Sequelize transforms database interactions in a Node.js e-commerce application.
What is Sequelize?
Sequelize is a promise-based Node.js ORM for SQL databases. it support PostgresSQL, MYSQL, MarisDB, SQLite, and Microsoft SQL Server.
Instead of writing complex SQL queries manually Sequelize allows developer to interact with databases using JavaScript objects and methods, bring database operations close to application’s domina logic.
Setting Up Sequelize in a Node.js Application
A typical setup in an Express application look like this:
//./util/database
const Sequelize = require('sequelize');
const sequelize = new Sequelize('my_new_db', 'root', 'root', {
dialect: 'mysql',
host: 'localhost'
});
module.exports = sequelize;
//app.js
const express = require('express');
const sequelize = require('./util/database');
const Product = require('./models/product');
const User = require('./models/user');
// Other imports...
const app = express();
// Express configuration...
// Define associations between models
Product.belongsTo(User, { constraints: true, onDelete: 'CASCADE' });
User.hasMany(Product);
User.hasOne(Cart);
// More associations...
// Sync models with database
sequelize
.sync()
.then(result => {
app.listen(3001);
})
.catch(err => {
console.log(err);
});
This code snippet demonstrates how to initialize Sequelize, Define model relationships, and synchronize your models with database
Defining Relationships: The Power of Associations
One of Sequelize’s greatest strengths is how it handles relationships between models. Consider these associations from our e-commerce application:
User.hasMany(Product);
User.hasOne(Cart);
Cart.belongsToMany(Product, { through: CartItem });
Order.belongsTo(User);
Order.belongsToMany(Product, { through: OrderItem });
Each association automatically generate helpful methods that make working with related data intuitive. For example, when you define User.hasMany(Order), Sequelize automatically creates methods like user.getOrders(), user.createOrder(), and user.setOrders().
Auto-Generated Methods: The Hidden Gem
These auto-generated methods follow consistent naming patterns based on the association type and model name. For instance, with the User.hasMany(Order) association, you get:
user.getOrders()– Retrieve all orders for a useruser.countOrders()– Count the user’s ordersuser.createOrder()– Create a new order for this useruser.addOrder(order)– Associate an existing order with this useruser.setOrders([orders])– Replace all of the user’s orders
Let’s see this in action with a real example from our application:
exports.postOrder = (req, res, next) => {
let fetchedCart;
req.user
.getCart()
.then(cart => {
fetchedCart = cart;
return cart.getProducts();
})
.then(products => {
return req.user
.createOrder()
.then(order => {
return order.addProducts(
products.map(product => {
product.orderItem = { quantity: product.cartItem.quantity };
return product;
})
);
});
})
.then(result => {
return fetchedCart.setProducts(null);
})
.then(result => {
res.redirect('/orders');
})
.catch(err => console.log(err));
};
This controller function demonstrates how Sequelize’s auto-generated methods simplify order creation:
req.user.getCart()– Retrieves the user’s cartcart.getProducts()– Gets all products in the cartreq.user.createOrder()– Creates a new order for the userorder.addProducts()– Adds products to the orderfetchedCart.setProducts(null)– Clears the cart by removing all products
Without Sequelize, each of these operations would require complex SQL joins and multiple queries.
Common Sequelize Methods in Practice
Beyond association methods, Sequelize provides standard CRUD operations:
Model.create()– Create a new recordModel.findByPk()– Find a record by primary keyModel.findAll()– Get all recordsModel.update()– Update recordsModel.destroy()– Delete records