TypeORMでDBアクセス#
TypeORMはTypeScriptを使ってデータベースに情報を保存するためのライブラリです。
ここでは、これまでに作ったアプリケーションに、アンケートをデータベースに保存する機能を追加します。
前提条件#
アプリケーションの作成 を行ってください。 データベースはDockerというアプリケーションを使って起動します。Dockerをインストールしてください。
TypeORMのインストール#
以下のコマンドをnpmプロジェクトのルートで実行してください。
npm install typeorm
今回はデータベースはPostgreSQLというデータベースを使用します。PostgreSQLにつなぐためのコネクタをインストールします。
npm install pg
tsconfig.jsonをTypeORM用に設定します。
{
"include": [
"src/backend/**/*"
],
"compilerOptions": {
// "target": "es5",//行の先頭に//を入れて無効化。
"target": "es6",// この行を追加
"emitDecoratorMetadata": true,// この行を追加
"experimentalDecorators": true,// この行を追加
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src/backend",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
これでTypeORMの設定が完了しました。
DockerでPostgreSQLを起動#
Dockerとは、コンテナと呼ばれる仮想環境上でアプリケーションを動作させるアプリケーションです。 手元のマシンに直接アプリケーションをインストールすると、インストールしたものが他に悪さをするときがあるのですが、Dockerであればすぐに消せるので、お手軽にいろいろなアプリケーションを動作させることができます。
DockerでPostgreSQLを起動します。 ターミナルを新しく立ち上げて、以下のコマンドを実行してください。
docker run --name postgres -e POSTGRES_PASSWORD=postgres -d -p 5432:5432 postgres:10-alpine
これでPostgreSQLが起動しました。
TypeORMでDB接続を行う。#
前回アンケートをとる画面を作りました。 ここでは、入力してもらったアンケートをデータベースに保存します。
まずはデータベースに保存するためのアンケートの構造を定義します。定義はTypeScriptで行います。
定義のファイルをおくディレクトリを作成します。
mkdir src/backend/models
src/backend/models/Enquete.ts を作成します。内容は以下です。
import { Entity, PrimaryGeneratedColumn, Column, BaseEntity } from 'typeorm'
@Entity()
export default class Enquete extends BaseEntity {
@PrimaryGeneratedColumn()
public id: number = 0
@Column()
public point: number = 0
@Column()
public message: string = ""
@Column()
public mail: string = ""
}
続けて、データベースへの保存処理と取得処理を作成します。 今回はWebAPIとして、データベースの保存、一覧取得を作成します。
src/backend/controllers/enquete.ts を作成し、内容は以下にしてください。
import express, { Router } from 'express'
import { getRepository } from 'typeorm'
import Enquete from '../models/Enquete'
var router: Router = express.Router();
router.post('/', function (req, res) {
const enquete = req.body;
const EnqueteRepository = getRepository(Enquete);
EnqueteRepository.save(enquete);
res.send(enquete);
});
export default router;
続いて、サーバ起動時にデータベースに接続するようにします。 src/backend/index.ts を以下のように修正してください。
import express from 'express'
import messageController from './controllers/message'
import enqueteController from './controllers/enquete'//この行を追加
import {createConnection} from 'typeorm'//この行を追加
import Enquete from './models/Enquete'//この行を追加
const app: express.Express = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use("/messages", messageController)
app.use("/api/enquetes", enqueteController)//この行を追加
app.use("/", express.static(__dirname + "/public"))
/* ここから */
!async function initialize(){
await createConnection({
type: "postgres",
url: process.env.DATABASE_URL || "postgres://postgres:postgres@127.0.0.1:5432/postgres",
synchronize: true,
entities: [
Enquete,
],
extra: {
ssl: (!!process.env.DATABASE_SSL) ? {
rejectUnauthorized: false,
} : false,
}
});
/* ここまで追加 */
// 3000番ポートでAPIサーバ起動
app.listen(3000, () => {
console.log('ポート3000番で起動しましたよ!')
})
}()//この行を追加
app.listenでWebサーバが起動するのですが、その前にデータベースに接続を行っています。
ここまでできたら、Vueからサーバに通信してAPIを呼んでみます。
Vueからサーバに通信を行う。#
Vueアプリからサーバに通信を行うためにはAxiosというライブラリを利用します。
Axiosをインストールします。ターミナルで、npmプロジェクトのルートで以下のコマンドを実行してください。
npm install axios
続いて、src/front/components/PostEnquete.vue を更新します。 2行、script タグの中に追加します。
<template>
<div>
<h1>{{title}}</h1>
<p>{{description}}</p>
<div v-if="!posted"><!-- 入力エリア ここから -->
<div>
<input type="radio" id="5" value="5" v-model="enquete.point"><label for="5">5点</label>
<input type="radio" id="4" value="4" v-model="enquete.point"><label for="4">4点</label>
<input type="radio" id="3" value="3" v-model="enquete.point"><label for="3">3点</label>
<input type="radio" id="2" value="2" v-model="enquete.point"><label for="2">2点</label>
<input type="radio" id="1" value="1" v-model="enquete.point"><label for="1">1点</label>
</div>
<div>
<p>ご意見・ご要望</p>
<textarea v-model="enquete.message"></textarea>
</div>
<div>
<p>メールアドレス</p>
<input type="mail" v-model="enquete.mail" />
</div>
<div>
<button @click="sendMessage()">アンケート送信</button>
</div>
</div><!-- 入力エリア ここまで-->
<div v-else><!-- 結果エリア ここから -->
<div>
点数{{enquete.point}}点
</div>
<div>
<p>ご意見・ご要望</p>
<p>{{enquete.message}}</p>
</div>
<div>
<p>メールアドレス</p>
<p>{{enquete.mail}}</p>
</div>
</div><!-- 結果エリア ここまで -->
</div>
</template>
<script lang="ts">
import Vue from "vue";
import axios from "axios";//この行を追加
export default Vue.extend({
data() {
return {
title: "アンケート",
description: "良かったですか?5点(高い) から 1点(低い) で点数をつけてください。",
enquete: {},
posted: false
};
},
methods: {
sendMessage(){
this.description = "アンケート送信をありがとうございました。";
axios.post("/api/enquetes/", this.enquete);//この行を追加
this.posted = true;
}
}
});
</script>
これで、アンケートをデータベースに保存できるようになりました! では確認してみます。
ブラウザで http://localhost:3000にアクセスしてください。 アンケートを入力します。 アンケート送信ボタンを押してください。
これで、アンケートが登録されました。
データベースの中をみて、アンケート内容を確認してみましょう。
ターミナルで以下のコマンドを実行します。
docker exec -it postgres psql -U postgres
これでPostgreSQLにログインしています。 続いて、同じターミナルでselect文を実行します。
select * from enquete;
すると、以下のような表示がされます。
id | point | message | mail
----+-------+------------------+--------------------
1 | 5 | とても最高です! | ukiuni@example.com
(1 row)
アンケート内容が保存されていることを確認できますね! データベースの中を見るためには、SQLというコマンドを発行します。 ここでは、enqueteからすべてを出力する、ということをしています。
\q と打って、Enterキーを押せば、PostgreSQLから抜けることができます。
これで、アンケートを収集できるようになりました。
次は、アンケート結果を一覧で見れるように、アンケート入力画面とは別に、アンケート一覧表示画面を作れるようにします。