node.js超入門ノート6(データベース CRUD編)

# 準備
viewsフォルダの中にhelloフォルダを作成します。
その後hello.ejsをhelloフォルダに移動し、index.ejsに名前を変更します。
hello.jsを以下のように修正します。

```javascript:routes/hello.js
// 変更前
res.render('hello', data);
// 変更後
res.render('hello/index', data);
```

# レコードの新規作成
以下のファイルを追加します。

```javascript:views/hello/add.ejs
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="content-type" content="text/html">
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css" />
    </head>

    <body class="container">

        <header>
            <h1 class="display-4">
                <%= title %>
            </h1>
        </header>
        <div role="main">
                <p><%- content %></p>
                <form action="/hello/add" method="post">
                    <div class="form-group">
                        <label for="name">NAME</label>
                        <input type="text" name="name" id="name" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="mail">MAIL</label>
                        <td><input type="text" name="mail" id="mail" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="age">AGE</label>
                        <td><input type="number" name="age" id="age" class="form-control">
                    </div>
                    <input type="submit" value="作成" class="btn btn-primary">
                </form>
        </div>
    </body>
</html>
```

次に/addの処理を作成します。

```javascript:routes/hello.js
const express = require('express');
const router = express.Router();

const sqlite3 = require('sqlite3');

// データベースオブジェクトの取得
const db = new sqlite3.Database('mydb.sqlite3');

router.get('/', (req, res, next) => {
    db.serialize(() => {
        var rows = "";
        db.each("select * from mydata", (err, row) => {
            // データベースアクセス完了時の処理
            if (!err) {
                rows += "<tr><th>" + row.id + "</th><td>" + row.name + "</td><td></tr>";
            }
        }, (err, count) => {
            if (!err){
                var data = {
                    title: 'Hello!',
                    content: rows // 取得したレコードデータ
                };
                res.render('hello/index', data);
            }
        });
    });
});

router.get('/add', (req, res, next) => {
    var data = {
        title: 'Hello/Add',
        content: '新しいレコードを入力：'
    }
    res.render('hello/add', data);
});

router.post('/add', (req, res, next) => {
    const nm = req.body.name;
    const ml = req.body.mail;
    const ag = req.body.age;
    db.serialize(() => {
        // ?(プレースホルダ)の位置に値が代入されます。
        // runはデータベースから取り出す必要のない処理で使います。
        db.run('insert into mydata (name, mail, age) values (?, ?, ?)', nm, ml, ag);
    });
    res.redirect('/hello');
});

module.exports = router;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/b578a0cc-15cd-e62f-87d8-4c6990b5eb10.png)

以下のURLからデータの新規作成ができます。

http://localhost:3000/hello/add

# レコードの表示
helloフォルダに以下のファイルを追加します。

```html:views/hello/show.ejs
<!DOCTYPE html>
<html lang="ja">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="content-type" content="text/html">
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css" />
    </head>

    <body class="container">
        <header>
            <h1 class="display-4">
                <%= title %>
            </h1>
        </header>
        <div role="main">
            <p><%- content %></p>
            <table class="table">
                <tr>
                    <th>ID</th>
                    <td><%= mydata.id %></td>
                </tr>
                <tr>
                    <th>NAME</th>
                    <td><%= mydata.name %></td>
                </tr>
                <tr>
                    <th>MAIL</th>
                    <td><%= mydata.mail %></td>
                </tr>
                <tr>
                    <th>AGE</th>
                    <td><%= mydata.age %></td>
                </tr>
            </table>
        </div>
    </body>
</html>
```
hello.jsに以下の処理を追加します。

```javascript:routes/hello.js
router.get('/show', (req, res, next) => {
    const id = req.query.id;
    db.serialize(() => {
        const q = "select * from mydata where id = ?";
        // 第2引数は?に渡す値
        db.get(q, [id], (err, row) => {
            if (!err) {
                var data = {
                    title: 'Hello/show',
                    content: 'id = ' + id + ' のレコード：',
                    mydata: row
                }
                res.render('hello/show', data);
            }
        });
    });
});
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/dbe07afd-6a6e-4846-fe9f-ccc649d8d52e.png)

以下のURLにアクセスする事で指定したデータを表示できます。
※id=の後に表示したいデータidを指定します。

http://localhost:3000/hello/show?id=1

# レコードの編集
edit.ejsを追加します。

```html:views/hello/edit.ejs
<!DOCTYPE html>
<html lang="ja">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="content-type" content="text/html">
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css" />
    </head>

    <body class="container">

        <header>
            <h1 class="display-4">
                <%= title %>
            </h1>
        </header>
        <div role="main">
                <p><%= content %></p>
                <form action="/hello/edit" method="post">
                    <input type="hidden" name="id" value="<%= mydata.id %>">
                    <div class="form-group">
                        <label for="name">NAME</label>
                        <input type="text" name="name" id="name" class="form-control" value="<%= mydata.name %>">
                    </div>
                    <div class="form-group">
                        <label for="mail">MAIL</label>
                        <td><input type="text" name="mail" id="mail" class="form-control" value="<%= mydata.mail %>">
                    </div>
                    <div class="form-group">
                        <label for="age">AGE</label>
                        <td><input type="number" name="age" id="age" class="form-control" value="<%= mydata.age %>">
                    </div>
                    <input type="submit" value="更新" class="btn btn-primary">
                </form>
        </div>
    </body>
</html>
```
次に処理を追加します。

```javascript:routes/hello.js
router.get('/edit', (req, res, next) => {
    const id = req.query.id;
    db.serialize(() => {
        const q = "select * from mydata where id = ?";
        db.get(q, [id], (err, row) => {
            if (!err) {
                var data = {
                    title: 'Hello/edit',
                    content: 'id = ' + id + ' のレコードを編集：',
                    mydata: row
                }
                res.render('hello/edit', data);
            }
        });
    });
});

router.post('/edit', (req, res, next) => {
    const id = req.body.id;
    const nm = req.body.name;
    const ml = req.body.mail;
    const ag = req.body.age;
    // idはuniqueなので指定したデータ一つだけ変更されます。
    const q = "update mydata set name = ?, mail = ?, age = ? where id = ?";
    db.serialize(() => {
        db.run(q, nm, ml, ag, id);
    });
    res.redirect('/hello');
});
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/be297d67-0959-0382-a7f0-44ec997d9491.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/4a6ab583-b201-38cf-3dec-814e6e97cefe.png)
以下のURLから編集が行えます。

http://localhost:3000/hello/edit?id=1

# レコードの削除

以下のファイルを作成します。

```html:views/hello/delete.ejs
<!DOCTYPE html>
<html lang="ja">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="content-type" content="text/html">
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css" />
    </head>

    <body class="container">
        <header>
            <h1 class="display-4">
                <%= title %>
            </h1>
        </header>
        <div role="main">
            <p><%= content %></p>
            <table class="table">
                <tr>
                    <th>NAME</th>
                    <td><%= mydata.name %></td>
                </tr>
                <tr>
                    <th>NAIL</th>
                    <td><%= mydata.mail %></td>
                </tr>
                <tr>
                    <th>AGE</th>
                    <td><%= mydata.age %></td>
                </tr>
            </table>
                <form action="/hello/delete" method="post">
                <input type="hidden" name="id" value="<%= mydata.id %>">
                <input type="submit" value="削除" class="btn btn-primary">
            </form>
        </div>
    </body>
</html>
```
以下を追記します。

```javascript:routes/hello.js
router.get('/delete', (req, res, next) => {
    const id = req.query.id;
    db.serialize(() => {
        const q = "select * from mydata where id = ?";
        db.get(q, [id], (err, row) => {
            if (!err) {
                var data = {
                    title: 'Hello/delete',
                    content: 'id = ' + id + ' のレコードを削除：',
                    mydata: row
                }
                res.render('hello/delete', data);
            }
        });
    });
});

router.post('/delete', (req, res, next) => {
    const id = req.body.id;
    db.serialize(() => {
        const q = "delete from mydata where id = ?";
        db.run(q, id);
    });
    res.redirect('/hello');
});
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/3af72aaa-41e4-2200-36e7-fc8554a36b5a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/50647fd9-a205-34a1-93f3-c0868cd97b5e.png)
以下のURLにアクセスすると削除できます。

http://localhost:3000/hello/delete?id=3

# レコードの検索

```html:views/hello/find.ejs
<!DOCTYPE html>
<html lang="ja">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="content-type" content="text/html">
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css" />
    </head>

    <body class="container">

        <header>
            <h1 class="display-4">
                <%= title %>
            </h1>
        </header>
        <div role="main">
            <p><%= content %></p>
            <form action="/hello/find" method="post">
                <div class="form-group">
                    <label for="find">FIND</label>
                    <input type="text" name="find" id="find" class="form-control" value="<%=find %>">
                </div>
                <input type="submit" value="更新" class="btn btn-primary">
            </form>
            <table class="table mt-4">
                <% for(var i in mydata) { %>
                <tr>
                    <% var obj = mydata[i]; %>
                    <th><%= obj.id %></th>
                    <td><%= obj.name %></td>
                    <td><%= obj.mail %></td>
                    <td><%= obj.age %></td>
                </tr>
                <% } %>
            </table>
        </div>
    </body>
</html>
```
以下を追記します。

```javascript:routes/hello.js
router.get('/find', (req, res, next) => {
    db.serialize(() => {
        db.all("select * from mydata", (err, rows) => {
            if (!err) {
                var data = {
                    title: 'Hello/find',
                    find:'',
                    content: '検索条件を入力してください。',
                    mydata: rows
                };
                res.render('hello/find', data);
            }
        });
    });
});

router.post('/find', (req, res, next) => {
    const find = req.body.find;
    db.serialize(() => {
        var q = "select * from mydata where ";
        db.all(q + find, [], (err, rows) => {
            if (!err) {
                var data = {
                    title: 'Hello/find',
                    find: find,
                    content: '検索条件 ' + find,
                    mydata: rows
                }
                res.render('hello/find', data);
            }
        });
    });
});
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/8e4a408a-c174-a7b6-de5f-e6695458abe9.png)
上記の例は以下のSQLクエリーが実行されます。

```sql
select * from mydata where id = 5
```
以下のURLにアクセスすると検索できます。

http://localhost:3000/hello/find

https://qiita.com/Glider2355/items/7f4551c52b77131df6e8