2019年5月31日金曜日

Node.jsでknex.jsを使ったSQL書き方Tips


オフィス狛 技術部のHammarです。

皆さんNode.jsとRDBを使って開発をされるときに、クエリビルダは何をお使いでしょうか?

以前にもブログで何度か書きましたが、弊社の一部プロジェクトではknex.jsというクエリビルダを使っています。

結構クセのある書き方ではじめは手こずりましたが、やはり人間慣れは重要で、今では意外と使いやすいなと思う部分も結構あります。
幅広いDBの種類に対応しているので、DBの種類によってインストールするモジュールを変える必要はなく、これ1つで同じ書き方ができるのでお勧めです。

ただあまり日本語の解説記事がないので、SQLの特殊な書き方をするときにどう書けばいいかわからなくて、ちょっとだけハマった事象について、自分への備忘録も兼ねて書こうと思います。

■基本的なSQL

例えば出身地、名前、年齢が登録されているテーブルがあったとして、下記のようなSQLでとあるデータを取得するとします。
    select
        name
    from users
    where
        birth_place = '東京都'
        and age >= '20';
これをnodeでknexを使って書くと(knexはrequire済みとします)
knex
    .select('name')
    .from('users')
    .where('birth_place', '東京都')
    .andWhere('age', '>=', '20')

という感じで基本的にはSQLの書き方に沿った感じで書くことが可能です。

基本的な書き方は公式リファレンスをみていただければほとんど大丈夫なのですが、公式にも詳しくのっていなかったりするものもあります。

■数値をプレースホルダにいれる場合

以前ブログにも書きました数値をプレースホルダにいれる場合、下記のように書きます。
狛ログ:knexライブラリのIN句でプレースホルダを使うときの注意点
const array = [1, 2, 3];
knex
    .select('name')
    .from('users')
    .whereRaw('id in (?)', [array]);

■from句でエイリアスを使いたい場合

knex
    .select('name')
    .from(users.clone().as('u'));
これはたとえばサブクエリでいろいろ結合した結果をセレクトしたいとき等で、別名にしたいときに利用できます。
const subQuery = サブクエリの内容
knex
    .select('sub_name')
    .from(subQuery.clone().as('sub'));

■order byで複数設定したい場合

通常のorder byの記述の方法で複数ソートしたいとき、公式の書き方だとちょっと面倒です。
    select *
    from users
    order by email asc, age desc
これをknexで書くと
knex
    .('users')
    .orderBy(['email', { column: 'age', order: 'desc' }])

上記でも全然問題ないんですが、ちょっとぱっと見わかりにくいのと、ソートが沢山あるとさらにわかりにくくなるので、下記のような書き方のほうがいいと思っています。
knex
    .('users')
    .orderByRaw('email asc, age desc');

このRawというのは基本的にそのままSQL文を記述が可能で、join句にもjoinRawというのがあったり、where句にもwhereRawというのあります。
select句にはselectRawみたいな書き方はないのですが、knex.raw()を使うことができ、例えば下記のようにselectにcase文を使いたい時など、select句で特殊なことをするときに使えます。
knex
    .select(
        'name',
        knex.raw('case when age >= 10 then categoryA else categoryB end as category'),
    )
    .from('users')
    .where('birth_place', '東京都')

で、knex.raw()はfrom句だろうが、where句だろうがどこにでも使えて、これを使うともはやknexの書き方に従わなくともSQLがそのまま書けますw
そこは臨機応変にだと思いますが、このように結構自由度も高いのでknexは個人的にはお勧めだと思います。

またtips的な事象が出てきたら書きたいと思います。

,

0 件のコメント:

コメントを投稿