はじめに
express.jsとリレーショナルDBを組み合わせる際のORMは長らくsequelize一強だったみたいですが、
ここに来てより洗練されたTypeORMというORMが台頭してきたので、PJへの組み込み方をば。
あ、TypeORMという名前ですが、JavaScript (ES7, ES6, ES5)もサポートしています。
typescript使わないよーという人もsequelizeと比較してみて良さげなら導入すると良いと思います。
紹介
TypeORMを使って開発すると、
- PythonのSQLAlchemyのようなRepositoryパターン、
- RailsのようなActiveRecordパターン
のどちらの方式でも書くことができます。
また、モデルの定義をしっかり書けば型の恩恵を最大限受けられたり、
複雑なリレーションを組めたり、migration世代管理できたり
各種機能が高水準でまとまっています。
Repository パターン例
モデルはこんな感じ。デコレーターでDBカラムの情報を定義します。
デコレーターにオプションオブジェクトを渡すことで様々な設定ができます。
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 255 })
firstName: string;
@Column({ type: 'varchar', length: 255, nullable: true })
lastName: string;
@Column({ type: 'int' })
age: number;
}
ドメインロジックはこんな感じ。
const user = new User();
user.firstName = "Timber";
user.lastName = "Saw";
user.age = 25;
await repository.save(user);
const allUsers = await repository.find();
const firstUser = await repository.findOne(1); // find by id
const timber = await repository.findOne({ firstName: "Timber", lastName: "Saw" });
await repository.remove(timber);
ActiveRecord パターン例
モデルはこんな感じ。継承元クラスが違うだけで、Repositoryパターンとほとんど同じです。
import {Entity, PrimaryGeneratedColumn, Column, BaseEntity} from "typeorm";
@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 255 })
firstName: string;
@Column({ type: 'varchar', length: 255, nullable: true })
lastName: string;
@Column({ type: 'int' })
age: number;
}
ドメインロジックはこんな感じ。
モデル自身に生えたsaveやdeleteメソッドを使います。
Rails使いならこっちのほうがしっくりきますね。
const user = new User();
user.firstName = "Timber";
user.lastName = "Saw";
user.age = 25;
await user.save();
const allUsers = await User.find();
const firstUser = await User.findOne(1);
const timber = await User.findOne({ firstName: "Timber", lastName: "Saw" });
await timber.remove();
使い方
長くなったので別記事にしました。
Typescript + TypeORMセットアップ & migration世代管理 & expressへの組み込み