5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MikroORMのはじめ方 - インストールからINSERTとSELECTまで

Last updated at Posted at 2021-02-22

この投稿は、TypeScript用ORMであるMikro ORMの初歩的なチュートリアルです。データベースはPostgreSQLを用います。

このチュートリアルで学べること

  • Mikro ORMのインストール方法
  • Mikro ORMの設定方法
  • Mikro ORMでのエンティティのINSERTSELECTのやり方

PostgreSQLを起動する

Mikro ORMは様々なデータベースに対応していますが、今回はPostgreSQLを使いたいので、PostgreSQLサーバーを起動しておきます。

PostgreSQLサーバーを起動するには、Dockerを使うのが手軽なので、それを使います。

docker-compose.ymlを用意します:

docker-compose.yml
version: '3.7'
services:
  db:
    image: postgres:11.3
    # Make postgres logs. More information about logging, see official documentation: https://www.postgresql.org/docs/11/runtime-config-logging.html
    command: postgres -c log_destination=stderr -c log_statement=all -c log_connections=on -c log_disconnections=on
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
    restart: always
    user: root
    logging:
      options:
        max-size: "10k"
        max-file: "5"

この設定では、Dockerホストからアクセスできるようにポート5432を開放します。PostgreSQLのユーザはtestにし、パスワードはtestにしてあります。commandにわちゃわちゃ書いてあるのはクエリーログを見れるようにするためのものです。

Docker ComposeでPostgreSQLサーバーを起動します:

docker-compose up

起動したらDockerホスト側からの接続テストを行います。接続テストにはpsqlコマンドを使います。このコマンドがMacOSに入っていない場合はbrew install postgresqlしてください。

PGPASSWORD=test psql \
    --host 127.0.0.1 \
    --port 5432 \
    --username test \
    --dbname test

このコマンドでプロンプトが立ち上がれば、接続OKです。

必要なパッケージをインストールする

必要なパッケージをインストールします。まず、TypeScriptは必須なので入れます。TypeScriptをコンパイルなしに実行したいので、ts-nodeも入れます。

yarn add -D typescript ts-node

次にMikro ORMのコアと、今回はデータベースはPostgreSQLを使うので、そのコネクターをインストールします。TypeScriptで定義したエンティティの型情報はしっかり認識させたいので、@mikro-orm/reflectionも入れておきます:

yarn add @mikro-orm/core @mikro-orm/postgresql @mikro-orm/reflection

Mikro ORMのCLIツールも入れます:

yarn add -D @mikro-orm/cli

Mikro ORMのCLIツールがインストールできているか確認します:

$ npx mikro-orm --version
4.4.4

TypeScriptのコンパイルオプションを設定する

Mikro ORMはデコレーターを使うので、TypeScriptのコンパイルオプションでそれを有効にします。

まず、TypeScriptの設定ファイルを生成します:

npx tsc -init

次に、デコレーター周りのオプションを有効化します:

tsconfig.json
{
  "compilerOptions": {
    /* ... */
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true
  }
}

Mikro ORMの設定ファイルを作る

データベースの接続情報などを書いておきます。

mikro-orm.config.ts
import { Options } from "@mikro-orm/core";
import { PostgreSqlDriver } from "@mikro-orm/postgresql";
import { TsMorphMetadataProvider } from "@mikro-orm/reflection";

const options: Options<PostgreSqlDriver> = {
  driver: PostgreSqlDriver,
  metadataProvider: TsMorphMetadataProvider,
  entities: ["./entities/*.js"],
  entitiesTs: ["./entities/*.ts"],
  clientUrl: "postgresql://test:test@127.0.0.1:5432/test",
};

export default options;

このファイルはMikro ORM CLIでデータベースを扱うときに使います。アプリ側からも同じ設定を使っていい場合は、このファイルをimportして流用できます。

metadataProviderはエンティティのメタデータをどの形式で書くかを決めるものです。Mikro ORMではいくつかの形式をサポートしていますが、TypeScriptの場合もっとも記述量が少なくて済むTsMorphMetadataProviderがオススメです。

entitiesTsでは、どのファイルにエンティティがあるかを指定します。これをヒントにMikro ORMはエンティティを探し出します。

clientUrlはデータベースの接続先URLです。設定ファイルでは、これをhost, port, user, password, dbNameに分解して書くこともできます。

Mikro ORM CLIはデフォルトだとTypeScriptで書いた設定ファイルmikro-orm.config.tsが認識できないので、package.jsonに下記の設定を加えておきます:

package.json
{
  /*...*/
  "mikro-orm": {
    "useTsNode": true,
    "configPaths": [
      "./src/mikro-orm.config.ts",
      "./dist/mikro-orm.config.js"
    ]
  }
}

エンティティを作る

Mikro ORMを動かすには、最低限1つ以上のエンティティが必要なので、試しにBookエンティティを作ります。エンティティはentitiesディレクトリを作り、そこに置くようにします。

entities/book.ts
import { Entity, PrimaryKey, Property } from "@mikro-orm/core";

@Entity()
export class Book {
  @PrimaryKey()
  id!: number;

  @Property()
  title!: string;
}

データベーススキーマを更新する

Bookのエンティティが準備できたら、このエンティティを保存するテーブルをデータベースに作るためにデータベーススキーマの更新をかけます。スキーマの更新にはMikro ORM CLIを使います。

いきなりスキーマ更新をかけてもいいですが、その前にどのようなSQLが実行されるのか確認しておきます:

npx mikro-orm schema:update --dump

このコマンドを実行すると、どのようにスキーマが更新されるかが分かります:

set names 'utf8';
set session_replication_role = 'replica';

create table "book" ("id" serial primary key, "title" varchar(255) not null);

set session_replication_role = 'origin';

更新内容が良さそうなので、このSQLを実行させます。

pnpx mikro-orm schema:update --run

psqlでデータベースのテーブルを確認してみると、テーブルが作られていることが分かります:

PGPASSWORD=test psql \
    --host 127.0.0.1 \
    --port 5432 \
    --username test \
    --dbname test \
    -c '\d'

出力結果:

            List of relations
 Schema |    Name     |   Type   | Owner
--------+-------------+----------+-------
 public | book        | table    | test
 public | book_id_seq | sequence | test
(2 rows)

エンティティの保存とロード

データベースの準備ができたので、エンティティの保存(INSERT)と、保存したエンティティのロード(SELECT)をやってみましょう。

main.tsというファイルを作り、次のようなコードを書きます:

main.ts
import { MikroORM } from "@mikro-orm/core";
import { Book } from "./entities/book";
import config from "./mikro-orm.config";

async function main() {
  // ORMの初期化
  const orm = await MikroORM.init(config);

  // Bookレポジトリを取得する
  const bookRepository = orm.em.getRepository(Book);

  // Bookエンティティを作る
  const newBook = new Book();
  newBook.title = "サバイバルTypeScript";

  // Bookエンティティを保存する
  await bookRepository.persistAndFlush(newBook);
  console.log({ newBook });
  //=> { newBook: Book { title: 'サバイバルTypeScript', id: 1 } }

  // 保存したBookエンティティを取り出す
  const books = await bookRepository.findAll();
  console.log({ books });
  //=> { books: [ Book { title: 'サバイバルTypeScript', id: 1 } ] }
}

main()
  .then(() => process.exit())
  .catch(console.error);

保存のメソッドがpersistAndFlushとなっていますが、Mikro ORMでは、保存予定のエンティティをマークする処理persistと実際にエンティティを保存する処理flushに分かれているためこのようなネーミングになっています。persistflushは別々に呼び出すことができます。persistAndFlushはそれら2つを一度に呼び出すためのショートカットです。このへんのメカニズムの詳細は公式ドキュメントを御覧ください: Working with Entity Manager | MikroORM

このスクリプトはTypeScriptで書いているので、ts-nodeで実行します:

pnpx ts-node main.ts

実行するとbookテーブルにエンティティが追加されます。

ORMの裏側で実行されたSQLは次の通りになります:

-- persitAndFlushの操作
BEGIN;
insert into "book" ("title") 
  values ('サバイバルTypeScript') returning "id";
COMMIT;

-- findAllの操作
select "e0".* from "book" as "e0";

以上でチュートリアルは完了です。このチュートリアルで作成したコードはGitHubにホスティングしてあります。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?