【node.js】bookshelfとknexを使ってCRUD操作

expressを使ったbookshelfの操作方法について書かれております。
#Bookshelfとは
SQLを使わずデータベースを使うことができるORM

>Bookshelfは、 Knex SQLクエリビルダー上に構築されたNode.js用のJavaScript ORMです。 Promiseベースのコールバックインターフェイスと従来のコールバックインターフェイスの両方、トランザクションサポート、eager / nested-eagerリレーションのロード、ポリモーフィックな関連付け、1対1、1対多、および多対多のリレーションのサポートを備えています。
PostgreSQL、MySQL、SQLite3で動作するように設計されています。

#knexとは
>Bookshelfは、内部で「クエリービルダー」と呼ばれるknexモジュールを利用しています。ですから、インストールの際には、まずknexを入れておく必要があります。

良く分からないけど、Bookshelfを使う際にはついてくる物らしい。。。

#モジュールのインストール

```bash

npm install --save knex
```

```bash

npm install --save bookshelf
```

#Bookshelfの初期設定

```javascript

var knex = require('knex')({
    client: 'mysql',
    connection: {
        host    : '127.0.0.1',
        user    : 'root',
        password: '',
        database: 'データベース名',
        charset : 'utf8'
    }
});

var Bookshelf = require('bookshelf')(knex);

var Mydata = Bookshelf.Model.extend({
    tableName: 'Mydata(テーブル名)'
});
```

上記のコードで行っている事は、
knexのロード、
knexの初期設定、
Bookshelfのロード、
モデルの作成

>###モデルとは？
テーブルにアクセスするオブジェクトです。
これを使って、テーブルのデータをCRUD操作します。

###モデルの項目追加
| hasTimestamps:true        |タイムスタンプのデータをレコードに追加する |    
|:-----------------|------------------:|
| user: function() {return this.belongsTo(テーブル名) |他のテーブルの値を取得可能にする |   

これでBookshelfの初期設定は完了しました。
いよいよ、CRUD操作をしていきます。

#Bookshelfのメソッド
Bookshelfで操作する際に使用するメソッドです。使いながら覚えていきましょう。

| fetchAll         |全てのレコードを取得する物 |    
|:-----------------|------------------:|
| then             |データベースアクセス完了後の処理をコールバック関数として設定します。 |   
|catch             |thenを実行した時にエラーが発生した時の処理です。|
|save              |オブジェクトの引数をテーブルに保存する処理をします。|
|where| 検索する対象に条件を設定して絞り込む|
|fetch| 最初の一つだけレコードを取り出す。|
|fetchPage|得られたページ番号を元にレコードを取り出します。|
|orderBy|レコードを並べ変える。|
|query|複数項目をチェックすする|


#レコードを取り出す

##全レコードを取り出す
```JavaScript
new Mydata().fetchAll().then((collection) => {
  -----取得できた場合の処理-----
}).catch((err) => {
  -----エラー発生時の処理-----
});
```

##レコードを保存する
新しいレコードの追加をしていきます。

```javascript
router.post('/add', (req, res, next) => {
  new Mydata(req.body).save().then((model) => {
    ー追加した後の操作ー
  });
});
```

##検索

```javascript
router.post('/', (req, res, next) => {
  new Mydata().where('id', '=', req.body.fstr).fetch().then((collection) => {
    取得後の操作
  }
}
```

##レコードを並べかえる
```javascript
router.get('/:page', (req, res, next) => {
  new Message().orderBy('created_at', 'DESC').fetchAll().then((collection) => {
    取得後の操作
  });
})
```

####orderByについて
第一引数にフィールド名、第二引数には「ABC」「DESC」の何かを指定します。
(DESCなら降順、ABCなら逆順)

##複数項目をチェックする
```javascript
router.post('/', (req, res, next) => {
  var nm = req.body.name;
  var pw = req.body.password;
  Mydata.query({where: {name: nm}, andWhere: {password: pw}})
    .fetch()
    .then((model) => {
      取得後の操作
    }）
}）
```

####関数query()に関して

| where:{name: nm}        |nameの値が変数nmである |    
|:-----------------|------------------:|
| andWhere:{password: pw}           |それに加えて、passwordの値が変数pwである |   

##ページネーション
Bookshelfを使う事で、ページネーションも使えるようになります。

```javascript
router.get('/:page', (req, res, next) => {
  var pg = req.params.page;
  pg *= 1;
  if(pg < 1){pg = 1; }
  new MyData().fetchPage({page:pg, pageSize:3}).then((collection) => {
    取得した後の操作
  })
  .catch((err) => {
    エラーを取得した後の操作
  }
}
```

####関数.fetchPageに関して

|page     |現在のページ番号 |    
|:-----------------|------------------:|
| pageCount |ページ数（最後のページのページ番号）|   
|pageSize|1ページ辺りのレコード数|
|rawCount|レコードの総数|



#参考
node.js超入門第2版 

Bookshelfとは
https://bookshelfjs.org/

paginationプラグイン
https://github.com/bookshelf/bookshelf/wiki/Plugin:-Pagination