数据库支持
- sequelize:
sequelize支持多种关系数据库,包括 MySQL、PostgreSQL、SQLite 和 MSSQL,提供广泛的兼容性和灵活性。 - objection:
objection也基于knex,支持所有knex支持的数据库,包括 MySQL、PostgreSQL 和 SQLite,提供良好的兼容性。 - bookshelf:
bookshelf依赖于knex,支持多种数据库(如 MySQL、PostgreSQL 和 SQLite),但不支持 MSSQL。 - waterline:
waterline支持多种数据库和适配器,包括 MySQL、MongoDB 和 SQLite,提供跨数据库操作的能力。
模型关系
- sequelize:
sequelize提供强大的模型关系支持,包括一对一、一对多和多对多关系,支持延迟加载和预加载。 - objection:
objection强调模型关系的可组合性,支持一对一、一对多和多对多关系,允许使用knex进行自定义查询。 - bookshelf:
bookshelf也支持复杂的模型关系,允许自定义关系和延迟加载,具有更高的灵活性。 - waterline:
waterline提供基本的模型关系支持,包括一对一、一对多和多对多关系,但相对较简单。
查询构建
- sequelize:
sequelize提供强大的查询构建器,支持链式调用、条件查询、聚合函数和事务管理,功能全面。 - objection:
objection继承了knex的查询构建能力,支持复杂查询、嵌套查询和事务,强调类型安全。 - bookshelf:
bookshelf基于knex的查询构建能力,支持链式调用和自定义查询,灵活性高。 - waterline:
waterline提供简单的查询 API,支持链式调用和条件查询,但功能相对较弱。
迁移和种子
- sequelize:
sequelize提供内置的迁移和种子功能,支持命令行工具和 API,易于管理数据库结构和初始数据。 - objection:
objection也依赖于knex的迁移功能,支持自定义迁移和种子脚本。 - bookshelf:
bookshelf不提供内置的迁移功能,但可以与knex的迁移工具结合使用。 - waterline:
waterline提供基本的迁移和种子支持,但功能较为简单。
代码示例
- sequelize:
使用
sequelize创建模型和查询const { Sequelize, DataTypes } = require('sequelize'); const sequelize = new Sequelize('database', 'username', 'password', { dialect: 'mysql' }); const User = sequelize.define('User', { name: DataTypes.STRING, email: DataTypes.STRING }); const Post = sequelize.define('Post', { title: DataTypes.STRING, content: DataTypes.TEXT }); User.hasMany(Post); Post.belongsTo(User); (async () => { await sequelize.sync(); const user = await User.create({ name: 'Alice', email: 'alice@example.com' }); const post = await Post.create({ title: 'Hello World', content: 'This is my first post.', UserId: user.id }); const posts = await User.findByPk(user.id, { include: Post }); console.log(posts); })(); - objection:
使用
objection创建模型和查询const { Model, knex } = require('objection'); const Knex = require('knex'); const knexConfig = { client: 'mysql', connection: { host: 'localhost', user: 'root', password: '', database: 'test' }}; const knex = Knex(knexConfig); Model.knex(knex); class User extends Model { static get tableName() { return 'users'; }} class Post extends Model { static get tableName() { return 'posts'; }} User.hasMany(Post); Post.belongsTo(User); (async () => { await knex.migrate.latest(); const user = await User.query().insert({ name: 'Alice', email: 'alice@example.com' }); const post = await Post.query().insert({ title: 'Hello World', content: 'This is my first post.', userId: user.id }); const posts = await User.query().findById(user.id).withGraphFetched('posts'); console.log(posts); })(); - bookshelf:
使用
bookshelf创建模型和查询const knex = require('knex')({ client: 'mysql', connection: { host: 'localhost', user: 'root', password: '', database: 'test' }}); const bookshelf = require('bookshelf')(knex); const User = bookshelf.model('User', { tableName: 'users' }); const Post = bookshelf.model('Post', { tableName: 'posts' }); User.hasMany(Post); Post.belongsTo(User); (async () => { await knex.migrate.latest(); const user = await new User({ name: 'Alice', email: 'alice@example.com' }).save(); const post = await new Post({ title: 'Hello World', content: 'This is my first post.', user_id: user.id }).save(); const posts = await User.where({ id: user.id }).fetch({ withRelated: ['posts'] }); console.log(posts); })(); - waterline:
使用
waterline创建模型和查询const Waterline = require('waterline'); const mysqlAdapter = require('sails-mysql'); const orm = new Waterline(); const User = Waterline.Collection.extend({ identity: 'user', datastore: 'mysql', attributes: { name: { type: 'string' }, email: { type: 'string' }, posts: { collection: 'post', via: 'user' }} }); const Post = Waterline.Collection.extend({ identity: 'post', datastore: 'mysql', attributes: { title: { type: 'string' }, content: { type: 'string' }, user: { model: 'user' }} }); orm.registerModel(User); orm.registerModel(Post); const config = { adapters: { mysql: mysqlAdapter }, datastores: { mysql: { adapter: 'mysql', host: 'localhost', user: 'root', password: '', database: 'test' }} }; orm.initialize(config, (err, models) => { if (err) throw err; models.user.create({ name: 'Alice', email: 'alice@example.com' }).then(user => { return models.post.create({ title: 'Hello World', content: 'This is my first post.', user: user.id }); }).then(() => { return models.user.findOne({ name: 'Alice' }).populate('posts'); }).then(user => { console.log(user); }); });