Node.js（データベースを用いたWebアプリケーション）

# プログラミングの勉強日記
2020年6月18日　Progate Lv.130
Node.jsⅡ,Ⅲ

##MySQL
　データベースを管理するツールである。Node.jsからMySQLを操作するには、Node.jsからMySQLに接続する。そのためにmysqlパッケージを利用する。

```:ターミナル
$npm install mysql
```

```javascript:app.js
//mysqlパッケージの読み込み
const mysql=require('mysql');
//接続情報をcreateConnectionメソッドを用いて定数connectionに代入
const connection=mysql.createConnection({
  //データベース名、パスワードなどを記述
});
```

##クエリの実行
　`connection.query('クエリ',クエリ実行後の処理)`と書くことで、Node.jsからデータベースに対してクエリを実行できる。
　クエリ実行後の処理は
　　第1引数のerror：クエリが失敗したときのエラー情報
　　第2引数のresults：クエリの実行後が入る

```javascript:app.js
connection.query(
  'SELECT * FROM items'
  (error,results)=>{
    console.log(results);
    res.render('index.ejs');
  }
);
```

```:ターミナル
[{id:1, name:'じゃがいも'},
 {id:2, name:'キャベツ'},
 {id:3, name:'にんじん'} ]
```

##取得した値の表示
　EJSはrenderメソッドから値を受け取ることができる。renderメソッドの第2引数に`{プロパティ:値}`と書くことで、EJS側に値を渡すことができる。

```javascript:app.js
app.get('/index', (req,res)=>{
  connection.query( 'SELECT * FROM items',
    (error,results)=>{
      res.render('index.ejs',{items:results}); //オブジェクトを渡す
    }
  );
};
```
　`{items:results}`はオブジェクトを渡しているので、配列resultsから1件目の要素を取り出すときは、res.render('index.ejs',{items:results[0]});`とする。

```index.ejs
<% items.forEach((item)=>{ %>
```

##postメソッド
　URLに対応する処理（ルーティング）を行う。getメソッドと同様の形で行う。

```javascript:app.js
app.post('/create', (req,res)=>{
  //処理
});
```

<font color=blue>getとpostの使い分け</font>
　getメソッド：ファイルを画像に表示したいときに使う
　postメソッド：データベースを変更したいときに使う

##フォームの作成
　フォームを作るときはHTMLの`<form>`タグを使う。action属性には送信先のURLをmethod属性にはpostかgetを指定する。

```new.ejs
<form action="/create" method="post">
  <input type="text">
  <input type="submit" values="作成する">
</form>
```

##フォームの値の受け取り
　input要素にname属性を指定すると、オブジェクトの形で情報がサーバーに送信される。サーバー側では`req.body.name`属性の値でフォームの値を取得できる。

```new.ejs:name属性を指定する
<input type="text" name="itemName">
```

```javascript:app.js
//フォームの値を受け取るために必要な典型文
app.use(express.urlencoded ({express:false}));
app.post('/create', (req,res)=>{
  console.log(req.body.itemName); //フォームの値を取得
});
```

##データベースへの追加
　SELECTと同様にqueryメソッドを使うことで、INSERTを実行できる。
<img width="364" alt="node3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/06a67169-625f-28b5-5987-ecaef301a02f.png">


```javascript:app.js
connection.query(
  //idカラムはAUTO INCREMENTが実行されるので不要。
  'INSERT INTO items (name) VALUE ("とまと")',
  (error,results)=>{
  ...
```

```javascript:app.js(フォームからの値をクエリに使う)
connection.query(
  'INSERT INTO items (name) VALUE (?)', //配列の値が?に入る
  [req.body.itemName], 
  (error,results)=>{
  ...
```

##リダイレクト
　サーバーは次に指定するURLをレスポンスすることができる。このレスポンスを受け取ったブラウザは指定されたURLにリクエストをする。このように別のURLに再度リクエストされる仕組みのこと。ユーザが移動前のページを訪れたときに、自動的に転送後のページへ転送する仕組みのこと。

###リダイレクト後のリロード
　リダイレクトを用いると追加処理後に`/index`にリクエストして、一覧画面を表示することができる。よって、INSERTした後にリロードしても追加処理が実行されないのでさらにINSERTで増えることはない。

###リダイレクトの使い方
　リダイレクトをするには、`res.redirect`メソッドを使って引数にURLを指定する。<font color=blue>POSTのときはリダイレクトを使う。（getのルーティングにリダイレクトとする）</font>


```javascript:app.js
//INSERTした後に`/index`（一覧画面）にリダイレクトする
app.post('/create', (req,res)=>{
  connection.query(
    'INSERT INTO items (name) VALUES (?)'
    [req.body.itemName],
    (error,results)=>{
      res.redirect('/index'); //URLを指定してリダイレクトする
    }
  );
});
```

##idの受け渡し
　データベースを削除や更新するときにはWHEREでidを指定する必要がある。このidを受け渡すにはURLを利用する。URLには`/delete/id:3`のようにidを含めるようにして、ルーティングのURLは`/delete/:id`のように指定する。この`/:id`の部分を<font color=orange>ルートパラメータ</font>という。

```:index.ejs
<form action="/delete/<%= item.id %>" method="post">
  <input type="submit" value="削除">
</form>
```
　`<%= item.id %>`とすることで送信先URLにidを含める。

```javascript:app.js
app.post('/delete/:id', (req,res)=>{
  console.log(req.params.id);
  res.redirect('/index');
});
```
　`req.params.パラメータ名`でルートパラメータの値を受け取れる。<font color=blue>idはルートパラメータとparamsで受け渡す。更新する値はフォームとbodyで受け渡す</font>


###クエリの実行

```javascript:app.js
connection.query(
  'DELETE FROM items WHERE id=?',
  [req.params.id],
  (error,results)=>{
    res.redirect('/index');
  }
);
```