bookshelf vs knex vs sequelize vs typeorm
Node.js ORM Libraries
bookshelfknexsequelizetypeorm类似的npm包:

Node.js ORM Libraries

Node.js ORM(对象关系映射)库用于简化与数据库的交互,提供了一种更高层次的抽象,使开发者能够使用JavaScript对象而不是SQL查询来操作数据库。这些库通常支持多种数据库,提供了模型定义、关系管理和查询构建等功能,旨在提高开发效率和代码可维护性。选择合适的ORM库可以显著影响应用程序的性能、可扩展性和开发体验。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
bookshelf06,357-2386 年前MIT
knex020,266916 kB7063 天前MIT
sequelize030,3482.91 MB1,0272 个月前MIT
typeorm036,47020.8 MB5175 个月前MIT

功能对比: bookshelf vs knex vs sequelize vs typeorm

设计原则

  • bookshelf:

    Bookshelf遵循简单和易用的设计原则,旨在快速上手并提供基本的ORM功能。它依赖于Knex.js作为查询构建器,强调模型和关系的简单定义。

  • knex:

    Knex.js的设计原则是灵活性和可扩展性,提供了一个强大的查询构建器,允许开发者以链式调用的方式构建SQL查询,适合需要高度自定义的场景。

  • sequelize:

    Sequelize的设计原则是功能丰富和易用性,提供了大量的内置功能,如模型验证、钩子、事务等,旨在简化复杂应用的开发。

  • typeorm:

    TypeORM的设计原则是类型安全和灵活性,支持Active Record和Data Mapper两种模式,适合TypeScript开发者,强调使用装饰器和类来定义模型和关系。

学习曲线

  • bookshelf:

    Bookshelf的学习曲线相对平缓,适合初学者和快速开发,文档清晰,易于理解基本概念和使用方法。

  • knex:

    Knex.js的学习曲线较陡,因为它不提供ORM功能,开发者需要对SQL有一定了解,才能充分利用其查询构建能力。

  • sequelize:

    Sequelize的学习曲线适中,虽然功能丰富,但文档详细,提供了大量示例,适合中级开发者学习和使用。

  • typeorm:

    TypeORM的学习曲线相对较高,尤其是对于不熟悉TypeScript的开发者,但其类型安全和强大的功能使得投资学习是值得的。

性能

  • bookshelf:

    Bookshelf的性能依赖于Knex.js的查询构建能力,适合小型到中型项目,但在处理复杂查询时可能会受到限制。

  • knex:

    Knex.js的性能非常高效,能够生成优化的SQL查询,适合需要高性能和复杂查询的应用。

  • sequelize:

    Sequelize的性能在处理复杂关系和大量数据时可能会受到影响,尤其是在使用事务时,但其优化选项可以帮助提高性能。

  • typeorm:

    TypeORM在处理复杂关系时性能良好,支持懒加载和查询优化,适合需要高性能和类型安全的应用。

扩展性

  • bookshelf:

    Bookshelf的扩展性较好,支持插件和自定义模型方法,适合需要快速迭代和扩展的项目。

  • knex:

    Knex.js的扩展性非常强,允许开发者自定义查询构建器和插件,适合需要高度定制的应用。

  • sequelize:

    Sequelize提供了丰富的扩展功能,如模型钩子、验证和自定义查询,适合需要复杂业务逻辑的项目。

  • typeorm:

    TypeORM的扩展性强,支持多种数据库和复杂关系,适合需要灵活性和可扩展性的应用。

社区支持

  • bookshelf:

    Bookshelf拥有一个小而活跃的社区,提供了基本的支持和文档,但相较于其他库,资源较少。

  • knex:

    Knex.js拥有一个庞大的社区和丰富的文档,开发者可以轻松找到支持和示例。

  • sequelize:

    Sequelize拥有一个活跃的社区和大量的文档、教程和示例,适合需要社区支持的开发者。

  • typeorm:

    TypeORM的社区正在快速增长,提供了良好的文档和支持,尤其是在TypeScript开发者中。

如何选择: bookshelf vs knex vs sequelize vs typeorm

  • bookshelf:

    选择Bookshelf如果你需要一个简单的ORM,易于使用且与Knex.js紧密集成,适合小型到中型项目。它支持模型关系和基本的CRUD操作,适合快速开发原型。

  • knex:

    选择Knex.js如果你需要一个灵活的SQL查询构建器,能够直接与SQL数据库交互,适合需要自定义复杂查询的项目。Knex不提供ORM功能,但它的灵活性和强大的查询构建能力使其适合高级用户。

  • sequelize:

    选择Sequelize如果你需要一个功能丰富的ORM,支持多种数据库(如PostgreSQL、MySQL、SQLite等),并且需要复杂的模型关系和事务管理。Sequelize提供了丰富的功能和良好的文档,适合中到大型项目。

  • typeorm:

    选择TypeORM如果你在使用TypeScript并需要一个支持Active Record和Data Mapper模式的ORM。TypeORM提供了强大的装饰器支持和灵活的查询构建,适合需要TypeScript类型安全和复杂关系的项目。

bookshelf的README

bookshelf.js

NPM Version Build Status Dependency Status devDependency Status

Bookshelf is a JavaScript ORM for Node.js, built on the Knex SQL query builder. It features both Promise-based and traditional callback interfaces, 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 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 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, and provides flexible, 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, and either mysql, pg, or sqlite3 from npm.

$ npm install knex
$ npm install bookshelf

# Then add one of the following:
$ npm install pg
$ npm install mysql
$ 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.

// Setting up the database connection
const knex = require('knex')({
  client: 'mysql',
  connection: {
    host     : '127.0.0.1',
    user     : 'your_database_user',
    password : 'your_database_password',
    database : 'myapp_test',
    charset  : 'utf8'
  }
})
const bookshelf = require('bookshelf')(knex)

// Defining models
const User = bookshelf.model('User', {
  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, e.g. bookshelf.js
const knex = require('knex')(dbConfig)
module.exports = require('bookshelf')(knex)

// elsewhere, to use the bookshelf client:
const bookshelf = require('./bookshelf')

const Post = bookshelf.model('Post', {
  // ...
})

Examples

Here is an example to get you started:

const knex = require('knex')({
  client: 'mysql',
  connection: process.env.MYSQL_DATABASE_CONNECTION
})
const bookshelf = require('bookshelf')(knex)

const User = bookshelf.model('User', {
  tableName: 'users',
  posts() {
    return this.hasMany(Posts)
  }
})

const Post = bookshelf.model('Post', {
  tableName: 'posts',
  tags() {
    return this.belongsToMany(Tag)
  }
})

const Tag = bookshelf.model('Tag', {
  tableName: 'tags'
})

new User({id: 1}).fetch({withRelated: ['posts.tags']}).then((user) => {
  console.log(user.related('posts').toJSON())
}).catch((error) => {
  console.error(error)
})

Official Plugins

  • Virtuals: Define virtual properties on your model to compute new values.
  • Case Converter: Handles the conversion between the database's snake_cased and a model's camelCased properties automatically.
  • Processor: Allows defining custom processor functions that handle transformation of values whenever they are .set() on a model.

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 the functionality of the {@link Model#visible} attribute 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.
  • bookshelf-plugin-mode - Plugin inspired by the functionality of the {@link Model#visible} attribute, allowing to specify different modes with corresponding visible/hidden fields of model.
  • bookshelf-secure-password - A plugin for easily securing passwords using bcrypt.
  • bookshelf-default-select - Enables default column selection for models. Inspired by the functionality of the {@link Model#visible} attribute, but operates on the database level.
  • bookshelf-ez-fetch - Convenient fetching methods which allow for compact filtering, relation selection and error handling.
  • bookshelf-manager - Model & Collection manager to make it easy to create & save deep, nested JSON structures from API requests.

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.

Contributing

If you want to contribute to Bookshelf you'll usually want to report an issue or submit a pull-request. For this purpose the online repository is available on GitHub.

For further help setting up your local development environment or learning how you can contribute to Bookshelf you should read the Contributing document available on GitHub.

F.A.Q.

Can I use standard node.js style callbacks?

Yes, you can call .asCallback(function(err, resp) { on any database operation 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 to 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 new 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. new 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 in the options object to your knex initialize call, you can see all of the query calls being made. You can also pass that same option to all methods that access the database, like model.fetch() or model.destroy(). Examples:

// Turning on debug mode for all queries
const knex = require('knex')({
  debug: true,
  client: 'mysql',
  connection: process.env.MYSQL_DATABASE_CONNECTION
})
const bookshelf = require('bookshelf')(knex)

// Debugging a single query
new User({id: 1}).fetch({debug: true, withRelated: ['posts.tags']}).then(user => {
  // ...
})

Sometimes you need to dive a bit further into the various calls and see what all is going on behind the scenes. You can use 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 Promises.

Adding the following block 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:

process.stderr.on('data', (data) => {
  console.log(data)
})

How do I run the test suite?

See the CONTRIBUTING document on GitHub.

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. No such adapter exists though.

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.