sequelizejs 多表关联以及 Scopes

sequelizejs 多表映射

belongsTo hasOne hasMany belongsTo 都会创建对应映射关系,他们关系如下:

belongsTohasOne 为 1:1 映射, hasMany 为 1:n 映射。 前两者的区别是外键一个会建立在 源 model 上 另一个会建立在参数指定的 model 上。

一般来讲使用 belongsTohasMany 来组成一对儿查询。

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
留言:

称呼:*

邮件:

网站:

内容: