# 使用 Objection.js 連線 Mysql DB (一)
###### tags: `w3HexSchool` . `node.js`
> 使用 node.js 時常常看到搭配的資料庫為 mongoDB (~~芒果好吃~~) ,
> 但目前業界常用的資料庫為 Mysql . Mssql 或 Oracle 啊!
> 難道這時我們要捨棄使用 node.js 改學 Java ?
> 身為 JS 無國界的信仰者,我堅信一定有第三方套件可以幫我們處理這東東
> 這時 objection.js 在此降臨,收到福音的我,決定將此好物傳道出去
## 安裝
```shell=
npm i -s objection knex
```
根據你要用的資料庫 , 選擇下方其一套件安裝
```shell=
npm i -s pg # PostgreSQL
npm i -s sqlite3 # sqlite
npm i -s mysql # mysql
npm i -s mysql2 # mysql
npm i -s oracledb # oracle
```
## 初始化資料庫
使用工具 ( [sqlitestudio](https://sqlitestudio.pl/index.rvt) ) 建立 sqlite DB 檔案
![](https://i.imgur.com/HxXYEnk.png)
如果不會使用 `sqlitestudio` 可參考 [文章: SQLite 管理工具 SQLiteStudio](https://chenglearning.blogspot.com/2013/11/sqlitestudio1sqlite.html)
下方我們建立一些基礎的 Table 跟資料
```sql=
-- init.sql
BEGIN TRANSACTION;
create table favorite
(
id INTEGER primary key autoincrement,
fk_user_id BIGINT(20),
fk_video_id BIGINT(20)
);
create table image
(
id INTEGER primary key autoincrement,
url VARCHAR(200),
file_path VARCHAR(60),
base64 TEXT
);
create table `user`
(
id INTEGER primary key autoincrement,
name VARCHAR(255),
nickname VARCHAR(50),
password VARCHAR(8000),
fk_image_id BIGINT(20)
);
INSERT INTO user (name, nickname, fk_image_id) VALUES
('索龍', '綠頭髮', null),
('那美', '航海士', null);
create table video
(
id INTEGER primary key autoincrement,
title VARCHAR(200),
fk_image_id BIGINT(20) unique,
create_at DATETIME,
update_at DATETIME,
watchNumber BIGINT(30)
);
COMMIT;
```
資料庫截圖 :
![](https://i.imgur.com/SNXODZl.png)
| 資料表名稱 | 功用 |
| ----------- | -------- |
| user | 使用者 |
| favorite | 紀錄使用者喜歡哪幾部電影 |
| video | 電影 |
| image | 圖片 ( 電影圖 . 個人頭像 ) |
## 第一次使用 - 取出單個 Table 中的資料
設定連線
```javascript=
// ./knex/connect.js
// run the following command to install:
// npm install objection knex sqlite3
const { Model } = require('objection');
const Knex = require('knex');
// Initialize knex.
const knex = Knex({
client: 'sqlite3',
useNullAsDefault: true,
connection: {
filename: '../db/test.sqlite3' // 設定檔案位置
}
});
// Give the knex instance to objection.
Model.knex(knex);
```
設定 Model
```javascript=
// ./model/user.js
// User model.
const { Model } = require('objection');
class User extends Model {
static get tableName() {
return 'user'; // 設定 資料表名稱
}
}
module.exports = User;
```
設定 Service
```javascript=
// ./service/user.js
const User = require('../models/user');
class UserService {
async add(user) {
return await User.query().insertAndFetch(user);
}
async list() {
return await User.query();
}
async findById(id = 0) {
return await User.query().findById(id);
}
// 只更新傳入的參數
async update(id, user) {
return await User.query().patchAndFetchById(id, user);
}
async deleteById(id) {
// WARNING : THIS WILL REMOVE THE USER FOREVER
return await User.query().deleteById(id);
}
}
module.exports = UserService;
```
執行檔
```javascript=
// ./app.js
const http = require("http");
require("./knex/connect");
const UserService = require("./service/user");
const run = async () => {
const users = await new UserService().list();
return users;
};
//create a server object:
http
.createServer(function(req, res) {
run().then(users => {
res.setHeader("content-type", "charset=utf-8");
res.write(`<head><meta charset="utf-8"></head>`);
users.forEach(element => {
res.write(`姓名:${element.name}<br><br><br><br>`); //write a response to the client
});
res.end(); //end the response
});
})
.listen(8080); //the server object listens on port 8080
```
## 結果
- 使用 codesandbox 顯示
<iframe
src="https://codesandbox.io/embed/falling-hooks-03h2p?fontsize=14&hidenavigation=1&theme=dark"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="falling-hooks-03h2p"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
></iframe>
## 參考資料
- https://vincit.github.io/objection.js/guide/getting-started.html