一、模型的引入
引入db.js const sequelize = require('./db') sequelize本身就是一個對象,他提供了眾多的方法, const account = sequelize.model('account') //獲取account這個模型
二,數據庫基本操作(增、刪、改、查)
增:
account.create(data).then(doc => { const {user_name, user_id, user_info, avatar} = doc res.cookie('user_id', user_id) return res.json({ code: 0, data: { user_name: user_name, user_id: user_id, user_info: user_info, avatar: avatar } }) })
刪:
Router.get('/cleardata', function(req,res) {
// 清空全部數據
poetrylist.destroy({
// where: {id: 123}
// 這里可以根據我們定義的條件刪除滿足條件的數據
}).then((doc) => {
return res.json({
code: 0,
data: doc
})
})
})
改:
Router.post('/updataUserInfo', function(req,res) {
// 完善用戶信息
const user_id = req.cookies.user_id
const user_info = req.body.userinfo
account.update(
user_info, // 這里是我們要更新的字段,使用逗號隔開
{
'where': {
'user_id': user_id // 這里是我們要更新那條數據的條件
}
}
).then((doc) => {
return res.json({
code: 0,
data: {
user_info: user_info
}
})
})
})
查:
Router.post('/getUserInfo', function(req,res) {
// 完善用戶信息
const user_id = req.body.user_id ? req.body.user_id : req.cookies.user_id
account.findOne({
'where': {'user_id': user_id},
// attributes屬性可以指定返回結果,返回那些字段的信息
attributes: ['user_name', 'avatar', 'user_info', 'user_fans', 'attention', 'poetry_num', 'user_id']
}).then((doc) => {
poetrylist.findAll({
where: {'user_id': user_id},
order: [
['create_temp', 'DESC'],
]
}).then((metadata) => {
return res.json({
code: 0,
data: {
user_info: doc,
list: metadata
}
})
})
})
})
這里使用的是findOne,還有findAll,findById等等,具體參考官方文檔
三、模型關系
這里就要就要求我們指定數據表之間的關系,這里直說關系,詳解請看官方文檔
1.一對一(BelongsTo, HasOne )
一對一關聯是由一個單一的外鍵,實現兩個模型之間的精確關聯。 BelongsTo關聯表示一對一關系的外鍵存在於源模型。 var Player = this.sequelize.define('player', {/* attributes */}) , Team = this.sequelize.define('team', {/* attributes */}); Player.belongsTo(Team); // 會為Player添加一個teamId 屬性以保持與Team 主鍵的關系 默認情況下,一個屬於關系的外鍵將從目標模型的名稱和主鍵名稱生成。 目標鍵是位於目標模型上通過源模型外鍵列指向的列。默認情況下,目標鍵是會belongsTo關系中目標模型的主鍵。要使用自定義列,請用targetKey選項來指定 HasOne關聯表示一對一關系的外鍵存在於目標模型。 雖然被稱為HasOne 關聯,但大多數 1:1關系中通常會使用BelongsTo 關聯,因為BelongsTo 會在源模型中添加外鍵,而HasOne 則會在目標模型中添加外鍵。 HasOne 與BelongsTo 的不同 在1:1 的關系中,可使用HasOne 或BelongsTo來定義。但它們的使用場景有所不同
2.一對多(HasMany)
One-To-Many關聯是指一個源模型連接多個目標模型。反之目標模型都會有一個明確的源。 var User = sequelize.define('user', {/* ... */}) var Project = sequelize.define('project', {/* ... */}) // 定義 hasMany 關聯 Project.hasMany(User, {as: 'Workers'}) 會向 User 中添加一個projectId或project_id屬性。Project 的實例中會有訪問器getWorkers 和 setWorkers。這是一種單向關聯方式,如果兩個模型間還有其它關聯方式請參考下面的多對多關系。
3.多對多(Belongs-To-Many)
多對多(Belongs-To-Many)關聯 Belongs-To-Many 關聯是指一個源模型連接多個目標模型。而且,目標模型也可以有多個相關的源。 Project.belongsToMany(User, {through: 'UserProject'}); User.belongsToMany(Project, {through: 'UserProject'}); 這會創建一個新模型UserProject其中會projectId和userId兩個外鍵。是否使用駝峰命名取決與相關聯的兩個表。 定義through選項后,Sequelize會嘗試自動生成名字,但並一定符合邏輯。 在本例中,會為User添加方法 getUsers, setUsers, addUser,addUsers to Project, and getProjects, setProjects, addProject, and addProjects 有時我們會對連接的模型進行重命名,同樣可以使用as實現。
四、多表聯查(我們進行用戶信息模型和文章模型的聯合查詢)如下圖的結果

const sequelize = require('./db')
const account = sequelize.model('account') // 獲取模型
const poetrylist = sequelize.model('poetrylist')
poetrylist.belongsTo(account, {foreignKey: 'user_id', targetKey: 'user_id'}); // 指定模型關系可查詢的外鍵字段
Router.get('/getPoetryList', function(req, res) {
// 獲取文章列表
poetrylist.findAll({
include: [{ // 通過include字段執行要聯合那個模型進行查詢
model: account, // 執行模型
attributes: ['user_name', 'avatar', 'user_id'] // 想要只選擇某些屬性可以使用 attributes: ['foo', 'bar']
}],
attributes: [
'content',
'poetrylist_id',
'recommend',
'star',
'user_id',
'create_temp',
'guest_num',
'transmit_content',
'transmit_user_id',
'transmit_user_name',
'transmit_poetrylist_id',
'id'],
order: [ // 使用order進行排序
['create_temp', 'DESC'], // 這;i按照時間順序進行排序
]
}).then((doc) => {
supportlist.findAll({
// 獲取當前用戶的點贊文章的列表
where: {
"user_id": req.cookies.user_id
}
}).then(suplist => {
// 數據處理
for (let i = 0; i < doc.length; i++) {
doc[i].dataValues.isAttention = false
if (suplist.length) {
for (let j = 0; j < suplist.length; j++) {
if (doc[i].dataValues.poetrylist_id === suplist[j].dataValues.poetrylist_id){
doc[i].dataValues.isAttention = true
}
}
} else {
doc[i].dataValues.isAttention = false
}
}
return res.json({
code: 0,
data: doc,
suplist: suplist
})
})
})
})
以上查詢代碼轉換位sql語句為:

五、事物
Transaction是Sequelize中用於實現事務功能的子類,通過調用Sequelize.transaction()方法可以創建一個該類的實例。在Sequelize中,支持自動提交/回滾,也可以支持用戶手動提交/回滾。
Sequelize有兩種使用事務的方式:
- 基於
Promise結果鏈的自動提交/回滾 - 另一種是不自動提交和回滾,而由用戶控制事務
受管理的事務(auto-callback)
受管理的事務會自動提交或回滾,你可以向sequelize.transaction方法傳遞一個回調函數來啟動一個事務。
需要注意,在這種方式下傳遞給回調函數的transaction會返回一個promise鏈,在promise鏈中(then或catch)中並不能調用t.commit()或t.rollback()來控制事務。在這種方式下,如果使用事務的所有promise鏈都執行成功,則自動提交;如果其中之一執行失敗,則自動回滾。
return sequelize.transaction(function (t) { // 要確保所有的查詢鏈都有return返回 return User.create({ firstName: 'Abraham', lastName: 'Lincoln' }, {transaction: t}).then(function (user) { return user.setShooter({ firstName: 'John', lastName: 'Boothe' }, {transaction: t}); }); }).then(function (result) { // Transaction 會自動提交 // result 是事務回調中使用promise鏈中執行結果 }).catch(function (err) { // Transaction 會自動回滾 // err 是事務回調中使用promise鏈中的異常結果 });
不受管理的事務(then-callback)
不受管理的事務需要你強制提交或回滾,如果不進行這些操作,事務會一直保持掛起狀態直到超時。
啟動一個不受管理的事務,同樣是調用sequelize.transaction()方法,但不傳遞回調函數參數(仍然可以傳遞選項參數)。然后可以在其返回的promisethen方法中手工控制事務:
Router.post('/subscription', function (req, res) {
// 關注功能
const data = {
user_id: req.cookies.user_id,
target_id: req.body.target_id
}
// Transaction是Sequelize中用於實現事務功能的子類,
// 通過調用Sequelize.transaction()方法可以創建一個該類的實例。
// 在Sequelize中,支持自動提交/回滾,也可以支持用戶手動提交/回滾。
return sequelize.transaction({
autocommit: true
}, t => {
return attentionlist.findOne({
'where': {
'user_id': req.cookies.user_id,
'target_id': req.body.target_id
}
},{transaction: t}).then(doc => {
if (!doc) {
return attentionlist.create(data,{transaction: t}).then(ret => {
return account.findOne({
'where': {'user_id': req.cookies.user_id}
}, {transaction: t}).then(rets => {
// increment自增函數
return rets.increment('attention').then(retss => {
return 'success'
})
})
}, {transaction: t}).then(docs => {
return docs
})
} else {
return 100
}
})
}).then(result => {
return res.json({
code: 0,
data: result
})
})
})
項目地址:https://github.com/songdongdong123/vue_chat
