Course contentsShow
← Node.js
Lesson 759 of 1,9808. Data Persistence and ORM IntegrationFree lesson

Mapping Domain Models to Database Records

You will bridge the gap between object-oriented JavaScript classes and flat relational tables.

In this lesson, you will learn how to translate your clean, object-oriented JavaScript classes into the rigid, flat structure of a relational database table.

When building applications, we often think in terms of Domain Models—JavaScript classes that contain logic, state, and relationships (like a User class). However, relational databases don't understand JavaScript objects; they only understand tables, rows, and columns. Mapping is the bridge that converts your rich, stateful object into a serialized format that the database can persist.

The Impedance Mismatch

JavaScript objects can be deeply nested, contain methods, and hold complex arrays. Database rows are flat and scalar (storing simple strings, numbers, or booleans). To bridge this, we treat the class as a template for the table record.

Consider a simple Product domain model:

class Product {
  constructor(id, name, price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }

  // Domain logic
  applyDiscount(percent) {
    this.price -= (this.price * percent);
  }
}

When saving this to a database, you cannot save the applyDiscount method. Instead, you extract the raw data properties to create a database record.

How Mapping Works

You typically perform this mapping in two directions:

  1. Serialization (Outbound): You take an instance of your Product class and extract its public properties to pass into a SQL INSERT or UPDATE statement.
  2. Hydration (Inbound): When you fetch data from the database using a driver, you receive a plain JSON object. You then "hydrate" that object by passing it into the Product constructor to restore the instance’s methods.
// Serialization: Getting ready to save
const rowData = { id: myProduct.id, name: myProduct.name, price: myProduct.price };
db.query('INSERT INTO products SET ?', rowData);

// Hydration: Converting a database row back into a Domain Model
const rawRow = await db.query('SELECT * FROM products WHERE id = 1');
const myProduct = new Product(rawRow.id, rawRow.name, rawRow.price);

By keeping these two worlds separate, your business logic remains protected inside the class, while your database remains efficient and organized.

Key Takeaway: Mapping is the process of stripping away class methods to save raw data to a table and re-wrapping that raw data back into an object instance once retrieved.