Open2
TypeORM 知見まとめ
TypeORMでSoft delete (論理削除)を実現する
前提 / 現状
- すべてのEntityは、下記BaseEntityクラスを継承することで、
created_at
,updated_at
,deleted_at
カラムを有している。BaseEntity.tsexport default abstract class BaseEntity { @CreateDateColumn({ type: "datetime" }) readonly created_at: Date; @Column({ type: "datetime", nullable: true, onUpdate: "CURRENT_TIMESTAMP" }) readonly updated_at: Date; @Column({ type: "datetime", nullable: true }) deleted_at: Date; }
- 基本的にレコードの削除はSoft deleteで行う方針で、TypeORMの削除処理の代わりに
someEntity.deleted_at = new Date();
なる処理を毎度書いている。
やりたいこと
- わざわざ
deleted_at
カラムに値を代入する処理を書かずとも、Soft deleteを一発で実施したい。
解決策
TypeORMにはSoft deleteの機能が組み込まれているっぽい。
BaseEntity.ts
export default abstract class BaseEntity {
@CreateDateColumn({ type: "datetime" })
readonly created_at: Date;
@UpdateDateColumn({ type: "datetime", nullable: true })
readonly updated_at: Date;
@DeleteDateColumn({ type: "datetime", nullable: true }) // 削除日時を自動代入
readonly deleted_at: Date;
}
Soft delete処理
const deletedRecords = someEntity.find(/* 省略 */); // 削除するレコードを抽出
someEntity.softRemove(deletedRecords); // softRemoveだとrelation先のレコードも削除できる
TypeORM × MySQLでJSON型を使う
動機
- これまで、1カラムに複数の値を持たせたいとき、複数レコード作成することで対応していた。
- 例えば、会社テーブルで、会社毎の営業曜日を保持したいケース。
operatingDays = [1, 2, 3, 4, 5]
- 例えば、会社テーブルで、会社毎の営業曜日を保持したいケース。
- レコード数が多くなってしまうので、1会社1レコードにしたい。
- となると、JSON型で配列を保持すればよいのでは?
解決策
TypeORMでJSON型を指定すると、MySQLのJSON型でカラムが作成される。
(PostgresSQLのJSONB型も対応しているらしい)
Company.ts
export default class Company extends BaseEntity {
@Column({ type: "json" }) // JSON型を指定する
operating_days: number[]; // JSON構造の型で宣言すればOK
}
実際にデータを取り出すと、JSONがパースされて返ってくるので、 JSON.parse
などする必要は無い。
便利!