使用Bookshelf进行查询:文档示例理解求助
我来把这段Bookshelf.js的示例拆解得明明白白,帮你理清每一步的逻辑:
先搞懂整体作用
这段代码是Bookshelf最核心的数据库模型定义+关联关系配置流程,本质是通过Bookshelf(基于Knex的ORM框架)把数据库表映射成JS模型,同时建立表之间的关联(比如用户和帖子的一对多、帖子和标签的多对多)。
逐行拆解代码
1. 初始化Knex(数据库连接层)
var knex = require('knex')({ client: 'mysql', connection: process.env.MYSQL_DATABASE_CONNECTION });
- Knex是Bookshelf的底层依赖,负责处理实际的数据库连接和SQL生成
client: 'mysql':指定使用MySQL数据库驱动(Bookshelf还支持PostgreSQL、SQLite等,换这里的参数就行)connection: process.env.MYSQL_DATABASE_CONNECTION:从环境变量读取数据库连接信息(格式一般是mysql://用户名:密码@主机:端口/数据库名),比硬写密码更安全
2. 绑定Knex到Bookshelf
var bookshelf = require('bookshelf')(knex);
Bookshelf本身不直接管数据库连接,必须绑定一个初始化好的Knex实例,之后所有Bookshelf的操作都会通过这个Knex实例执行。
3. 定义模型(对应数据库表)
Bookshelf里的Model就是数据库表的JS映射,每个模型对应一张表,通过tableName指定表名。
3.1 User模型(对应users表)
var User = bookshelf.Model.extend({ tableName: 'users', posts: function() { return this.hasMany(Posts); } });
tableName: 'users':明确这个模型对应数据库里的users表(比如表中有id、name、email等字段,模型会自动映射这些字段,不用手动定义)posts: function():定义一对多关联:一个用户可以有多篇帖子this.hasMany(Posts):表示当前User实例拥有多个Posts实例,底层会自动关联外键(默认是posts表的user_id字段关联users表的id字段;如果外键不是这个名字,需要手动指定,比如hasMany(Posts, 'author_id'))- ❌ 示例里的坑:这里引用
Posts的时候,Posts模型还没定义,实际运行会报ReferenceError!解决办法:要么把Posts模型定义在User前面,要么改成延迟引用(比如return this.hasMany(require('./post-model')))
3.2 Posts模型(对应messages表?大概率是笔误)
var Posts = bookshelf.Model.extend({ tableName: 'messages', tags: function() { return this.belongsToMany(Tag); } });
tableName: 'messages':这里明显不合理——模型叫Posts却对应messages表,应该是示例笔误,实际应该写tableName: 'posts'tags: function():定义多对多关联:一篇帖子可以有多个标签,一个标签也可以对应多篇帖子this.belongsToMany(Tag):多对多关联需要一张中间表(默认是按两个表名的字母序拼接,比如posts_tags,存储post_id和tag_id两个外键);如果中间表名或外键不是默认值,需要手动指定,比如belongsToMany(Tag, 'post_tag_relation', 'post_id', 'tag_id')
3.3 未写完的Tag模型
示例最后是var Tag = bo...,完整的Tag模型应该是这样:
var Tag = bookshelf.Model.extend({ tableName: 'tags', posts: function() { return this.belongsToMany(Posts); } });
- 对应数据库的
tags表,同时定义反向的多对多关联——从Tag也能拿到对应的所有帖子,实现双向关联查询
核心逻辑总结
整个流程是:
- 用Knex建立数据库连接
- 让Bookshelf绑定这个连接
- 为每个数据库表定义模型,同时声明模型间的关联关系
- 之后就可以用模型做关联查询,比如:
- 查ID为1的用户的所有帖子:
User.where('id', 1).fetch({withRelated: ['posts']}) .then(user => console.log(user.toJSON().posts)) - 查ID为1的帖子的所有标签:
Posts.where('id', 1).fetch({withRelated: ['tags']}) .then(post => console.log(post.toJSON().tags))
- 查ID为1的用户的所有帖子:
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

