# 使用 Objection.js 連線 Mysql DB (二)
###### tags: `w3HexSchool` . `node.js`
> 第二篇我們來說說 , Objection 裡面的 2 大重要觀念與其歷史吧 !
> - ORM ( Object-Relational Mapping )
> - Transaction
## orm 是什麼東西 ?
這是一個由 Java 工程師 Gavin King 開發出的 Hibernate 所衍生出的一個概念
將 每個 Table 都可視為一個 Object , 並設定 Table 之間的關係 ( Relation )
常見的關係有 :
- 1 對 1 - 兩樣東西為 1 個對應 1 個的存在 (ex: 學生與學生證 )
- 1 對多 - 兩樣東西為 1 個對應 多個的存在 (ex: 班級與學生 )
- 多對 1 - 兩樣東西為 多個對應 1 個的存在 (ex: 蘋果與蘋果樹 )
- 多對多 - 兩樣東西為 多個對應 多個的存在 (ex: 學生與課程 )
## 設定
> Objection 中的各式 Relation
> - BelongsToOneRelation
> - HasOneRelation
> - HasManyRelation
> - ManyToManyRelation
> - HasOneThroughRelation
>
> 詳情可見 : https://vincit.github.io/objection.js/guide/relations.html
### BelongsToOneRelation
> 包含在其他東西中 ( ex : 輪胎包含於車子中 )
```javascript=
class Wheel extends Model {
static tableName = 'wheel';
static relationMappings = {
car: {
relation: Model.BelongsToOneRelation,
modelClass: Car,
join: {
from: 'wheel.fk_car_id',
to: 'car.id'
}
}
};
}
```
### HasOneRelation
> 拥有某東西 ( ex : 車子有一個引擎 )
```javascript=
class Car extends Model {
static tableName = 'car';
static relationMappings = {
engine: {
relation: Model.HasOneRelation,
modelClass: Engine,
join: {
from: 'car.id',
to: 'engine.car_id'
}
}
};
}
```
### HasManyRelation
> 拥有多個某東西 ( ex : 車子有四個輪胎 )
```javascript=
class Car extends Model {
static tableName = 'car';
static relationMappings = {
wheels: {
relation: Model.HasManyRelation,
modelClass: Wheel,
join: {
from: 'car.id',
to: 'wheel.fk_car_id',
}
}
};
}
```
## Transaction 是什麼?
有時我們修改 Mysql 中的資料 , 可能需要 2 個 Table 中的資料一同做修改 , 為了確保資料的一同修改 , 因此 Mysql 多了 commit 跟 rollback 做處理 ,
而 commit 動作 , 可被稱作 Transaction commit
同理 , rollback 可被稱作 Transaction rollback
```sql=
START TRANSACTION;
UPDATE user SET email='test@gmail.com' WHERE username = 'test';
UPDATE user SET fk_group_id=3 WHERE username = 'temp';
UPDATE group SET name='VIP群組' WHERE id = 3;
COMMIT;
```
上方指令 , 要修改 3 個地方的資料 , 而且要確保修改時能一同修改 , 修改失敗時 , 則不做修改 ( 或者說回到 START TRANSACTION 那時的資料狀態 )
## 使用 Transaction
> 教學 : https://vincit.github.io/objection.js/guide/transactions.html
```javascript=
// @/utils/transWrapper.js
const {transaction, Model} = require('objection');
/**************
* Use sample :
return await transWrapper(async (trx) => await ContextService.add(context,trx));
***************/
const transWrapper = async function (func) {
return await transaction(Model.knex(), async (trx) => {
return await func(trx);
});
};
module.exports = transWrapper;
```
## 參考資料
- hibernate wiki - https://zh.wikipedia.org/wiki/Hibernate
- objection 教學 - https://vincit.github.io/objection.js/guide/models.html#examples
- https://www.mysql.tw/2018/05/mysqlrollbackcommit.html