<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dhanya Chandrasekaran</title>
    <description>The latest articles on DEV Community by Dhanya Chandrasekaran (@dhanya).</description>
    <link>https://dev.to/dhanya</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F950844%2F4c5169ed-04d7-439f-9c75-5b8663033dc6.png</url>
      <title>DEV Community: Dhanya Chandrasekaran</title>
      <link>https://dev.to/dhanya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhanya"/>
    <language>en</language>
    <item>
      <title>ORM - Active Record Pattern vs Data Mapper Pattern</title>
      <dc:creator>Dhanya Chandrasekaran</dc:creator>
      <pubDate>Wed, 20 Dec 2023 07:58:18 +0000</pubDate>
      <link>https://dev.to/dhanya/orm-active-record-pattern-vs-data-mapper-pattern-2764</link>
      <guid>https://dev.to/dhanya/orm-active-record-pattern-vs-data-mapper-pattern-2764</guid>
      <description>&lt;p&gt;Active record and Data mapper patterns are two different approaches in accessing data in database (which can be referred as a persistent storage).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Active Record Pattern:&lt;/strong&gt;&lt;br&gt;
In this approach, a table is viewed as a class/entity and an object instance is associated with each row in the table.&lt;br&gt;
Creation, Updation and Deletion of an object associates to the corresponding row in the table.&lt;/p&gt;

&lt;p&gt;Example in typeorm:&lt;br&gt;
[Typeorm - orm that can run in NodeJs, Browser etc]&lt;br&gt;
user.js - referred as user model which represents the user table in database.&lt;/p&gt;

&lt;p&gt;import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from "typeorm"&lt;/p&gt;

&lt;p&gt;@Enitiy()&lt;br&gt;
export class User extends BaseEntity {&lt;br&gt;
  @PrimaryGeneratedColumn()&lt;br&gt;
  id: number;&lt;br&gt;
  @Column()&lt;br&gt;
  firstName: string;&lt;br&gt;
  @Column() &lt;br&gt;
  lastName: string;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;The extended class BaseEntity provides all methods with respect to the creation, updation and deletion of a record.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creation of a new record:
import { User } from '../models/user.js'&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;const user = new User();&lt;br&gt;
user.firstName = 'John';&lt;br&gt;
user.lastName = 'Doe';&lt;br&gt;
await user.save();&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Mapper Pattern:&lt;/strong&gt;&lt;br&gt;
In this approach, the query methods such as save, remove etc are defined in a separate class called "repositories".&lt;br&gt;
By this way it achieves independency between the in-memory representation (the entities/models) and the persistent storage (which refers to the database), as the entities will not be aware of how the data is being stored in database.&lt;/p&gt;

&lt;p&gt;Example in typeorm:&lt;br&gt;
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"&lt;/p&gt;

&lt;p&gt;@Enitiy()&lt;br&gt;
export class User {&lt;br&gt;
  @PrimaryGeneratedColumn()&lt;br&gt;
  id: number;&lt;br&gt;
  @Column()&lt;br&gt;
  firstName: string;&lt;br&gt;
  @Column() &lt;br&gt;
  lastName: string;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Creation of a new record:&lt;br&gt;
import { User } from '../models/user.js'&lt;/p&gt;

&lt;p&gt;const userRepository = MyDataSource.getRepository(User);&lt;br&gt;
const user = new User();&lt;br&gt;
user.firstName = 'John';&lt;br&gt;
user.lastName = 'Doe';&lt;br&gt;
await userRepository.save(user);&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comparison:&lt;/strong&gt;&lt;br&gt;
When to use Data Mapper:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can be used in complex/larger applications where we have a complex domain logic (business logic)&lt;/li&gt;
&lt;li&gt;Can be used if we want a separation or independency between in-memory representation (domain layer) and persistent storage (database layer).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example usecase - &lt;br&gt;
User along with the book he/she borrowed:&lt;br&gt;
Domain object:&lt;br&gt;
class User {&lt;br&gt;
    private firstName: string;&lt;br&gt;
    private lastName: string;&lt;br&gt;
    private booksBorrowed: BooksBorrowed[];&lt;br&gt;
    constructor(firstName: string, lastName: &lt;br&gt;
      string, booksBorrowed: BooksBorrowed[]) &lt;br&gt;
    {&lt;br&gt;
       this.firstName = firstName;&lt;br&gt;
       this.lastName = lastName;&lt;br&gt;
       this.booksBorrowed = booksBorrowed;&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;class BooksBorrowed {&lt;br&gt;
    private bookId: string;&lt;br&gt;
    private author: string;&lt;br&gt;
    constructor(bookId: string, author: &lt;br&gt;
      string) {&lt;br&gt;
                  this.bookId = bookId;&lt;br&gt;
                  this.author = author;&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Database schema can be different from what we have defined in domain object.&lt;br&gt;
Therefore save, fetch operations and complex logic can be handled independently without exposing it to the domain object.&lt;/p&gt;

&lt;p&gt;As the domain object is independent of the database schema, data mapper can be used in cases where the database schema changes frequently.&lt;/p&gt;

&lt;p&gt;When to use Active Record Pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is suitable in case of a simpler application where it mostly involves basic CRUD operations.&lt;/li&gt;
&lt;li&gt;If we want the model (in-memory storage) to replicate the database schema (i.e no need for separation between the domain layer and database layer).&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
