← Назад к вопросам

Для чего нужно ORM?

1.0 Junior🔥 121 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

ORM (Object-Relational Mapping)

ОRM — это инструмент, который помогает работать с базами данных, но для фронтенд-разработчика это обычно не релевантно в прямом смысле. Однако понимание ORM важно при работе с полнофункциональными фреймворками или при общении с бэкенд-командой.

Что такое ORM

ORM (Object-Relational Mapping) — это технология, которая отображает таблицы БД на объекты в программном коде. Вместо написания SQL запросов, ты работаешь с объектами.

Основная проблема, которую решает ORM

Без ORM (через raw SQL):

// Node.js с психтоп postgres
const result = await client.query(
  "SELECT id, name, email FROM users WHERE id = $1",
  [userId]
);

const user = {
  id: result.rows[0].id,
  name: result.rows[0].name,
  email: result.rows[0].email
};

С ORM (например, Sequelize или TypeORM):

const user = await User.findById(userId);
// Объект ready to use
console.log(user.name, user.email);

Популярные ORM для Node.js / JavaScript

1. Sequelize (Node.js)

const { DataTypes } = require("sequelize");
const sequelize = new Sequelize("database", "user", "password");

const User = sequelize.define("User", {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  name: DataTypes.STRING,
  email: DataTypes.STRING
});

const user = await User.findByPk(1);
console.log(user.name);

2. TypeORM (TypeScript)

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  email: string;
}

const userRepository = AppDataSource.getRepository(User);
const user = await userRepository.findOneBy({ id: 1 });

3. Prisma (Modern ORM)

// prisma/schema.prisma
model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String
}

// Использование
const user = await prisma.user.findUnique({
  where: { id: 1 }
});

Основные функции ORM

1. Определение моделей

// TypeORM
@Entity()
export class Post {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  content: string;

  @CreateDateColumn()
  createdAt: Date;
}

2. CRUD операции

// Create
const post = await postRepository.create({
  title: "My Post",
  content: "Content here"
});
await postRepository.save(post);

// Read
const post = await postRepository.findOne({ where: { id: 1 } });

// Update
post.title = "Updated Title";
await postRepository.save(post);

// Delete
await postRepository.remove(post);

3. Связи между таблицами (Relations)

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  // Один ко многим — User имеет много Posts
  @OneToMany(() => Post, (post) => post.user, { cascade: true })
  posts: Post[];
}

@Entity()
export class Post {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  // Многие к одному — Post принадлежит одному User
  @ManyToOne(() => User, (user) => user.posts)
  user: User;
}

// Использование
const user = await userRepository.findOne({
  where: { id: 1 },
  relations: ["posts"] // Загрузить связанные посты
});
console.log(user.posts); // Массив постов

4. Запросы с фильтрацией

// Простой фильтр
const users = await userRepository.find({
  where: { name: "John" }
});

// Сложный фильтр
const users = await userRepository.find({
  where: {
    name: Like("%John%"),
    age: MoreThan(18)
  },
  order: { createdAt: "DESC" },
  take: 10, // LIMIT
  skip: 0   // OFFSET
});

Преимущества ORM

1. Абстракция от БД:

// Код одинаков для PostgreSQL, MySQL, SQLite
const users = await userRepository.find();
// ORM автоматически переводит в нужный SQL диалект

2. Безопасность от SQL-инъекций:

// ПЛОХО — уязвимо к SQL-инъекциям
query(`SELECT * FROM users WHERE email = `);

// ХОРОШО — ORM защищает
const user = await userRepository.findOneBy({ email: userEmail });

3. Type-safety в TypeScript:

// Автодополнение и проверка типов
const user = await userRepository.findOne({ where: { id: 1 } });
user.name.toUpperCase(); // TypeScript знает, что это строка

4. Удобные связи:

const user = await userRepository.findOne({
  where: { id: 1 },
  relations: ["posts", "comments", "profile"]
});
// Все связанные данные загружены одним запросом

Недостатки ORM

1. Производительность:

// N+1 query проблема
const users = await userRepository.find();
for (const user of users) {
  const posts = await postRepository.find({
    where: { userId: user.id }
  });
  // Один запрос за юзера = медленно!
}

// Правильно
const users = await userRepository.find({
  relations: ["posts"]
});

2. Сложные запросы:

// Сложные аналитические запросы проще на raw SQL
const stats = await datasource.query(`
  SELECT 
    DATE(created_at) as date,
    COUNT(*) as count,
    SUM(amount) as total
  FROM orders
  GROUP BY DATE(created_at)
  HAVING SUM(amount) > 1000
`);

3. Изучение кривой:

Каждый ORM имеет свой API и документацию.

ORM и фронтенд

Для фронтенда ORM обычно не используется напрямую, но имеет значение:

  1. При работе с Electron — используется Node.js ORM
  2. При разработке BFF (Backend for Frontend) — может использоваться
  3. При понимании API бэкенда — помогает понять, как структурированы данные

Пример интеграции в React приложение

// useUsers.ts — hook для загрузки пользователей
import { useEffect, useState } from "react";

interface User {
  id: number;
  name: string;
  email: string;
}

export function useUsers() {
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetch("/api/users")
      .then(res => res.json())
      .then(data => {
        setUsers(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err.message);
        setLoading(false);
      });
  }, []);

  return { users, loading, error };
}

// В компоненте
function UsersList() {
  const { users, loading, error } = useUsers();

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name} ({user.email})</li>
      ))}
    </ul>
  );
}

Итог

ORM — это инструмент для серверной разработки, который упрощает работу с базами данных. Для фронтенд-разработчика важно понимать концепцию, но прямого применения обычно нет, если ты не работаешь с Node.js бэкендом или Electron приложениями.

Для чего нужно ORM? | PrepBro