🐕
typeormに中間テーブルを挿入する方法(ManyToManyを使わない)
概要
typeorm で中間テーブルを手動で作成する方法についてまとめます。
ManyToMany が自動生成されるので、あまり意味がなかったりしますが、気になったので調べました。
ソースコードは以下になります。
実装方法
typeorm、docker-compose を使います。
若干異なりますが、環境構築の方法と、typeorm の設定方法、ormconfig.json
をormconfig.ts
にする方法は以下の記事を参考にしてください。
テーブル定義
以下はUser
エンティティとWork
エンティティです。
多対多ですので、中間テーブルが必要です。
User
エンティティ。
src/entity/User.ts
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column()
age: number;
}
Work
エンティティ。
src/entity/Work.ts
import { Column, Entity, PrimaryGeneratedColumn, Unique } from "typeorm";
@Entity()
@Unique(["title"])
export class Work {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
body: string;
}
以下は、中間テーブルのUserWork
エンティティです。
typorm の中間テーブルを定義しています。
UserWork
エンティティ。
src/entity/UserWork.ts
import { Entity, ManyToOne, JoinColumn, PrimaryColumn } from "typeorm";
import { User } from "./User";
import { Work } from "./Work";
@Entity()
export class UserWork {
@PrimaryColumn()
user_id: number;
@PrimaryColumn()
work_id: number;
@ManyToOne(() => User, (user) => user.id, {
onDelete: "CASCADE",
})
@JoinColumn({ name: "user_id" })
public user!: User;
@ManyToOne(() => Work, (work) => work.id, {
onDelete: "CASCADE",
})
@JoinColumn({ name: "work_id" })
public work!: Work;
}
動作確認
./src/index.ts
に DB への接続とデータの挿入を定義しています。
./src/index.ts
import "reflect-metadata";
import { createConnection } from "typeorm";
import { User } from "./entity/User";
import { Work } from "./entity/Work";
import { UserWork } from "./entity/UserWork";
createConnection()
.then(async (connection) => {
console.log("Inserting a new user into the database...");
const user1 = new User();
user1.firstName = "hoge";
user1.lastName = "hoge";
user1.age = 25;
await connection.manager.save(user1);
const user2 = new User();
user2.firstName = "fuga";
user2.lastName = "fuga";
user2.age = 25;
await connection.manager.save(user2);
const user3 = new User();
user3.firstName = "piyo";
user3.lastName = "piyo";
user3.age = 35;
await connection.manager.save(user3);
console.log("Inserting a new work into the database...");
const work1 = new Work();
work1.title = "フロント";
work1.body = "運用";
await connection.manager.save(work1);
const work2 = new Work();
work2.title = "バックエンド";
work2.body = "API作成";
await connection.manager.save(work2);
const work3 = new Work();
work3.title = "DB";
work3.body = "ER設計";
await connection.manager.save(work3);
console.log("Inserting a new userWork into the database...");
const userWork1 = new UserWork();
userWork1.user_id = 1;
userWork1.work_id = 1;
await connection.manager.save(userWork1);
const userWork2 = new UserWork();
userWork2.user_id = 1;
userWork2.work_id = 2;
await connection.manager.save(userWork2);
const userWork3 = new UserWork();
userWork3.user_id = 2;
userWork3.work_id = 1;
await connection.manager.save(userWork3);
const userWork4 = new UserWork();
userWork4.user_id = 3;
userWork4.work_id = 3;
await connection.manager.save(userWork4);
console.log("Here you can setup and run express/koa/any other framework.");
})
.catch((error) => console.log(error));
ts-node ./src/index.ts
で実行すると、データの挿入が完了します。
ts-node ./src/index.ts
DB を確認すると、中間テーブルが生成されたため、リレーションがとれていることがわかります。
mysql -u root --port 3306 -h 127.0.0.1 -D typeorm_db -e 'SELECT * FROM user; SELECT * FROM work; SELECT * FROM user_works;' -p
+----+-----------+----------+-----+
| id | firstName | lastName | age |
+----+-----------+----------+-----+
| 1 | hoge | hoge | 25 |
| 2 | fuga | fuga | 25 |
| 3 | piyo | piyo | 35 |
+----+-----------+----------+-----+
+----+--------------------+-----------+
| id | title | body |
+----+--------------------+-----------+
| 1 | フロント | 運用 |
| 2 | バックエンド | API作成 |
| 3 | DB | ER設計 |
+----+--------------------+-----------+
+---------+---------+
| user_id | work_id |
+---------+---------+
| 1 | 1 |
| 2 | 1 |
| 1 | 2 |
| 3 | 3 |
+---------+---------+
参考
Discussion