Express+MySQL+sequelizeでデータベース管理


Nodeにはrailsのようにデータベースを管理できるモジュールであるsequelizeがあります。
expressで開発をやっていると、railsがどれだけ便利だったのかを思い知らされますね笑

<h1>expressでアプリケーション開発</h1>

https://gist.github.com/mitsuruog/fc48397a8e80f051a145

ざっと説明すると、

```terminal
$ npm install -g express-generator
$ express --view=pug your-app-name
$ cd your-app-name
$ npm install
$ npm start
```

云々、ということです。

<h1>mysqlの導入</h1>

この前expressでpassport認証する際にmysqlを導入する内容を書いたのでそっちをみてみてください。
https://qiita.com/y4u0t2a1r0/items/db6c39e9dcea21f8e994
ググればすぐです。

<h1>sequelize</h1>

cliで利用するためにsequelize-cliをグローバルでインストールします。

```terminal
$ npm install -g sequelize-cli
$ npm install --save sequelize
```

仕事場の環境上、windowsで仮想環境(vagrant)を立ち上げて開発を行なっていたのですが、
windowsの場合、シンボリックリンクが貼れずにnpm installがうまくいかないことがあるので、
もしnpm installでエラーが発生したら、

```
$ npm install -g sequelize-cli --no-bin-links
$ npm install --save sequelize --no-bin-links
```

という感じで--no-bin-linksをつけてあげてください。
http://eiua-memo.tumblr.com/post/117361529158/npmvagrantvagrant%E3%81%AE%E5%85%B1%E6%9C%89%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E4%B8%8A%E3%81%A7npm

で、うまくインストールできたら、railsチックにデータベースを作成していきましょう！

```terminal
$ sequelize init
```

initしてあげると、アプリケーションのディレクトリに、
config, migration, model
の３つのディレクトリが作成されます。

migration, modelのディレクトリにはまだ何も入っていませんが、
configディレクトリ内にはconfig.jsonなるものがあります。

```config.json
{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}
```

こんな感じになっているので、利用する用途に合わせて、
mysqlのパスワードや利用するデータベースの名前（任意）、ホスト（ローカルホストならlocalhost）を書いてあげます。

　まずはデータベースを作成しましょう。

```terminal
$ sequelize db:create
```

これで先ほどconfig.jsonに書き込んだdatabaseを作成します。
次のコマンドたちもよく使いますのでメモ。

```terminal
$ sequelize db:drop # dbを落とす
$ sequelize db:create # dbを作成
$ sequelize db:migrate # migrate実行
$ sequelize db:migrate:undo:all # 実行されたmigrateを全て取り消し
$ sequelize db:seed:all # 設定されていたseedファイルをmigrate
$ seqeulize db:seed:undo:all # seedファイルのmigrateを全て取り消し
```

次に、例としてusername(type=string), age(type=integer)のカラムを持つuserテーブルを作成します。

```terminal
$ sequelize model:create --underscored --name user --attributes "user_name:string,age:integer"
```

railsみたいにmodelを作成できて、最初感動しました笑
ですが、sequelizeではrailsのように外部キーなどをcli上で指定することはないっぽいです。
基本的にmodel:createで作成されるmigrationファイルに外部制約などを設定してdb:migrateする感じですね。

```app/migrations/migration_file.js
user_id: {
  allowNull: false,
  references: {
    model: 'users',
    key: 'id'
  },
  type: Sequelize.INTEGER
}
```

上のコードはuserの子テーブルに定義されたuser_idカラムの設定を想定しています。
references:{}の中に親のmodelとその参照するkeyを設定します。

associationについて、公式で色々読めるので細かいところはそっちを参考にしてみてください。
http://docs.sequelizejs.com/manual/tutorial/associations.html

多対多のテーブルを作成する場合も、

```terminal
$ sequelize model:create --underscored --name communities_users --attributes "community_id:integer, user_id:integer"
```

このように外部キーであるカラムを用意しておいて、migrationファイル内にreferencesを設定していきます。
（例としてusersを複数要するcommunitiesとcommunitiesを複数要するusersの中間テーブルを考えています）
modelにも、hasManyやbelongsToなどを定義してあげれば良いです。
中間テーブルの場合throughで関係を持たせてあげればオッケーです。

この点も公式のassociationの項目を参考にしてみてください。
http://docs.sequelizejs.com/manual/tutorial/associations.html#belongsto


<h1>sequelizeでCRUD</h1>
mysqlをexpressで使うと、

```app.js
let mysql = require('mysql2');
let connection = mysql.createConnection(
  host: 'localhost',
  user: 'root',
  password: '********',
  database: 'testdb'
});

connection.query('select * from users;', function(err, users) {
  console.log(users); // queryの結果が返ってくる
}
```

みたいな感じのを書いて、
select, insert, update, deleteを行うことになりますが、
sequelizeではこのようになります。↓

```app.js
let db = require('./models/index'); // cliでinitした時に作成されるmodels配下のindex.js

// findAll
db.users.findAll({}).then((instances) => { // usersのところが自分で作成したモデル
  console.log(instances); // usersの中身を全て取得した結果
});

// create
db.users.create({
  username: '#####',
  email: '#####@#####'
}).then((createdUser) => {
  console.log(createdUser); // 作成されたuserインスタンスの詳細
});
```

こんな感じでデータベース内の要素を全取得したり、作成保存したり、更新削除することができます。

ajaxでフロントからデータを飛ばして、

```front.js
$.ajax({
  url: 'users/new',
  type: 'post'
}).done((data) => { // data = サーバーから返ってきたデータ
  console.log(data);
}).fail((err) => {
  console.log(err);
});
```

```app.js
router.post('/new', function(req, res, next) {
  db.users.create({
    username: '#####',
    email: '#####@#####'
  }).then((createdUser) => {
    res.send(createdUser); // ajaxのdoneにdataを渡す
  }).catch((err) => {
    res.status(500).send(err);
  });
});
```

こんな感じにサーバーでデータベースを更新するっていうのが基本的な使い方でしょうか。

適当に作ったリポジトリがあるので、参考になれば、、、
https://github.com/yutaro1204/saya-akane

<img width="1436" alt="Screen Shot 2018-08-03 at 1.11.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/245704/2e9e1de9-164a-7dc6-c225-8c535329a484.png">