nodejsnotes

Topic 012: ORMs & ODMs in Node.js

Topic 012: ORMs & ODMs in Node.js

ORM (Object-Relational Mapping)

Definition: ORM is a programming technique used to convert data between incompatible type systems in object-oriented programming languages. It is used to interact with relational databases (SQL databases) by mapping objects in your code to database tables.

Examples of ORMs:

Key Features:

Example Using Sequelize (Node.js):

  1. Install Sequelize and a SQL database driver (e.g., for PostgreSQL):

    npm install sequelize pg pg-hstore
    
  2. Define a Model and Perform Operations:

    const { Sequelize, DataTypes } = require("sequelize");
    const sequelize = new Sequelize("database", "username", "password", {
      host: "localhost",
      dialect: "postgres",
    });
    
    // Define a model
    const User = sequelize.define("User", {
      name: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      age: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
      status: {
        type: DataTypes.STRING,
      },
      score: {
        type: DataTypes.INTEGER,
      },
    });
    
    async function run() {
      await sequelize.sync({ force: true }); // Sync all defined models to the DB
    
      // Create a new user
      const newUser = await User.create({ name: "John Doe", age: 30, status: "A", score: 90 });
    
      // Find users with complex query
      const users = await User.findAll({
        where: {
          age: { [Sequelize.Op.gt]: 25 },
          [Sequelize.Op.or]: [{ status: "A" }, { score: { [Sequelize.Op.gt]: 80 } }],
        },
      });
    
      console.log(users);
    }
    
    run().catch(console.error);
    

ODM (Object-Document Mapping)

Definition: ODM is a technique used to map objects in object-oriented programming languages to documents in NoSQL databases (such as MongoDB). It allows the application to interact with the NoSQL database using objects, abstracting away the complexity of the database queries.

Examples of ODMs:

Key Features:

Example Using Mongoose (Node.js):

  1. Install Mongoose:

    npm install mongoose
    
  2. Define a Model and Perform Operations:

    const mongoose = require("mongoose");
    
    const uri = "mongodb://localhost:27017/your_database";
    mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
    
    // Define a schema and model
    const userSchema = new mongoose.Schema({
      name: { type: String, required: true },
      age: { type: Number, required: true },
      status: String,
      score: Number,
    });
    
    const User = mongoose.model("User", userSchema);
    
    async function run() {
      // Create a new user
      const newUser = new User({ name: "John Doe", age: 30, status: "A", score: 90 });
      await newUser.save();
    
      // Find users with complex query
      const users = await User.find({
        age: { $gt: 25 },
        $or: [{ status: "A" }, { score: { $gt: 80 } }],
      }).exec();
    
      console.log(users);
    }
    
    run()
      .catch(console.error)
      .finally(() => mongoose.connection.close());
    

Comparison of ORM and ODM

Feature ORM ODM
Database Type Relational (SQL) Databases NoSQL Databases
Data Structure Tables with rows and columns Documents (often JSON-like)
Relationships Uses foreign keys and joins Uses embedded documents and references
Schema Fixed schema (enforced by the database) Flexible schema (can be enforced by the ODM)
Examples Sequelize, Hibernate, Entity Framework Mongoose, Morphia, Spring Data MongoDB
Query Language SQL Query objects (e.g., MongoDB query language)

Conclusion

Here’s a detailed look at three popular ORMs & ODMs in Node.js: Mongoose, Sequelize, and Knex.

Mongoose

Mongoose is an ODM (Object Data Modeling) library for MongoDB and Node.js. It provides a schema-based solution to model your application data.

Installation

npm install mongoose

Usage Example

  1. Connect to MongoDB:
const mongoose = require("mongoose");

mongoose
  .connect("mongodb://localhost:27017/mydatabase", {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => {
    console.log("Connected to MongoDB");
  })
  .catch((error) => {
    console.error("Error connecting to MongoDB:", error);
  });
  1. Define a Schema and Model:
const { Schema } = mongoose;

const userSchema = new Schema({
  name: String,
  email: String,
  age: Number,
});

const User = mongoose.model("User", userSchema);
  1. Create and Save a Document:
const newUser = new User({
  name: "John Doe",
  email: "john@example.com",
  age: 30,
});

newUser
  .save()
  .then(() => {
    console.log("User saved");
  })
  .catch((error) => {
    console.error("Error saving user:", error);
  });
  1. Query Documents:
User.find({ age: { $gt: 25 } })
  .then((users) => {
    console.log("Users older than 25:", users);
  })
  .catch((error) => {
    console.error("Error finding users:", error);
  });

Sequelize

Sequelize is a promise-based ORM for Node.js, supporting many SQL dialects like MySQL, PostgreSQL, SQLite, and MSSQL.

Installation

npm install sequelize
npm install mysql2  # Or any other SQL dialect driver

Usage Example

  1. Initialize Sequelize:
const { Sequelize, DataTypes } = require("sequelize");
const sequelize = new Sequelize("database", "username", "password", {
  host: "localhost",
  dialect: "mysql", // Change this to your dialect
});
  1. Define a Model:
const User = sequelize.define(
  "User",
  {
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
    },
    age: {
      type: DataTypes.INTEGER,
    },
  },
  {
    tableName: "users",
  }
);
  1. Sync Models with the Database:
sequelize.sync().then(() => {
  console.log("Database & tables created!");
});
  1. Create and Save a Record:
User.create({
  name: "Jane Doe",
  email: "jane@example.com",
  age: 28,
}).then((user) => {
  console.log("User created:", user);
});
  1. Query Records:
User.findAll({ where: { age: { [Sequelize.Op.gt]: 25 } } }).then((users) => {
  console.log("Users older than 25:", users);
});

Knex.js

Knex.js is a SQL query builder for Node.js, supporting various SQL dialects. Unlike ORMs, Knex.js is primarily a query builder but can be used with other ORMs like Bookshelf.js for a more ORM-like experience.

Installation

npm install knex
npm install pg  # Or any other SQL dialect driver

Usage Example

  1. Initialize Knex:
const knex = require("knex")({
  client: "pg",
  connection: {
    host: "127.0.0.1",
    user: "your_database_user",
    password: "your_database_password",
    database: "myapp_test",
  },
});
  1. Create a Table:
knex.schema
  .createTable("users", (table) => {
    table.increments("id");
    table.string("name");
    table.string("email");
    table.integer("age");
  })
  .then(() => {
    console.log("Table created");
  })
  .catch((error) => {
    console.error("Error creating table:", error);
  });
  1. Insert Data:
knex("users")
  .insert({
    name: "Alice",
    email: "alice@example.com",
    age: 25,
  })
  .then(() => {
    console.log("Data inserted");
  });
  1. Query Data:
knex("users")
  .where("age", ">", 20)
  .select("name", "email")
  .then((users) => {
    console.log("Users older than 20:", users);
  });
  1. Close the Connection:
knex.destroy().then(() => {
  console.log("Connection closed");
});

Summary

Each of these tools has its own strengths and is suitable for different types of projects and database requirements.