• Active Record 与 Data Mapper
    • 什么是Active Record模式?
    • 什么是Data Mapper模式?
    • 我应该选择哪一个?

    Active Record 与 Data Mapper

    什么是Active Record模式?

    在 TypeORM 中,你可以使用 Active Record 和 Data Mapper 模式。

    使用 Active Record 方法,你可以在模型本身内定义所有查询方法,并使用模型方法保存、删除和加载对象。

    简单来说,Active Record 模式是一种在模型中访问数据库的方法。 你可以在Wikipedia上查看有关 Active Record 模式的更多信息。

    例如:

    1. import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from "typeorm";
    2. @Entity()
    3. export class User extends BaseEntity {
    4. @PrimaryGeneratedColumn()
    5. id: number;
    6. @Column()
    7. firstName: string;
    8. @Column()
    9. lastName: string;
    10. @Column()
    11. isActive: boolean;
    12. }

    所有 active-record 实体都必须扩展BaseEntity类,它提供了与实体一起使用的方法。

    以下示例展示如何使用此类实体:

    1. // 示例如何保存AR实体
    2. const user = new User();
    3. user.firstName = "Timber";
    4. user.lastName = "Saw";
    5. user.isActive = true;
    6. await user.save();
    7. // 示例如何删除AR实体
    8. await user.remove();
    9. // 示例如何加载AR实体
    10. const users = await User.find({ skip: 2, take: 5 });
    11. const newUsers = await User.find({ isActive: true });
    12. const timber = await User.findOne({ firstName: "Timber", lastName: "Saw" });

    BaseEntity具有标准Repository的大部分方法。 大多数情况下,你不需要将RepositoryEntityManager与 active record 实体一起使用。

    现在假设我们要创建一个按 first name 和 last name 返回用户的函数。 我们可以在User类中创建静态方法等函数:

    1. import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from "typeorm";
    2. @Entity()
    3. export class User extends BaseEntity {
    4. @PrimaryGeneratedColumn()
    5. id: number;
    6. @Column()
    7. firstName: string;
    8. @Column()
    9. lastName: string;
    10. @Column()
    11. isActive: boolean;
    12. static findByName(firstName: string, lastName: string) {
    13. return this.createQueryBuilder("user")
    14. .where("user.firstName = :firstName", { firstName })
    15. .andWhere("user.lastName = :lastName", { lastName })
    16. .getMany();
    17. }
    18. }

    并像使用其他方法一样使用它:

    1. const timber = await User.findByName("Timber", "Saw");

    什么是Data Mapper模式?

    在 TypeORM 中,您可以使用 Active Record 和 Data Mapper 模式。

    使用 Data Mapper 方法,你可以在名为”repositories”的单独类中定义所有查询方法,并使用存储库保存、删除和加载对象。 在数据映射器中,你的实体非常笨,它们只是定义了相应的属性,并且可能有一些很笨的方法。

    简单来说,数据映射器是一种在存储库而不是模型中访问数据库的方法。 你可以在Wikipedia上查看更多关于 data mapper 的信息。

    例如:

    1. import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
    2. @Entity()
    3. export class User {
    4. @PrimaryGeneratedColumn()
    5. id: number;
    6. @Column()
    7. firstName: string;
    8. @Column()
    9. lastName: string;
    10. @Column()
    11. isActive: boolean;
    12. }

    以下示例展示如何使用此类实体:

    1. const userRepository = connection.getRepository(User);
    2. // 示例如何保存DM实体
    3. const user = new User();
    4. user.firstName = "Timber";
    5. user.lastName = "Saw";
    6. user.isActive = true;
    7. await userRepository.save(user);
    8. // 示例如何删除DM实体
    9. await userRepository.remove(user);
    10. // 示例如何加载DM实体
    11. const users = await userRepository.find({ skip: 2, take: 5 });
    12. const newUsers = await userRepository.find({ isActive: true });
    13. const timber = await userRepository.findOne({ firstName: "Timber", lastName: "Saw" });

    现在假设我们要创建一个按 first name 和 last name 返回用户的函数。 我们可以在”custom repository”中创建这样的功能。

    1. import { EntityRepository, Repository } from "typeorm";
    2. import { User } from "../entity/User";
    3. @EntityRepository()
    4. export class UserRepository extends Repository<User> {
    5. findByName(firstName: string, lastName: string) {
    6. return this.createQueryBuilder("user")
    7. .where("user.firstName = :firstName", { firstName })
    8. .andWhere("user.lastName = :lastName", { lastName })
    9. .getMany();
    10. }
    11. }

    并以这种方式使用它:

    1. const userRepository = connection.getCustomRepository(UserRepository);
    2. const timber = await userRepository.findByName("Timber", "Saw");

    了解有关custom repositories的更多信息。

    我应该选择哪一个?

    决定取决于你。 这两种策略都有自己的缺点和优点。

    在软件开发中我们应该始终牢记的一件事是我们如何维护它。 Data Mapper方法可以帮助你保持软件的可维护性,这在更大的应用程序中更有效。 Active record方法可以帮助你保持简单,这在小型应用程序中运行更好。 简单性始终是提高可维护性的关键。