8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ExpressでCRUDアプリ(メモアプリ)を作る

Last updated at Posted at 2020-08-28

Expressで基本的なCRUDアプリを作成する際の手順をまとめました。
DBにはMySQLを使います。

対象読者

初めてExpressを触る方

使用したバージョン

macOS Catalina 10.15.4
node:v12.14.0
MySQL:v8.0.19
Express:v4.17.1

MySQLを使う準備

自前のMacにMySQLが入っていない場合、MySQLをhomebrew経由でインストールする。
brew install mysql

// 起動
mysql.server start

// 停止
mysql.server stop

//ステータス確認
mysql.server status

// バージョン確認
mysqld --version

*MySQLのバージョンが8以上の場合、node.jsからMySQLへの接続時エラーが出るため以下のページを参考にすると良いです。
[Express.js(node.js)からMySQLへの接続とCRUD操作 | アールエフェクト] (https://reffect.co.jp/node-js/express-js-connect-mysql#MySQL)

プロジェクト作成〜Hello Worldまで

適当なディレクトリを作ってnpm init -yでプロジェクトを作成。
npm install expressでexpressインストール
npm install mysqlでmysqlインストール
npm install ejsでejsインストール
###DB作成
create-database.jsを作成し、以下を記述します。

create-database.js
const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',//mysqlと合わせる
  password: '',//mysqlと合わせる
});

//mysqlに接続してデータベース作成(成功するとconsoleに'database created'と出る)
connection.connect(function(err) {
    if (err) throw err;
    console.log('Connected');
    connection.query('CREATE DATABASE express_db', function (err, result) {
    if (err) throw err; 
      console.log('database created');
    });
});

※mysqlはmysql.server startのコマンドで立ち上げておきます。
node create-database.jsを実行するとDBが作成されます。

###テーブル作成
create-table.jsを作成し、以下を記述します。

create-table.js
const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',//mysqlと合わせる
  password: '',//mysqlと合わせる
  database: 'express_db' //先ほど作成したDBの名前
});

//テーブルの作成
connection.connect(function(err) {
    if (err) throw err;
    console.log('Connected');
    const sql = 'CREATE TABLE items (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, title VARCHAR(255) NOT NULL, text VARCHAR(255) NOT NULL)';
    connection.query(sql, function (err, result) {  
    if (err) throw err;  
    console.log('table created');  
    });
});

node create-table.jsを実行するとitemsテーブルが作成されます。

###ローカルサーバーの設定

app.jsを作成し、以下を記述します。

app.js
const express = require('express');
const mysql = require('mysql');
const app = express();

app.use(express.static('public'));//静的配信のフォルダを指定
app.use(express.urlencoded({extended: false}));

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',//mysqlと合わせる
  password: '',//mysqlと合わせる
  database: 'express_db' //先ほど作成したDBの名前
});

//viewsディレクトリ以下のejsファイル認識させる
app.set('views', './views');
app.set('view engine', 'ejs');

//hello world
app.get("/", (req,res) => {
    res.send("Hello World");
});

app.listen(3000);//3000ポートでローカルサーバーたつ

node app.jsを実行するとローカルでサーバが立ちます。
localhost:3000にアクセスすると'Hello World'と表示されます。

CRUD

app.jsを編集し、基本的なCRUD機能を実装していきます。
※変更を加えた際は、ブラウザで確認する前に一度ctrl+Cでサーバーを停止させてから再度node app.jsを実行してください。

作成(create)

app.js
const express = require('express');
const mysql = require('mysql');
const app = express();

app.use(express.static('public'));
app.use(express.urlencoded({extended: false}));

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'express_db' 
});

//viewsディレクトリ以下のejsファイル認識させる
app.set('views', './views');
app.set('view engine', 'ejs');

//hello-world
app.get("/", (req,res) => {
    res.send("Hello World");
});

/* ============ここから追加============ */
//新規作成画面のルーティング
app.get('/new', (req, res) => {
    res.render('new.ejs');
});
//新規作成アクション
app.post('/create', (req, res) => {
connection.query(
    'INSERT INTO items (title, text) VALUES (?, ?)',
    [req.body.itemTitle, req.body.itemText],
    (error, results) => {
    res.redirect('/')//methodがpostのときはredirectを使う
    }
);
});
/* ============ここまで追加============ */

app.listen(3000);
views/new.ejs
<form action="/create" method="post">
    <input type="text" name="itemTitle">
    <input type="text" name="itemText">
    <input type="submit" value="作成する">
</form>

localhost:3000/newにアクセスすると、フォームが表示されるようになります。
「作成する」をクリックすると、DBにデータが保存されます。

一覧(read)

Hello Worldと表示させていた部分を投稿したデータが一覧表示されるようにします。app.jsを修正し、index.ejsを新規作成します。

app.js
const express = require('express');
const mysql = require('mysql');
const app = express();

app.use(express.static('public'));
app.use(express.urlencoded({extended: false}));

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'express_db' 
});

//viewsディレクトリ以下のejsファイル認識させる
app.set('views', './views');
app.set('view engine', 'ejs');

/* ============ここから変更============ */
//一覧画面のルーティング
app.get('/', (req, res) => {
    connection.query(
      'SELECT * FROM items',
      (error, results) => {
        res.render('index.ejs', {items: results});//itemというキーでviewにデータベースの中身を渡せる
      }
    );
  });
/* ============ここまで変更============ */

//新規作成画面のルーティング
app.get('/new', (req, res) => {
    res.render('new.ejs');
});
//新規作成アクション
app.post('/create', (req, res) => {
connection.query(
    'INSERT INTO items (title, text) VALUES (?, ?)',
    [req.body.itemTitle, req.body.itemText],
    (error, results) => {
    res.redirect('/')
    });
});

app.listen(3000);
views/index.ejs
<% items.forEach((item) => { %>
 <li>
  <div>
   <span><%= item.title %></span>
   <span><%= item.text %></span>
  </div>
 </li>
<% }) %>

編集(update)

一覧画面から、それぞれの記事の編集画面に飛べるようにapp.jsとindex.ejsを修正し、edit.ejsを新規作成します。

app.js
/* ~~省略~~ */

//新規作成画面のルーティング
app.get('/new', (req, res) => {
    res.render('new.ejs');
});
//新規作成アクション
app.post('/create', (req, res) => {
connection.query(
    'INSERT INTO items (title, text) VALUES (?, ?)',
    [req.body.itemTitle, req.body.itemText],
    (error, results) => {
    res.redirect('/')
    });
});

/* ============ここから追加============ */
//編集画面へのルーティング
app.get('/edit/:id', (req, res) => {
    connection.query(
      'SELECT * FROM items WHERE id = ?',
      [req.params.id],
      (error, results) => {
        res.render('edit.ejs', {item: results[0]});
      }
    );
});

//更新アクション
app.post('/update/:id', (req, res) => {
    connection.query(
    'UPDATE items SET title = ?, text = ? WHERE id = ?',[req.body.itemTitle, req.body.itemText, req.params.id],(error,results)=>{
      res.redirect('/');
    })
});
/* ============ここまで追加============ */

app.listen(3000);
views/index.ejs
<% items.forEach((item) => { %>
    <li>
      <div>
        <span><%= item.title %></span>
        <span><%= item.text %></span>
      </div>
    </li>
<!-- ============ここから追加============ -->
    <a href="/edit/<%= item.id %>">編集</a>
<!-- ============ここまで追加============ -->
<% }) %>
views/edit.ejs
<form action="/update/<%= item.id %>" method="post">
 <input type="text" name="itemTitle" value="<%= item.title %>">
 <input type="text" name="itemText" value="<%= item.text %>">
 <input type="submit" value="更新する">
</form>

削除(delete)

一覧画面から、それぞれの記事を削除できるようにapp.jsとindex.ejsを修正します。

app.js
/* ~~省略~~ */

//編集画面へのルーティング
app.get('/edit/:id', (req, res) => {
    connection.query(
      'SELECT * FROM items WHERE id = ?',
      [req.params.id],
      (error, results) => {
        res.render('edit.ejs', {item: results[0]});
      }
    );
});

//更新アクション
app.post('/update/:id', (req, res) => {
    connection.query(
    'UPDATE items SET title = ?, text = ? WHERE id = ?',[req.body.itemTitle, req.body.itemText, req.params.id],(error,results)=>{
      res.redirect('/');
    })
});

/* ============ここから追加============ */
//削除
app.post('/delete/:id', (req, res) => {
    connection.query(
      'DELETE FROM items WHERE id = ?',
      [req.params.id],
      (error, results) => {
        res.redirect('/');
      }
    );
});
/* ============ここまで追加============ */

app.listen(3000);
views/index.ejs
<% items.forEach((item) => { %>
    <li>
      <div>
        <span><%= item.title %></span>
        <span><%= item.text %></span>
      </div>
    </li>
    <a href="/edit/<%= item.id %>">編集</a>
<!-- ============ここから追加============ -->
    <form action="/delete/<%= item.id %>" method="post">
      <input type="submit" value="削除">
    </form>
<!-- ============ここまで追加============ -->
<% }) %>

以上でCRUD機能の実装は完了です!

##完成形
GitHubに完成形のコードを上げてます。ご参考まで。

##参考
//mysqlのインストール(記事の前半部分)
https://reffect.co.jp/laravel/mysql-laravel-in-mac

//データベースの作成、テーブルの作成など
https://reffect.co.jp/node-js/express-js-connect-mysql

8
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?