//tips
//smart contract
一旦dbとの取り出しをレコード単位に変更。
const express = require('express');
const router = express.Router();
const sqlite3=require('sqlite3');
//データベースオブジェクトの取得
//sqlite3.Databaseオブジェクトで引数にデータベースファイル名をとる
//このデータベースファイル名はDB browser for sqliteフォルダ内に作成したもの
const db=new sqlite3.Database('mydb.sqlite3');
router.get('/', (req, res, next) =>{
//データベースのシリアライズ(直列化)
//シリアライズとは用意された処理を順番に実行するためのもの
//まずは、データベースを利用する処理はserializeの引数に用意した関数の中に書くと覚える
db.serialize(()=>{
var rows="";
//レコードを全て取り出す
//db.all(クエリー文、関数)
//第一引数に実行するsql命令文を記載
//第2引数の関数は、データベースから処理結果が返ってきたら実行する処理。コールバック関数
//db.eachは二つ関数をとり、一つ目の関数はレコードを一つ取るごとに実行、二つ目は全てのレコードを取り出し終わったら実行
db.each("select*from mydata",(err,rows)=>{
//データベースアクセス完了時の処理
//errはエラー情報を渡すためのもの、rowsはデータベースから返されたレコードをまとめたもの
//rowsは各レコードをjsオブジェクトにしたものを配列にしたもの
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',data);
}
});
});
});
module.exports = router;
こちらでの反映を試みる。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<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">
<table class="table">
<%- content %>
</table>
</div>
</body>
</html>
実行してみるとzsh: segmentation fault npm startとなる事象が発生。
これは引数のrowにsをつけてしまったのが問題だった。
Htmlの復習として下記記載。
tr要素は「Table Row」「表の行」
th要素は「Table Header「表の見出し」
td要素は「Table Data」:「名前」というth要素の下に「鈴木」というtd要素が追加されて表が作られていく形
今回のhello.ejsはかなりスッキリしており<%- content %>の記載だけで済んだ。これはjsで処理したテーブルごと出力していることを示している。
db.each("select*from mydata",(err,row)=>{
if(!err){
rows+="<tr><th>"+row.id+"</th><td>"+row.名前+"</td><td></tr>";
}
の部分が該当する。
最後の<td>はあってもなくても良いが表示位置を若干変えるのに役立っていた。
表示はできたので、さらにデータベースへの理解を深めていく。下のCRUDを実行していく。
Create:新しいレコードの作成保存
Read:レコードをデータベースから取り出し
Update:レコードの内容を書き換え
Delete:レコードを削除
Viewsフォルダーの中にhelloフォルダを作成。hello.ejsをその中に移動し、名前もindex.ejsに変更。
これは/hello/indexに対応するため。
Hello.jsのコードをres.render('hello/index',data);に変更しておく。
また、新たにadd.ejsを作成する。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<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 method="post" action="/hello/add">
<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>
これに対応するためにhello.jsの方も修正。
これでhello/addに書き込んでsubmitするも、エラー。
[Error: SQLITE_ERROR: near "value": syntax error
Emitted 'error' event on Statement instance at:
] {
errno: 1,
code: 'SQLITE_ERROR'
}
Dbコマンドのvaluesのsがついていなかったのが問題だった。
これによりデータベースへ新たなレコードを追加できるようになった。
http://localhost:3000/hello/show?id=1でアクセスして、レコード内容を取り出した。
router.get('/show', (req, res, next) =>{
//リクエストのidの値を取得
const id=req.query.id;
db.serialize(()=>{
//select * テーブル where 条件でphpの時と同じ
const q="select * from mydata where id=?";
//今回は一部の取り出しなのでallではなくdb.get
//第一引数はsql,第二引数は?に渡す値を配列にまとめたもの、第3引数はコールバック関数
//getの場合得られるレコードは一つだけになる
db.get(q,[id],(err,row)=>{
if(!err){
var data={
title:'Hello/show',
content:'id= '+id+' のレコード:',
mydata:row
};
res.render('hello/show',data);
}
});
});
});
編集も同様に行ってみる。
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;
//update テーブル set フィールド1=値1...where 条件;
//更新するレコードのあるテーブルを指定
const q="update mydata set name=?,mail=?,age=? where id=?";
db.serialize(()=>{
db.run(q,nm,ml,ag,id);
});
res.redirect('/hello');
});
かなり/showの部分と似ていた。ただ、updateの際はwhereの条件を必ず設定することを忘れない。そうしないと全て書き換えられてしまう。
レコードの削除も行っていく。