@22bate7/bookshelf 中文文档教程
bookshelf.js
Bookshelf 是用于 Node.js 的 JavaScript ORM,构建于 Knex SQL 查询生成器之上。 同时具有基于承诺和传统的回调接口,提供事务支持、渴望/嵌套-渴望关系加载、多态关联以及对一对一、一对多和多对多关系的支持。
它旨在与 PostgreSQL、MySQL 和 SQLite3 很好地配合使用。
网站和文档。 该项目托管在 GitHub 上,并且具有全面的 测试套件。
Introduction
Bookshelf 旨在为在 JavaScript 中查询数据库时的常见任务提供一个简单的库,并在这些对象之间形成关系,从 数据映射器模式。
Bookshelf 具有简洁、有文化的代码库,易于阅读、理解和扩展。 它不会强制您使用任何特定的验证方案,提供灵活高效的关系/嵌套关系加载以及一流的事务支持。
它是一个精简的对象关系映射器,允许您在需要不完全符合库存约定的自定义查询时下拉到原始 knex 界面。
Installation
您需要安装一份 knex.js,以及来自 npm 的 mysql、pg 或 sqlite3。
$ npm install knex --save
$ npm install bookshelf --save
# Then add one of the following:
$ npm install pg
$ npm install mysql
$ npm install mariasql
$ npm install sqlite3
Bookshelf 库通过传递初始化的 Knex 客户端实例来初始化。 knex 文档 提供了许多针对不同数据库的示例。
var knex = require('knex')({
client: 'mysql',
connection: {
host : '127.0.0.1',
user : 'your_database_user',
password : 'your_database_password',
database : 'myapp_test',
charset : 'utf8'
}
});
var bookshelf = require('bookshelf')(knex);
var User = bookshelf.Model.extend({
tableName: 'users'
});
此初始化在您的应用程序中可能只发生一次。 当它为当前数据库创建一个连接池时,您应该使用整个图书馆返回的 bookshelf
实例。 您需要将初始化创建的实例存储在应用程序的某个位置,以便您可以引用它。 要遵循的常见模式是在模块中初始化客户端,以便您以后可以轻松引用它:
// In a file named something like bookshelf.js
var knex = require('knex')(dbConfig);
module.exports = require('bookshelf')(knex);
// elsewhere, to use the bookshelf client:
var bookshelf = require('./bookshelf');
var Post = bookshelf.Model.extend({
// ...
});
Examples
这是一个让您入门的示例:
var knex = require('knex')({client: 'mysql', connection: process.env.MYSQL_DATABASE_CONNECTION });
var bookshelf = require('bookshelf')(knex);
var User = bookshelf.Model.extend({
tableName: 'users',
posts: function() {
return this.hasMany(Posts);
}
});
var Posts = bookshelf.Model.extend({
tableName: 'messages',
tags: function() {
return this.belongsToMany(Tag);
}
});
var Tag = bookshelf.Model.extend({
tableName: 'tags'
})
User.where('id', 1).fetch({withRelated: ['posts.tags']}).then(function(user) {
console.log(user.related('posts').toJSON());
}).catch(function(err) {
console.error(err);
});
Plugins
- Registry: Register models in a central location so that you can refer to them using a string in relations instead of having to require it every time. Helps deal with the challenges of circular module dependencies in Node.
- Virtuals: Define virtual properties on your model to compute new values.
- Visibility: Specify a whitelist/blacklist of model attributes when serialized toJSON.
- Pagination: Adds
fetchPage
methods to use for pagination in place offetch
andfetchAll
.
Community plugins
- bookshelf-cascade-delete - Cascade delete related models on destroy.
- bookshelf-json-columns - Parse and stringify JSON columns on save and fetch instead of manually define hooks for each model (PostgreSQL and SQLite).
- bookshelf-mask - Similar to Visibility but supporting multiple scopes, masking models and collections using the json-mask API.
- bookshelf-schema - A plugin for handling fields, relations, scopes and more.
- bookshelf-signals - A plugin that translates Bookshelf events to a central hub.
- bookshelf-paranoia - Protect your database from data loss by soft deleting your rows.
- bookshelf-uuid - Automatically generates UUIDs for your models.
- bookshelf-modelbase - An alternative to extend
Model
, adding timestamps, attribute validation and some native CRUD methods. - bookshelf-advanced-serialization - A more powerful visibility plugin, supporting serializing models and collections according to access permissions, application context, and after ensuring relations have been loaded.
Support
对库有疑问吗? 快来加入我们的 #bookshelf freenode IRC 频道 以获得对 knex.js 和 bookshelf.js,或在 Stack Overflow 或GitHub 问题跟踪器。
F.A.Q.
Can I use standard node.js style callbacks?
是的 - 您可以在任何“同步”方法上调用 .asCallback(function(err, resp) {
并根据需要使用标准的 (err, result)
样式回调接口.
My relations don't seem to be loading, what's up?
确保检查传递给正在获取的初始模型的初始参数的类型是否正确。例如 new Model({id: '1'}).load([relations...]) 不会返回与
Model({id: 1}).load([relations...])
相同的结果 - 请注意,id 在一种情况下是字符串,在另一种情况下是数字. 如果从 url 参数中检索 id,这可能是一个常见的错误。
只有在您急于加载数据而不首先获取原始模型的情况下,这才是一个问题。Model({id: '1'}) .fetch({withRelated: [relations...]})
应该可以正常工作。
My process won't exit after my script is finished, why?
这里的问题是 Bookshelf 使用的数据库抽象层 Knex 使用连接池,从而保持数据库连接打开。如果你希望你的进程在你的脚本完成后退出,你将有 o 在 Bookshelf
实例的 knex
属性上或在期间传递的 Knex
实例上调用 .destroy(cb)
初始化。 有关连接池的更多信息,请参阅 Knex 文档。
How do I debug?
如果您将 {debug: true}
作为初始化设置中的选项之一传递,您可以看到所有正在进行的查询调用。 有时您需要更深入地研究各种调用,看看幕后发生了什么。 我推荐 node-inspector,它允许您像您一样使用 debugger
语句调试代码会在浏览器中。
”promise 库副本,您可以在此处阅读更多关于调试这些 promise 的信息……但简而言之,添加:
process.stderr.on('data', function(data) {
console.log(data);
});
Bookshelf 使用它自己的“ bluebird handlers,这对调试很有帮助。
How do I run the test suite?
测试套件查找名为 BOOKSHELF_TEST
的环境变量以获取数据库配置的路径。 如果运行以下命令:$ export BOOKSHELF_TEST='/path/to/your/bookshelf_config.js'
,替换为您的配置文件的路径,并且配置文件有效,测试套件应该与 npm test 一起运行。
另请注意,您必须为要运行的测试套件创建适当的数据库。 例如,对于 MySQL,除了在运行测试套件之前导出正确的测试设置之外,您还需要运行命令 create database bookshelf_test;
。
Can I use Bookshelf outside of Node.js?
虽然它主要针对 Node.js,但所有依赖项都与浏览器兼容,并且可以通过提供自定义 Knex 适配器。
Which open-source projects are using Bookshelf?
我们发现了以下使用 Bookshelf 的项目,但还可以有更多:
- Ghost (A blogging platform) uses bookshelf. [Link]
- Soapee (Soap Making Community and Resources) uses bookshelf. [Link]
- NodeZA (Node.js social platform for developers in South Africa) uses bookshelf. [Link]
- Sunday Cook (A social cooking event platform) uses bookshelf. [Link]
- FlyptoX (Open-source Node.js cryptocurrency exchange) uses bookshelf. [Link]
- And of course, everything on here use bookshelf too.
bookshelf.js
Bookshelf is a JavaScript ORM for Node.js, built on the Knex SQL query builder. Featuring both promise based and traditional callback interfaces, providing transaction support, eager/nested-eager relation loading, polymorphic associations, and support for one-to-one, one-to-many, and many-to-many relations.
It is designed to work well with PostgreSQL, MySQL, and SQLite3.
Website and documentation. The project is hosted on GitHub, and has a comprehensive test suite.
Introduction
Bookshelf aims to provide a simple library for common tasks when querying databases in JavaScript, and forming relations between these objects, taking a lot of ideas from the the Data Mapper Pattern.
With a concise, literate codebase, Bookshelf is simple to read, understand, and extend. It doesn't force you to use any specific validation scheme, provides flexible and efficient relation/nested-relation loading, and first class transaction support.
It's a lean Object Relational Mapper, allowing you to drop down to the raw knex interface whenever you need a custom query that doesn't quite fit with the stock conventions.
Installation
You'll need to install a copy of knex.js, and either mysql, pg, or sqlite3 from npm.
$ npm install knex --save
$ npm install bookshelf --save
# Then add one of the following:
$ npm install pg
$ npm install mysql
$ npm install mariasql
$ npm install sqlite3
The Bookshelf library is initialized by passing an initialized Knex client instance. The knex documentation provides a number of examples for different databases.
var knex = require('knex')({
client: 'mysql',
connection: {
host : '127.0.0.1',
user : 'your_database_user',
password : 'your_database_password',
database : 'myapp_test',
charset : 'utf8'
}
});
var bookshelf = require('bookshelf')(knex);
var User = bookshelf.Model.extend({
tableName: 'users'
});
This initialization should likely only ever happen once in your application. As it creates a connection pool for the current database, you should use the bookshelf
instance returned throughout your library. You'll need to store this instance created by the initialize somewhere in the application so you can reference it. A common pattern to follow is to initialize the client in a module so you can easily reference it later:
// In a file named something like bookshelf.js
var knex = require('knex')(dbConfig);
module.exports = require('bookshelf')(knex);
// elsewhere, to use the bookshelf client:
var bookshelf = require('./bookshelf');
var Post = bookshelf.Model.extend({
// ...
});
Examples
Here is an example to get you started:
var knex = require('knex')({client: 'mysql', connection: process.env.MYSQL_DATABASE_CONNECTION });
var bookshelf = require('bookshelf')(knex);
var User = bookshelf.Model.extend({
tableName: 'users',
posts: function() {
return this.hasMany(Posts);
}
});
var Posts = bookshelf.Model.extend({
tableName: 'messages',
tags: function() {
return this.belongsToMany(Tag);
}
});
var Tag = bookshelf.Model.extend({
tableName: 'tags'
})
User.where('id', 1).fetch({withRelated: ['posts.tags']}).then(function(user) {
console.log(user.related('posts').toJSON());
}).catch(function(err) {
console.error(err);
});
Plugins
- Registry: Register models in a central location so that you can refer to them using a string in relations instead of having to require it every time. Helps deal with the challenges of circular module dependencies in Node.
- Virtuals: Define virtual properties on your model to compute new values.
- Visibility: Specify a whitelist/blacklist of model attributes when serialized toJSON.
- Pagination: Adds
fetchPage
methods to use for pagination in place offetch
andfetchAll
.
Community plugins
- bookshelf-cascade-delete - Cascade delete related models on destroy.
- bookshelf-json-columns - Parse and stringify JSON columns on save and fetch instead of manually define hooks for each model (PostgreSQL and SQLite).
- bookshelf-mask - Similar to Visibility but supporting multiple scopes, masking models and collections using the json-mask API.
- bookshelf-schema - A plugin for handling fields, relations, scopes and more.
- bookshelf-signals - A plugin that translates Bookshelf events to a central hub.
- bookshelf-paranoia - Protect your database from data loss by soft deleting your rows.
- bookshelf-uuid - Automatically generates UUIDs for your models.
- bookshelf-modelbase - An alternative to extend
Model
, adding timestamps, attribute validation and some native CRUD methods. - bookshelf-advanced-serialization - A more powerful visibility plugin, supporting serializing models and collections according to access permissions, application context, and after ensuring relations have been loaded.
Support
Have questions about the library? Come join us in the #bookshelf freenode IRC channel for support on knex.js and bookshelf.js, or post an issue on Stack Overflow or in the GitHub issue tracker.
F.A.Q.
Can I use standard node.js style callbacks?
Yes - you can call .asCallback(function(err, resp) {
on any "sync" method and use the standard (err, result)
style callback interface if you prefer.
My relations don't seem to be loading, what's up?
Make sure you check that the type is correct for the initial parameters passed to the initial model being fetched. For example new Model({id: '1'}).load([relations...])
will not return the same as Model({id: 1}).load([relations...])
- notice that the id is a string in one case and a number in the other. This can be a common mistake if retrieving the id from a url parameter.
This is only an issue if you're eager loading data with load without first fetching the original model. Model({id: '1'}).fetch({withRelated: [relations...]})
should work just fine.
My process won't exit after my script is finished, why?
The issue here is that Knex, the database abstraction layer used by Bookshelf, uses connection pooling and thus keeps the database connection open. If you want your process to exit after your script has finished, you will have to call .destroy(cb)
on the knex
property of your Bookshelf
instance or on the Knex
instance passed during initialization. More information about connection pooling can be found over at the Knex docs.
How do I debug?
If you pass {debug: true}
as one of the options in your initialize settings, you can see all of the query calls being made. Sometimes you need to dive a bit further into the various calls and see what all is going on behind the scenes. I'd recommend node-inspector, which allows you to debug code with debugger
statements like you would in the browser.
Bookshelf uses its own copy of the "bluebird" promise library, you can read up here for more on debugging these promises… but in short, adding:
process.stderr.on('data', function(data) {
console.log(data);
});
At the start of your application code will catch any errors not otherwise caught in the normal promise chain handlers, which is very helpful in debugging.
How do I run the test suite?
The test suite looks for an environment variable called BOOKSHELF_TEST
for the path to the database configuration. If you run the following command: $ export BOOKSHELF_TEST='/path/to/your/bookshelf_config.js'
, replacing with the path to your config file, and the config file is valid, the test suite should run with npm test.
Also note that you will have to create the appropriate database(s) for the test suite to run. For example, with MySQL, you'll need to run the command create database bookshelf_test;
in addition to exporting the correct test settings prior to running the test suite.
Can I use Bookshelf outside of Node.js?
While it primarily targets Node.js, all dependencies are browser compatible, and it could be adapted to work with other javascript environments supporting a sqlite3 database, by providing a custom Knex adapter.
Which open-source projects are using Bookshelf?
We found the following projects using Bookshelf, but there can be more:
- Ghost (A blogging platform) uses bookshelf. [Link]
- Soapee (Soap Making Community and Resources) uses bookshelf. [Link]
- NodeZA (Node.js social platform for developers in South Africa) uses bookshelf. [Link]
- Sunday Cook (A social cooking event platform) uses bookshelf. [Link]
- FlyptoX (Open-source Node.js cryptocurrency exchange) uses bookshelf. [Link]
- And of course, everything on here use bookshelf too.