LoginSignup
1
2

More than 5 years have passed since last update.

Node.js向けORM Objection.jsを使ってみた(3) - 基本的なクエリの発行方法について

Posted at

概要

データベースに対してクエリを発行する際は、QueryBuilderオブジェクトを使用します。

Modelのqueryメソッド(staticメソッド)を実行すると、QueryBuilderを取得できます。

メソッドチェーンによってクエリを構築していき、thenメソッドを実行すると、構築したクエリが実行されます。

const queryBuilder = Project.query();

queryBuilder.then(projects => console.log(projects));

// awaitでも実行可能
const projects = await queryBuilder.where('name', '=', 'hogepiyo');

Modelの定義についてはこちらを参照。

Fetch Queries

テーブルの全レコードを取得する

const projects = await Project.query();
// select "projects".* from "projects"

console.log(projects.every(project => project instanceof Project)); // true

指定したIDを保持するレコードを取得する

whereメソッドを使用して、返却されるレコードを制限できます。

const project = await Project.query().where({ id: 1 }).first();
// select "projects".* from "projects" where "id" = 1

console.log(project instanceof Project); // true

// 上記と同様のSQLを実行する
await Project.query().where('id', '=', 1).first();
await Project.query().where('id', 1).first()

// findByIdメソッドを使用することで、より簡潔に記述できる
await Project.query().findById(1);

複雑なクエリ

const tasks = await Task
  .query()
  .select('name', 'description')
  .where('deadline', '>=', new Date())
  .orWhere(function() {
    this
      .where('assignedTo', '=', 1)
      .andWhere('projectId', '=', 2);
  })
  .orderBy('deadline', 'asc');

// select "name", "description" from "tasks" where "deadline" >= '2018-08-19 01:43:33.853' or ("assignedTo" = 1 and "projectId" = 2) order by "deadline" asc

Insert Queries

レコードを作成する

const user = await User.query().insert({ name: 'fuga', email: 'fuga@example.com' });
// insert into "users" ("email", "name") values ('fuga@example.com', 'fuga') returning "id"

console.log(user); // User { name: 'fuga', email: 'fuga@example.com', id: 3 }

const users = await User.query().insert([
  { name: 'hoge', email: 'hoge@example.com' },
  { name: 'piyo', email: 'piyo@example.com' }
]);
// insert into "users" ("email", "name") values ('hoge@example.com', 'hoge'), ('piyo@example.com', 'piyo') returning "id"

console.log(users);
// [ User { name: 'hoge', email: 'hoge@example.com', id: 5 },
//   User { name: 'piyo', email: 'piyo@example.com', id: 6 } ]

作成されたレコードの全カラムを取得する

insertメソッドを実行すると、引数で指定したプロパティとプライマリキーのみが設定された状態でModelのインスタンスが返却されます。

カラムにデフォルト値を設定しているなどの都合で、すべてのカラムが必要な場合は、insertAndFetchメソッドを使用します。

const task = await Task.query().insert({ assignedTo: 1, projectId: 1, name: 'sample' });

console.log(task); // Task { assignedTo: 1, projectId: 1, name: 'sample', id: 1 }

const taskWithAllProps = await Task.query().insertAndFetch({ assignedTo: 1, projectId: 1, name: 'sample' });
// PostgreSQLであれば、
// `await Task.query().insert({ assignedTo: 1, projectId: 1, name: 'sample' }).returning('*')`
// でも可

console.log(taskWithAllProps);
// Task {
//   assignedTo: 1,
//   projectId: 1,
//   name: 'sample',
//   id: 2,
//   description: null,
//   deadline: null,
//   createdAt: 2018-08-18T17:18:12.358Z,
//   updatedAt: 2018-08-18T17:18:12.358Z }

Update Queries

特定のレコードを更新する

patchまたはupdateメソッドを使用することで、レコードの更新を行うことができます。

戻り値は、更新されたレコードの行数です。

patchとupdateは、ModelのjsonSchemaプロパティでrequiredと指定されたプロパティの扱いが異なります。

updateメソッドは、required指定されたプロパティが引数に指定されなかった場合、ValidationErrorを発生させます。

そのため、レコードの一部のカラムのみを更新する際はpatch、全カラムを更新する際はupdateを使うと良いと思います。

const num = await User.query().where({ id: 1 }).patch({ name: 'hoge' });
// update "users" set "name" = 'hoge' where "id" = '1'

console.log(num); // 1

// ModelのjsonSchemaプロパティでrequiredと指定したプロパティを省略すると、
// ValidationErrorが発生する
await User.query().where({ id: 1 }).update({ name: 'hoge' }));
// ValidationError: email: is a required property

更新後、最新レコードを取得する

patchAndFetchByIdまたはupdateAndFetchByIdメソッドを使用すると、

更新されたレコードの件数ではなく、更新後のレコードそのものを取得することができます。

const user = await User.query().patchAndFetchById(1, { name: 'piyo' });
// update "users" set "name" = 'piyo' where "users"."id" = '1'

console.log(user); // User { name: 'piyo', id: 1, email: 'taro@example.com' }

// PostgreSQLの場合は、`await User.query().patch({ name: 'piyo' }).where({ id: 1 }).returning('*')`でも可

Delete Queries

特定のレコードを削除する

deleteメソッドを使用します。

戻り値は、削除されたレコードの行数です。

const num = await User.query().delete().where({ id: 3 });
// delete from "users" where "id" = '3'

console.log(num); // 1

参考

1
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
1
2