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) })
相关文章
相关标签/搜索