一個關於vue+mysql+express的全棧項目(四)------ sequelize中部分解釋


一、模型的引入

引入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鏈中(thencatch)中並不能調用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM