Sequelize-nodejs-2-basic usage

Basic usage基本使用

To get the ball rollin' you first have to create an instance of Sequelize. Use it the following way:html

使用Sequelize的您必須首先建立一個實例。如下方式使用它:node

const sequelize = new Sequelize('database', 'username', 'password', { dialect: 'mysql' });

This will save the passed database credentials and provide all further methods.mysql

這將保存經過的數據庫證書並提供全部進一步的方法。git

Furthermore you can specify a non-default host/port:github

此外您能夠指定一個非默認主機/端口,下面是三種鏈接的方式,使用第一種:web

const Sequelize = require('sequelize'); const sequelize = new Sequelize('token', 'root', 'mypassword', { dialect: 'mysql',//鏈接的數據庫類型 // host: "127.0.0.1",//數據庫地址 // port: 3306,//數據庫接口 });

 

If you just don't have a password:sql

const sequelize = new Sequelize({ database: 'db_name', username: 'username', password: null, dialect: 'mysql' });

 

You can also use a connection string:數據庫

const sequelize = new Sequelize('mysql://user:pass@example.com:9821/db_name', { // Look to the next section for possible options })

 

 

Options

Besides the host and the port, Sequelize comes with a whole bunch of options. Here they are:後端

除了主機和端口,Sequelize有不少options數組

const sequelize = new Sequelize('database', 'username', 'password', { // the sql dialect of the database // currently supported: 'mysql', 'sqlite', 'postgres', 'mssql' dialect: 'mysql', // 自定義的host或者默認的localhost host: 'my.server.tld', // 自定義的端口,或者默認的,mysql默認的端口爲3306 port: 12345, // 自定義的協議,默認的爲'tcp' // postgres only, useful for Heroku protocol: null, // 禁用日誌記錄,默認使用console.log logging: false, // you can also pass any dialect options to the underlying dialect library // - default is empty // - currently supported: 'mysql', 'postgres', 'mssql'  dialectOptions: { socketPath: '/Applications/MAMP/tmp/mysql/mysql.sock', supportBigNumbers: true, bigNumberStrings: true }, // the storage engine for sqlite // - default ':memory:' storage: 'path/to/database.sqlite', // 禁用插入未定義的值爲null // - default: false omitNull: true, // 是否使用一個本地庫. // in the case of 'pg' -- set this to true will allow SSL support // - default: false native: true, // Specify options, which are used when sequelize.define is called. // The following example: // define: { timestamps: false } // is basically the same as: // sequelize.define(name, attributes, { timestamps: false }) // so defining the timestamps for each model will be not necessary  define: { underscored: false freezeTableName: false, charset: 'utf8', dialectOptions: { collate: 'utf8_general_ci' }, timestamps: true }, // 相似的同步:您能夠定義這個老是強迫使用同步模型 sync: { force: true }, // pool configuration used to pool database connections  pool: { max: 5,//鏈接池中最大鏈接數量 idle: 30000, acquire: 60000,//若是一個線程 60 秒鐘內沒有被使用過的話,那麼就釋放線程 }, // isolation level of each transaction // defaults to dialect default  isolationLevel: Transaction.ISOLATION_LEVELS.REPEATABLE_READ })

Hint: You can also define a custom function for the logging part. Just pass a function. The first parameter will be the string that is logged.您還能夠定義一個自定義的日誌函數。僅僅經過一個函數。第一個參數是被記錄的字符串

 

Read replication

Sequelize supports read replication, i.e. having multiple servers that you can connect to when you want to do a SELECT query. When you do read replication, you specify one or more servers to act as read replicas, and one server to act as the write master, which handles all writes and updates and propagates them to the replicas (note that the actual replication process is not handled by Sequelize, but should be set up by database backend).

Sequelize支持讀複製,即當你想作一個SELECT查詢有多個服務器能夠鏈接。當你讀複製,您指定一個或多個服務器做爲讀副本,和一個服務器充當主寫,用來處理全部寫和更新並將它們傳遞到副本(請注意,實際的複製過程不是由Sequelize,但應該被數據庫後端創建)

const sequelize = new Sequelize('database', null, null, { dialect: 'mysql', port: 3306 replication: { read: [ { host: '8.8.8.8', username: 'read-username', password: 'some-password' }, { host: '9.9.9.9', username: 'another-username', password: null } ], write: { host: '1.1.1.1', username: 'write-username', password: 'any-password' } }, pool: { // If you want to override the options used for the read/write pool you can do so here max: 20, idle: 30000 }, })

If you have any general settings that apply to all replicas you do not need to provide them for each instance. In the code above, database name and port is propagated to all replicas. The same will happen for user and password, if you leave them out for any of the replicas. Each replica has the following options:host,port,username,password,database.

若是你有任何通常設置適用於全部副本,那麼你就不須要爲每一個實例一一提供設置。在上面的代碼中,數據庫名稱和端口傳播到全部副本。若是你離開任何副本,用戶名和密碼也會同樣傳播。每一個副本都有如下選項:host,port,username,password,database

Sequelize uses a pool to manage connections to your replicas. Internally Sequelize will maintain two pools created using pool configuration.

Sequelize使用池來管理鏈接到您的副本。內部Sequelize將保持經過使用池配置進行建立的兩個池。

If you want to modify these, you can pass pool as an options when instantiating Sequelize, as shown above.

若是你想修改這些,當實例化Sequelize時,你能夠把池做爲一個選項,如上所示。

Each write or useMaster: true query will use write pool. For SELECT read pool will be used. Read replica are switched using a basic round robin scheduling.

每一個write或useMaster:真正的查詢將使用寫池。對於SELECT命令,讀池將被使用。讀副本將使用一個基本的輪循調度。

 

Dialects

With the release of Sequelize 1.6.0, the library got independent from specific dialects. This means, that you'll have to add the respective connector library to your project yourself.

MySQL

In order to get Sequelize working nicely together with MySQL, you'll need to install mysql2@^1.0.0-rc.10 or higher. Once that's done you can use it like this:

在上面安裝處也有說過,若是想要和mysql一塊兒使用,必須安裝mysql2@^1.0.0-rc.10模塊或者更高的版本

const sequelize = new Sequelize('database', 'username', 'password', { dialect: 'mysql' })

Note: You can pass options directly to dialect library by setting the dialectOptions parameter. See Options for examples (currently only mysql is supported).

注意:您能夠經過設置dialectOptions參數直接傳遞options給dialect庫。

SQLite

For SQLite compatibility you'll need sqlite3@~3.0.0. Configure Sequelize like this:

同時SQLite須要安裝sqlite3@~3.0.0

const sequelize = new Sequelize('database', 'username', 'password', { // sqlite! now! dialect: 'sqlite', // the storage engine for sqlite // - default ':memory:' storage: 'path/to/database.sqlite' })

 

Or you can use a connection string as well with a path:

或者可使用帶着路徑的鏈接字符串的形式

const sequelize = new Sequelize('sqlite:/home/abs/path/dbname.db') const sequelize = new Sequelize('sqlite:relativePath/dbname.db')

 

PostgreSQL

The library for PostgreSQL is pg@^5.0.0 || ^6.0.0 You'll just need to define the dialect:

須要安裝pg@^5.0.0 或 ^6.0.0版本

const sequelize = new Sequelize('database', 'username', 'password', { // gimme postgres, please! dialect: 'postgres' })

 

MSSQL

The library for MSSQL is tedious@^1.7.0 You'll just need to define the dialect:

須要安裝tedious@^1.7.0

const sequelize = new Sequelize('database', 'username', 'password', { dialect: 'mssql' })

 

Executing raw SQL queries執行原始SQL查詢

As there are often use cases in which it is just easier to execute raw / already prepared SQL queries, you can utilize the function sequelize.query.

在常用的狀況下,執行原始/已經準備好的SQL查詢是十分容易的,你可使用函數sequelize.query

Here is how it works:

// 原始查詢的參數 sequelize.query('your query', [, options]) // Quick example,例子 sequelize.query("SELECT * FROM myTable").then(myTableRows => { console.log(myTableRows) }) // 若是你想返回使用模型選項的sequelize實例. // 這使您能夠輕鬆地將一個查詢映射到sequelize的預約義模型 .query('SELECT * FROM projects', { model: Projects }) .then(projects => { // 每一個記錄將被映射到項目的model.  console.log(projects) }) // Options is an object with the following keys: sequelize .query('SELECT 1', { // 每一次SQL查詢都會調用記錄查詢的函數並返給服務器  logging: console.log, // 若是plain是true的,那麼sequelize將只返回第一個記錄的結果集 // 若是是false則返回因此記錄 plain: false, // 設置爲真,若是你沒有爲你查詢設置一個模型定義 raw: false, //您正在執行的查詢類型。查詢類型影響如何在結果傳回以前對其進行格式化  type: Sequelize.QueryTypes.SELECT }) // 第二個參數爲null // Even if we declared a callee here, the raw: true would // supersede and return a raw object.即便咱們聲明瞭一個被調用者,raw: true將取代並返回一個原始對象 sequelize .query('SELECT * FROM projects', { raw: true }) .then(projects => { console.log(projects) })

Replacements in a query can be done in two different ways, either using named parameters (starting with :), or unnamed, represented by a ?

替換查詢中能夠經過兩種不一樣的方式,使用命名參數(以:開始),或匿名,以?表示

The syntax used depends on the replacements option passed to the function:

使用的語法取決於傳遞給函數的替代選項

  • If an array is passed, ? will be replaced in the order that they appear in the array若是經過的是數組,?將會按照他們在數組中出現的順序來進行替換
  • If an object is passed, :key will be replaced with the keys from that object. If the object contains keys not found in the query or vice versa, an exception will be thrown.若是經過的是對象,:key將會被對象中的keys值替換。若是在查詢中包含keys的對象沒有被找到,將會拋出一個異常;反之亦然。
sequelize
  .query(
    'SELECT * FROM projects WHERE status = ?', { raw: true, replacements: ['active'] ) .then(projects => { console.log(projects) }) sequelize .query( 'SELECT * FROM projects WHERE status = :status ', { raw: true, replacements: { status: 'active' } } ) .then(projects => { console.log(projects) })

One note: If the attribute names of the table contain dots, the resulting objects will be nested:

若是表的屬性名稱包含點,由此產生的對象將被嵌套

sequelize.query('select 1 as `foo.bar.baz`').then(rows => { console.log(JSON.stringify(rows)) /* [{ "foo": { "bar": { "baz": 1 } } }] */ })

 

舉一個簡單的例子,鏈接的是mysql:

const Sequelize = require('sequelize'); const sequelize = new Sequelize('token', 'root', 'user78', { dialect: 'mysql', //默認host和port // host: "127.0.0.1", // port: 3306, }); sequelize.query("SELECT * FROM user").then(myTableRows => { console.log(myTableRows) })

返回:

userdeMacBook-Pro:test-sequelize user$ node index.js 
sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators node_modules/sequelize/lib/sequelize.js:242:13 Executing (default): SELECT * FROM user [ [ TextRow { username: '1', id: 1, password: '1' }, TextRow { username: '12', id: 12, password: '2' }, TextRow { username: 'name', id: 13, password: '1231' }, TextRow { username: 'admin11', id: 21, password: '1111' }, TextRow { username: 'admin11111s', id: 22, password: '1111' }, TextRow { username: 'admin11111s', id: 23, password: 'aa' }, TextRow { username: 'user', id: 24, password: 'user' } ], [ TextRow { username: '1', id: 1, password: '1' }, TextRow { username: '12', id: 12, password: '2' }, TextRow { username: 'name', id: 13, password: '1231' }, TextRow { username: 'admin11', id: 21, password: '1111' }, TextRow { username: 'admin11111s', id: 22, password: '1111' }, TextRow { username: 'admin11111s', id: 23, password: 'aa' }, TextRow { username: 'user', id: 24, password: 'user' } ] ]

警告:

sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators node_modules/sequelize/lib/sequelize.js:242:13

上面警告要解決的問題是:

Let me distill this regardless, Most web frameworks in Node.js allow parsing a object like string to actual JS object. This becomes a major issue when developers are passing user input without sanitizing them to Sequelize methods.

大多數web框架在nodejs容許解析字符串變爲實際js對象這樣的對象。這就變成了一個主要問題當開發人員經過用戶輸入沒有對Sequelize方法進行處理

For example, consider this sample of code好比

db.Token.findOne({
      where: { token: req.query.token } );

Now a bad actor could pass token='{"$gt": 1}' which will make above query to become something like this

這是傳入token='{"$gt": 1}'則會將查詢變爲:

db.Token.findOne({
      where: { token: { $gt: 1 } } );

This is because $gt is a string based operator which can be injected as string. To mitigate this we introduced secure operators #8240

這是由於基於操做符的字符串將會被檢測成字符串,爲了解決這樣的問題,咱們將介紹安全操做符

Secure operators are Symbols which can't be duplicated by such object conversion. If we were using above code with secure operators we get this state 安全操做符都是Symbols對象,是不能被這樣的對象轉換複製的。若是咱們使用上面帶有安全操做符的代碼,咱們將獲得了這種狀態:

db.Token.findOne({
      where: { token: { $gt: 1 // invalid, as Op.gt is an operator but $gt is not. This will throw an error  } } );

是無效的,Op.gt纔是操做符,而$gt不是,因此會拋出錯誤

 

那麼什麼是安全操做符:

http://docs.sequelizejs.com/manual/tutorial/querying.html#operators-security

Operators Aliases操做符別名

Sequelize allows setting specific strings as aliases for operators

Sequelize容許爲操做符設置特殊的字符串做爲別名,好比:

const Op = Sequelize.Op; const operatorsAliases = { $gt: Op.gt } const connection = new Sequelize(db, user, pass, { operatorsAliases }) [Op.gt]: 6 // > 6 $gt: 6 // same as using Op.gt (> 6)
$gt的別名設置爲Op.gt
 

Operators security操做符安全性

Using Sequelize without any aliases improves security. Some frameworks automatically parse user input into js objects and if you fail to sanitize your input it might be possible to inject an Object with string operators to Sequelize.

使用沒有任何別名的Sequelize提升了安全性。有些框架自動解析用戶輸入到js對象若是你未能清潔你的輸入有可能注入Sequelize對象和字符串運算符

Not having any string aliases will make it extremely unlikely that operators could be injected but you should always properly validate and sanitize user input.

向後兼容性緣由Sequelize默認設置下面的別名 - $eq, $ne, $gte, $gt, $lte, $lt, $not, $in, $notIn, $is, $like, $notLike, $iLike, $notILike, $regexp, $notRegexp, $iRegexp, $notIRegexp, $between, $notBetween, $overlap, $contains, $contained, $adjacent, $strictLeft, $strictRight, $noExtendRight, $noExtendLeft, $and, $or, $any, $all, $values, $col

目前如下遺留別名也被設置,但計劃在不久的未來被徹底移除 - ne, not, in, notIn, gte, gt, lte, lt, like, ilike, $ilike, nlike, $notlike, notilike, .., between, !.., notbetween, nbetween, overlap, &&, @>, <@

For better security it is highly advised to use Sequelize.Op and not depend on any string alias at all. You can limit alias your application will need by setting operatorsAliases option, remember to sanitize user input especially when you are directly passing them to Sequelize methods.

爲了更好的安全,強烈建議使用Sequelize.Op和不依賴於任何字符串的別名。你能夠經過設置別名operatorsAliases選項來限制你的應用程序須要的別名,記得要檢查用戶輸入特別是當你直接傳遞他們給Sequelize的方法。

const Op = Sequelize.Op; //use sequelize without any operators aliases,不使用別名 const connection = new Sequelize(db, user, pass, { operatorsAliases: false }); //use sequelize with only alias for $and => Op.and,只使用Op.and一個別名 const connection2 = new Sequelize(db, user, pass, { operatorsAliases: { $and: Op.and } });

Sequelize will warn you if you're using the default aliases and not limiting them if you want to keep using all default aliases (excluding legacy ones) without the warning you can pass the following operatorsAliases option -

若是你使用默認的別名並無進行限制,Sequelize會警告你,因此我獲得了上面的警告。

若是你想繼續使用全部缺省別名(不包括遺留的)沒有警告,您能夠經過設置如下operatorsAliases選項:

const Op = Sequelize.Op; const operatorsAliases = { $eq: Op.eq, $ne: Op.ne, $gte: Op.gte, $gt: Op.gt, $lte: Op.lte, $lt: Op.lt, $not: Op.not, $in: Op.in, $notIn: Op.notIn, $is: Op.is, $like: Op.like, $notLike: Op.notLike, $iLike: Op.iLike, $notILike: Op.notILike, $regexp: Op.regexp, $notRegexp: Op.notRegexp, $iRegexp: Op.iRegexp, $notIRegexp: Op.notIRegexp, $between: Op.between, $notBetween: Op.notBetween, $overlap: Op.overlap, $contains: Op.contains, $contained: Op.contained, $adjacent: Op.adjacent, $strictLeft: Op.strictLeft, $strictRight: Op.strictRight, $noExtendRight: Op.noExtendRight, $noExtendLeft: Op.noExtendLeft, $and: Op.and, $or: Op.or, $any: Op.any, $all: Op.all, $values: Op.values, $col: Op.col }; const connection = new Sequelize(db, user, pass, { operatorsAliases });

 

解決警告的辦法:

因此咱們最好的解決上面的警告的方法就是添加別名定義,將以前的例子改爲下面的樣子,警告將消失:

const Sequelize = require('sequelize'); const Op = Sequelize.Op; const operatorsAliases = { $eq: Op.eq, $ne: Op.ne, $gte: Op.gte, $gt: Op.gt, $lte: Op.lte, $lt: Op.lt, $not: Op.not, $in: Op.in, $notIn: Op.notIn, $is: Op.is, $like: Op.like, $notLike: Op.notLike, $iLike: Op.iLike, $notILike: Op.notILike, $regexp: Op.regexp, $notRegexp: Op.notRegexp, $iRegexp: Op.iRegexp, $notIRegexp: Op.notIRegexp, $between: Op.between, $notBetween: Op.notBetween, $overlap: Op.overlap, $contains: Op.contains, $contained: Op.contained, $adjacent: Op.adjacent, $strictLeft: Op.strictLeft, $strictRight: Op.strictRight, $noExtendRight: Op.noExtendRight, $noExtendLeft: Op.noExtendLeft, $and: Op.and, $or: Op.or, $any: Op.any, $all: Op.all, $values: Op.values, $col: Op.col }; const sequelize = new Sequelize('token', 'root', 'user78', { dialect: 'mysql', operatorsAliases //默認host和port // host: "127.0.0.1", // port: 3306, }); sequelize.query("SELECT * FROM user").then(myTableRows => { console.log(myTableRows) })
相關文章
相關標籤/搜索