sequelize參考
Sequelize類是引用sequlize模組後獲取一個頂級物件,我們通過它來建立sequlize例項,也可以通過該物件來獲取模內其它物件的引用,如:Utils工具類、Transaction事務類等。建立例項後,可以通過例項來建立或定義Model(模型)、執行查詢、同步資料庫結構等操作。
註釋:mysql的引擎模組名是: mysql2
Model相當於資料庫中表,有時它也會被稱為“模型”或“工廠”。Model不能通過建構函式建立,而只能通過sequlize.define方法來定義或通過sequlize.import匯入。通過define定義一個Model,就相當於定義了一種模型與資料表之間的對映關係,通過模型可以實現對錶記錄的增、刪、改、查等操作。
模型(Model)之間存在各種各樣的關係,如:一對一(One-To-One )、一對多(One-To-Many)等。模型間的關係本質上是對其代表的資料庫中表之間的關係描述,通過這些關係可以實現資料庫中表之間主/外來鍵約束的建立。查詢時也可以基於這些關係,生成在資料庫中執行的連線查詢或複合查詢SQL語句。
Sequelize中有兩種查詢:使用Model(模型)中的方法查詢和使用sequelize.query()進行基於SQL語句的原始查詢。
Instance類表示資料庫中的一行記錄,該類不能直接例項化,而應該由Model物件建立。Instance例項有兩種,由Model.build方法建立的非持久化例項,和由Model.create方法建立的持久化例項。應該注意,Instance翻譯後也叫做“例項”,但它在Sequelize 中是一個類,它的例項應該叫做“例項”類的例項。
Transaction是Sequelize中用於實現事務功能的子類,通過呼叫Sequelize.transaction()方法可以建立一個該類的例項。在Sequelize中,支援自動提交/回滾,也可以支援使用者手動提交/回滾
.Scopes - 作用域,表示一個限制範圍,它最終會生成SQL查詢中的where子句。它在模型定義方法sequelize.define的option引數,或通過Model.scope()方法指定。
Hooks(鉤子)是指會在模型生命週期的特殊時刻被呼叫的函式,如:模型例項被建立前會呼叫beforeCreate函式,而在模型例項建立後又會呼叫afterCreate函式。通過這些鉤子函式,使用我們具有在生命週期的特殊時刻訪問或操作模型資料的能力。
在使用sequelize.define方法定義模型時,我們一般會為模型屬性(列)指定型別type,它表示資料型別,Sequelize會按指定的型別在資料庫中建立欄位。這些型別被定義到了sequelize模組的DataTypes類中,它是一個靜態類可以直接引用其屬性或方法。
Sequelize 2.0.0引入了一個新的CLI(命令列工具),其基於gulp並結合sequelize-cli和gulp-sequelize,CLI用於支援資料遷移和專案引導。通過遷移,可以將現有資料庫遷移到另一個狀態,反之亦然:這些遷移檔案會被儲存在遷移檔案中,遷移檔案描述了怎樣到達新狀態以及如何恢復更改以返回到遷移前的舊狀態。
在SQL查詢中,分組查詢是較常用的一種查詢方式。分組查詢是指通過GROUP BY關鍵字,將查詢結果按照一個或多個欄位進行分組,分組時欄位值相同的會被分為一組。在Node.js基於Sequelize的ORM框架中,同樣支援分組查詢,使用非常簡單方便。
Sequelize 可以實現針對單個例項的一或多個欄位的自增、自減操作,也可以對符合條件的資料進行批量的自增、自減操作。單個例項欄位的自增、自減可以利用Instance的相應方法實現,而批量自增、自減則需要藉助sequelize提供的字面量方法實現。
belongsToMany用於表示模型間N:M(多對多)的關係,N:M關係通過一個“關係表”建立兩個模型間的關聯關係。用於建立關聯關係的“關係表”可以手工建立,也可以由Sequelize自動建立。
在構建高併發的Web應用時,除了應用層要採取負載均衡方案外,資料庫也要支援高可用和高併發性。使用較多的資料庫優化方案是:通過主從複製(Master-Slave)的方式來同步資料,再通過讀寫分離(MySQL-Proxy)來提升資料庫的併發負載能力。在Node.js中,使用 Sequelize操作資料庫時,同樣支援讀寫分離。
Sequelize 基於資料庫例項定義模型,可以方便的進行資料的增、刪、改、查操作,並可以基於模型關係實現連線查詢、事務等操作。但這些操作都是基於一個數據庫例項,即:一個sequelize例項,除讀寫分離外,Sequelize也並不支援多資料庫操作。如果你的專案中需要對多個數據庫進行操作,就不那麼方便。本文將針對Sequelize操作多資料庫的情況做一些整理
在使用Sequelize進行關係模型(表)間連線查詢時,我們會通過model/as來指定已存在關聯關係的連線查詢模型,或是通過association來直接指定連線查詢模型關係。那麼,兩者各應該在什麼場景下使用呢?
參考:
中文文件
官方文件
參考文件
查詢快取
var ValidateMe = sequelize.define('foo', {
foo: {
type: Sequelize.STRING,
validate: {
is: ["^[a-z]+$",'i'], // 全匹配字母
is: /^[a-z]+$/i, // 全匹配字母,用規則表示式寫法
not: ["[a-z]",'i'], // 不能包含字母
isEmail: true, // 檢查郵件格式
isUrl: true, // 是否是合法網址
isIP: true, // 是否是合法IP地址
isIPv4: true, // 是否是合法IPv4地址
isIPv6: true, // 是否是合法IPv6地址
isAlpha: true, // 是否是字母
isAlphanumeric: true, // 是否是數字和字母
isNumeric: true, // 只允許數字
isInt: true, // 只允許整數
isFloat: true, // 是否是浮點數
isDecimal: true, // 是否是十進位制書
isLowercase: true, // 是否是小寫
isUppercase: true, // 是否大寫
notNull: true, // 不允許為null
isNull: true, // 是否是null
notEmpty: true, // 不允許為空
equals: 'specific value', // 等於某些值
contains: 'foo', // 包含某些字元
notIn: [['foo', 'bar']], // 不在列表中
isIn: [['foo', 'bar']], // 在列表中
notContains: 'bar', // 不包含
len: [2,10], // 長度範圍
isUUID: 4, // 是否是合法 uuids
isDate: true, // 是否是有效日期
isAfter: "2011-11-05", // 是否晚於某個日期
isBefore: "2011-11-05", // 是否早於某個日期
max: 23, // 最大值
min: 23, // 最小值
isArray: true, // 是否是陣列
isCreditCard: true, // 是否是有效信用卡號
// 自定義規則
isEven: function(value) {
if(parseInt(value) % 2 != 0) {
throw new Error('請輸入偶數!')
}
}
}
}
});
Project.findAll({
//複雜過濾,可巢狀
where: {
id: {
$and: {a: 5} // AND (a = 5)
$or: [{a: 5}, {a: 6}] // (a = 5 OR a = 6)
$gt: 6, // id > 6
$gte: 6, // id >= 6
$lt: 10, // id < 10
$lte: 10, // id <= 10
$ne: 20, // id != 20
$between: [6, 10], // BETWEEN 6 AND 10
$notBetween: [11, 15], // NOT BETWEEN 11 AND 15
$in: [1, 2], // IN [1, 2]
$notIn: [1, 2], // NOT IN [1, 2]
$like: '%hat', // LIKE '%hat'
$notLike: '%hat' // NOT LIKE '%hat'
$iLike: '%hat' // ILIKE '%hat' (case insensitive) (PG only)
$notILike: '%hat' // NOT ILIKE '%hat' (PG only)
$overlap: [1, 2] // && [1, 2] (PG array overlap operator)
$contains: [1, 2] // @> [1, 2] (PG array contains operator)
$contained: [1, 2] // <@ [1, 2] (PG array contained by operator)
$any: [2,3] // ANY ARRAY[2, 3]::INTEGER (PG only)
},
status: {
$not: false, // status NOT FALSE
}
}
})
Project.all()
Project.findById
Project.findByOne
Project.findOrCreate
Project.findAndCountAll
Project.count()
Project.max()
//CRUD
Project.create()
Project.save()
Project.update()
Project.destroy()
//批量
User.bulkCreate([])
//排序
something.findOne({
order: [
'name',
// 返回 `name`
'username DESC',
// 返回 `username DESC`
['username', 'DESC'],
// 返回 `username` DESC
sequelize.fn('max', sequelize.col('age')),
// 返回 max(`age`)
[sequelize.fn('max', sequelize.col('age')), 'DESC'],
// 返回 max(`age`) DESC
[sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'],
// 返回 otherfunction(`col1`, 12, 'lalala') DESC
[sequelize.fn('otherfunction', sequelize.fn('awesomefunction', sequelize.col('col'))), 'DESC']
// 返回 otherfunction(awesomefunction(`col`)) DESC, 有可能是無限迴圈
[{ raw: 'otherfunction(awesomefunction(`col`))' }, 'DESC']
// 也可以這樣寫
]
})
// 分頁查詢
Project.findAll({ limit: 10 })
Project.findAll({ offset: 8 })
Project.findAll({ offset: 5, limit: 5 })
//關聯查詢 include 支援巢狀,這可能是ORM裡面最難的部分。