JS ORM框架详细介绍

ORM(Object-Relational Mapping)框架是连接面向对象编程语言和关系型数据库的桥梁,它允许开发者以面向对象的方式操作数据库,而无需直接编写SQL语句。以下是JavaScript生态系统中主要ORM框架的详细介绍。

主流JS ORM框架

1. Sequelize

特点

  • 支持多种数据库:PostgreSQL, MySQL, MariaDB, SQLite, MSSQL
  • 成熟的解决方案,社区支持强大
  • 提供事务支持、迁移、模型关联等功能
  • 支持Promise和async/await 基本用法
    const { Sequelize, Model, DataTypes } = require('sequelize');
    const sequelize = new Sequelize('sqlite::memory:');
    class User extends Model {}
    User.init({
    username: DataTypes.STRING,
    birthday: DataTypes.DATE
    }, { sequelize, modelName: 'user' });
    (async () => {
    await sequelize.sync();
    const jane = await User.create({
      username: 'janedoe',
      birthday: new Date(1980, 6, 20)
    });
    console.log(jane.toJSON());
    })();
    

2. TypeORM

特点

  • 支持TypeScript和JavaScript(ES5, ES6, ES7, ES8)
  • 支持多种数据库:MySQL, PostgreSQL, MariaDB, SQLite, MSSQL, MongoDB等
  • 同时支持Active Record和Data Mapper模式
  • 装饰器语法 基本用法
    import { Entity, PrimaryGeneratedColumn, Column, createConnection } from "typeorm";
    @Entity()
    export class User {
      @PrimaryGeneratedColumn()
      id: number;
      @Column()
      firstName: string;
      @Column()
      lastName: string;
    }
    (async () => {
      const connection = await createConnection();
      const user = new User();
      user.firstName = "Timber";
      user.lastName = "Saw";
      await connection.manager.save(user);
    })();
    

3. Prisma

特点

  • 下一代ORM,提供类型安全的数据库访问
  • 自带Prisma Client自动生成
  • 提供数据迁移工具
  • 支持GraphQL
  • 支持多种数据库:PostgreSQL, MySQL, SQLite, MSSQL, MongoDB 基本用法
    const { PrismaClient } = require('@prisma/client')
    const prisma = new PrismaClient()
    async function main() {
    const newUser = await prisma.user.create({
      data: {
        name: 'Alice',
        email: 'alice@prisma.io',
      },
    })
    console.log(newUser)
    }
    main()
    .catch(e => {
      throw e
    })
    .finally(async () => {
      await prisma.$disconnect()
    })
    

4. Mongoose (针对MongoDB)

特点

  • 专为MongoDB设计的ODM(Object Document Mapping)
  • 提供模式(schema)验证、中间件、查询构建等功能
  • 成熟的生态系统 基本用法
    const mongoose = require('mongoose');
    mongoose.connect('mongodb://localhost/test');
    const Cat = mongoose.model('Cat', { name: String });
    const kitty = new Cat({ name: 'Zildjian' });
    kitty.save().then(() => console.log('meow'));
    

5. Knex.js

特点

  • 更接近SQL的查询构建器
  • 支持事务、连接池、迁移等
  • 可以与Objection.js等ORM配合使用 基本用法
    const knex = require('knex')({
    client: 'sqlite3',
    connection: {
      filename: './data.db',
    },
    });
    knex('users').where('id', 1)
    .then(rows => {
      console.log(rows);
    });
    

ORM框架核心功能比较

功能 Sequelize TypeORM Prisma Mongoose Knex.js
多数据库支持
TypeScript 部分 部分 部分
迁移工具
事务支持
关联/关系
查询构建器
活跃社区

选择建议

  1. 全功能ORM:TypeORM或Sequelize
    • 需要TypeScript支持优先TypeORM
    • 需要成熟稳定选择Sequelize
  2. 现代开发体验:Prisma
    • 适合新项目,追求开发效率和类型安全
  3. MongoDB开发:Mongoose
    • MongoDB专用,功能全面
  4. 轻量级SQL操作:Knex.js
    • 需要更接近SQL的体验
    • 作为其他ORM的底层查询构建器

高级主题

性能优化

  1. 懒加载 vs 急加载
    // 懒加载
    const user = await User.findOne();
    const posts = await user.getPosts();
    // 急加载
    const user = await User.findOne({
      include: ['posts']
    });
    
  2. 批量操作
    // 避免N+1查询
    await User.findAll({
      include: [{
        model: Post,
        where: { status: 'published' }
      }]
    });
    
  3. 索引优化
    // Sequelize示例
    User.init({
      email: {
        type: DataTypes.STRING,
        unique: true
      }
    }, { sequelize });
    

复杂查询示例

// TypeORM复杂查询
const users = await userRepository
  .createQueryBuilder("user")
  .leftJoinAndSelect("user.photos", "photo")
  .where("user.name = :name", { name: "John" })
  .andWhere("photo.isPublished = :isPublished", { isPublished: true })
  .orderBy("user.registrationDate", "DESC")
  .skip(10)
  .take(5)
  .getMany();

总结

JavaScript生态中的ORM框架各有特点,选择时应考虑:

  • 项目规模和技术栈
  • 数据库类型
  • 团队熟悉程度
  • 对TypeScript的支持需求
  • 长期维护性 现代JavaScript开发中,TypeORM和Prisma因其对TypeScript的良好支持和现代化特性而越来越受欢迎,而Sequelize则因其成熟稳定仍然在许多项目中广泛使用。









results matching ""

    No results matching ""