Nodejs ORM框架Sequelize快速入門
阿新 • • 發佈:2019-01-04
Nodejs ORM框架Sequelize快速入門
什麼是ORM?
簡單的講就是對SQL查詢語句的封裝,讓我們可以用OOP的方式操作資料庫,優雅的生成安全、可維護的SQL程式碼。直觀上,是一種Model和SQL的對映關係。
const User = sequelize.define('user', { id: { type: Sequelize.INTEGER, allowNull: false, autoIncrement: true, primaryKey: true }, email: { type: Sequelize.STRING, allowNull: false, validate: { isEmail: true }, unique: true } })
CREATE TABLE IF NOT EXISTS `users` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`email` VARCHAR(255) NOT NULL UNIQUE
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NOT NULL,
UNIQUE (email)
);
那麼什麼是Sequelize?
Sequelize是一款基於Nodejs功能強大的非同步ORM框架。
同時支援PostgreSQL, MySQL, SQLite and MSSQL多種資料庫,很適合作為Nodejs後端資料庫的儲存介面,為快速開發Nodejs應用奠定紮實、安全的基礎。
既然Nodejs的強項在於非同步,沒有理由不找一個強大的支援非同步的資料庫框架,與之配合,雙劍合併~
//引入框架 var Sequelize = require('sequelize'); //初始化連結(支援連線池) var sequelize = new Sequelize('database', 'username', 'password', { host: 'localhost', dialect: 'mysql'|'sqlite'|'postgres'|'mssql', pool: { max: 5, min: 0, idle: 10000 }, // SQLite only storage: 'path/to/database.sqlite' }); //定義資料模型 var User = sequelize.define('user', { username: Sequelize.STRING, birthday: Sequelize.DATE }); //初始化資料 sequelize.sync().then(function() { return User.create({ username: 'janedoe', birthday: new Date(1980, 6, 20) }); }).then(function(jane) { //獲取資料 console.log(jane.get({ plain: true })); }).catch(function (err) { //異常捕獲 console.log('Unable to connect to the database:', err); });
Sequelize有哪些特色?
強大的模型定義,支援虛擬型別。Javascript雖然被很多人詬病雜亂無章法,但是函式即物件這個特色,可以說是我的最愛,非常靈活強大。
var Foo = sequelize.define('foo', {
firstname: Sequelize.STRING,
lastname: Sequelize.STRING
}, {
getterMethods : {
fullName : function() { return this.firstname + ' ' + this.lastname }
},
setterMethods : {
fullName : function(value) {
var names = value.split(' ');
this.setDataValue('firstname', names.slice(0, -1).join(' '));
this.setDataValue('lastname', names.slice(-1).join(' '));
},
}
});
支援完善的資料驗證,減輕前後端的驗證壓力。
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('請輸入偶數!')
}
}
}
}
});
Sequelize的查詢非常全面和靈活
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裡面最難的部分。
var User = sequelize.define('user', { name: Sequelize.STRING })
, Task = sequelize.define('task', { name: Sequelize.STRING })
, Tool = sequelize.define('tool', { name: Sequelize.STRING })
Task.belongsTo(User) // 增加外來鍵屬性 UserId 到 Task
User.hasMany(Task) // 給 Task 增加外來鍵屬性 userId
User.hasMany(Tool, { as: 'Instruments' }) // 給 Task 增加自定義外來鍵屬性 InstrumentsId
Task.findAll({ include: [ User ] })
User.findAll({ include: [{
model: Tool,
as: 'Instruments',
where: { name: { $like: '%ooth%' } }
}] })
User.findAll({ include: ['Instruments'] })
var User = this.sequelize.define('user', {/* attributes */}, {underscored: true})
, Company = this.sequelize.define('company', {
uuid: {
type: Sequelize.UUID,
primaryKey: true
}
});
User.belongsTo(Company); // 增加 company_uuid 外來鍵屬性到 user
User.belongsTo(UserRole, {as: 'role'});
// 自定義外來鍵屬性 roleId 到 user 而不是 userRoleId
User.belongsTo(Company, {foreignKey: 'fk_companyname', targetKey: 'name'}); // 增加自定義外來鍵屬性 fk_companyname 到 User
Person.hasOne(Person, {as: 'Father', foreignKey: 'DadId'})
// Person 增加外來鍵屬性 DadId
Coach.hasOne(Team) // `coachId` 作為 Team 的外來鍵屬性
Project.hasMany(User, {as: 'Workers'})
// 給 User 增加外來鍵屬性 projectId / project_id
Project.belongsToMany(User, {through: 'UserProject'});
User.belongsToMany(Project, {through: 'UserProject'});
// 建立新的模型: UserProject 包含外來鍵屬性:projectId 和 userId
Sequelize還有完善的遷移同步資料方案,migrate so easy。
//$ sequelize db:migrate //用命令直接生成模版指令碼,接下來的還是寫js
module.exports = {
up: function(queryInterface, Sequelize) {
// 需要修改資料庫的操作
},
down: function(queryInterface, Sequelize) {
// 取消修改的操作
}
}