sequelizejs 多表映射
belongsTo hasOne hasMany belongsTo 都会创建对应映射关系,他们关系如下:
belongsTo
和 hasOne
为 1:1 映射, hasMany
为 1:n 映射。 前两者的区别是外键一个会建立在 源 model 上 另一个会建立在参数指定的 model 上。
一般来讲使用 belongsTo
与 hasMany
来组成一对儿查询。
ps:
A.belongsTo(B); //外键在 A 上
A.hasOne(B); //外键在 B 上。
//A.belongsTo(B) 与 B.hasOne(A) 达到的效果是一样的,只不过外间的位置不同。
B.hasMany(A); //外键在 A 上和 A.belongsTo(B) 相同。
//A.belongsTo(B) 与 B.hasMany(A) 可以连成一对来使用。
很多时候,belongsTo 和 hasOne 的区别仅仅是语义上的,上个例子:
const Team = sequelize.define('team', { /* attributes */ });
const Player = sequelize.define('player', { /* attributes */ })
Player.belongsTo(Team); // 1:1 映射。 增加 player.getTeam() 函数。
//上面等同于下面 ,所以只能存在一个。
Team.hasOne(Player); //不常用,不会增加 player.getTeam() 函数。
Team.hasMany(Player); // 1:n 映射。 增加 team.getPlayers() 函数
一旦建立了映射,查询出的模型就会增加对应的函数 getTeam getPlayers 都返回一个 Promise 对象
Team.findById(1).then(team => {
var playerList = team.getPlayers({
where: {
}
}); // Promise 对象
playerList.then(data => {
console.log(data); // [Model]
})
});
Player.findById(1).then(player => { // Promise 对象
var team = player.getTeam({
where: {
}
});
team.then(data => {
console.log(data);// Model
})
});
当然也可以使用 include 参数来进行 innerJoin
Player.findAll({
include: [Team]
}).then(player => {
console.log(player[0]);
});
Team.findAll({
include: [Player]
}).then(team => {
console.log(team[0]); // []
});
belongsToMany 会建立 n:m 的映射,举个例子如果一个队员A 即可以是篮球队的,也同时可以是足球队的,那么 队员 与 球队之间的关系就是 n:m
Player.belongsToMany(Team, { through: TeamPlayerMap })
Team.belongsToMany(Player, { through: TeamPlayerMap })
TeamPlayerMap 会在调用 sequelize.sync(); 是被创建。
Scopes
Scopes 可以方便的添加一些默认的条件,一些常用的 where 条件可以被集成进去:
const Project = sequelize.define('project', {
// Attributes
}, {
defaultScope: {
where: {
active: true
}
},
scopes: {
deleted: {
where: {
deleted: true
}
}
}
});
defaultScope 是每次查询都会被调用的 可以使用 .unscoped()
或 .scope(null)
来禁止。
User.unscoped().findAll()
User.scope(null).findAll()
以名称方式调用某个 scope
const DeletedProjects = Project.scope('deleted');
DeletedProjects.findAll();
// some time passes
// let's look for deleted projects again!
DeletedProjects.findAll();
多个 scope 可以自动被 merge
// These two are equivalent
Project.scope('deleted', 'activeUsers').findAll();
Project.scope(['deleted', 'activeUsers']).findAll();
等于如下sql
SELECT * FROM projects
INNER JOIN users ON projects.userId = users.id
AND users.active = true