2019-07-22に更新

挑め!node-mysql2の罠

mysql2 とは

MySQLのバージョンって8じゃないの?
今回扱うのはNodeJSでMySQLとの接続を扱うライブラリです。
Node-mysql2

migrate to mysql2

元々本家のmysqlライブラリを使っていたのですが、
古いcallbackをasync/awaitに書き換えるついでに
mysql2パッケージに移行することにしました。

主な実装の変更点

トランザクション

特に今回はinsertのロジックの実装の際にtransaction処理が必要になりました。
async/awaitで読みやすくします。(最後の全体のコード参照)

connection.query()からconnection.execute()へ

query()はSQLインジェクションができてしまうようです。

  • execute vs query

    Execute - no possibly sql injection

    query - possibly sql injection

戻り値の実装の変更

mysql2ではrowsfieldsというプロパティが返却されてくるので
コードを対応させます。従来のデータはrowsに入っています。

const [rows,fields] = await conn.execute(
                                                    query,
                                                    this.convertUndefToNull(params)
                                            )

mysql2はクエリにundefを渡してはいけない!

SQLのパラメータにundefinedを渡すと、mysql側で内部的にnullに変換してくれていた処理が、mysql2では明示的にnullを渡せと言われます。
変換するメソッドを作ります。

/**
     * paramに含まれるundefをnullに置き換えるメソッド
     * @param {any[]} param 
     */
    public convertUndefToNull(param){
        for(let i=0; i < param.length; i++){
            if(param[i] === undefined){
                param[i] = null
            }
        }
        return param
    }

全体のコード

public insertQuery(query:string,params:any[]){
        return new Promise(async(resolve,reject)=>{
            let conn = await pool.getConnection()
            try {
                await conn.beginTransaction();
                const [rows,fields] = await conn.execute(
                                                    query,
                                                    this.convertUndefToNull(params)
                                            )
                await conn.commit()
                console.log(rows)
                resolve(rows)                
            } catch (error) {
                await conn.rollback()
                reject(error)
            } finally{
                await conn.release()
            }
        })

    }

ckoshien

個人開発4年目。普段はアプリケーションエンジニア。 ReactJS/NodeJS/ReactNative/Java

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント