Node.js的ORM映射器Sequelize的关联
协会的总结
属于
具有一个相关性。
- 例) Players.belongsTo(Teams)
球员表将自动添加外键teamId。
只有一个
具有一个相关。
- 例) Players.hasOne(Profiles)
在Profiles表中,将添加一个外键playerId,并且该外键是自动追加的。在进行include操作时,只会输出第一条记录。
拥有许多
具有多个关联。
- 例) Players.hasMany(Profiles)
在 Profiles 表中,外键 playerId 会自动添加。在 include 时,会输出多个记录。
属于许多
具有多对多的中间表。
-
- 例1)Players.belongsToMany(Teams, { through: TeamPlayers })
-
- 中間テーブル’TeamPlayers’が作成され、そこに外部キーteamId playerIdが自動追加される
-
- 例2)Teams.belongsToMany(Players, { through: TeamPlayers })
- 中間テーブル’TeamPlayers’が作成され、そこに外部キーplayerId teamIdが自動追加される
belongTo和hasOne的区别在于
动作几乎相同,只是顺序发生了变化。
属于之样本
// model(テーブル)を定義
// 主キー`id`や`createdAt`、`updatedAt`は勝手に定義されるので記述不要
const Players = sequelize.define('players', {
name: Sequelize.STRING,
});
const Teams = sequelize.define('teams', {
name: Sequelize.STRING,
});
Players.belongsTo(Teams, { foreignKey: 'team_id' }) // playersに外部キー'team_id'が作成される。foreignKeyを省略した場合、キャメルケースでid名'teamId'が自動生成される
// modelを元にDBテーブルの作成({force:true}オプションは、テーブルdrop&create)
await Players.sync({ force: true });
await Teams.sync({ force: true });
// レコードのcreate
const team1 = await Teams.create({ name: 'team1' });
const player1 = await Players.create({ name: 'player1', team_id: team1.id });
// レコード取得
const player = await Players.findById(player1.id, { include: Teams })
console.log(player.get({ plain: true }))
输出结果
{ id: 1,
name: 'player1',
createdat: 2019-08-29t02:36:21.464z,
updatedat: 2019-08-29t02:36:21.464z,
team_id: 1,
team:
{ id: 1,
name: 'team1',
createdat: 2019-08-29t02:36:21.448z,
updatedat: 2019-08-29t02:36:21.448z } }
尽管以下可能通过团队 : 球员 = 1: n 的方式获得,但是无法实现。
const team = await Teams.findById(team1.id, { include: Players})
输出结果 (chū lì jié guǒ)
failed: sequelizeeagerloadingerror: players is not associated to teams!
有一个示例
// model(テーブル)を定義
const Players = sequelize.define('players', {
name: Sequelize.STRING,
});
const Profiles= sequelize.define('profiles', {
name: Sequelize.STRING,
});
Players.hasOne(Profiles,{foreignKey:'player_id'})
// modelを元にDBテーブルの作成
await Players.sync({ force: true });
await Profiles.sync({ force: true });
// レコードのcreate
const player1= await Players.create({ name: 'player1' });
const profile1= await Profiles.create({ name: 'profile1', player_id: player1.id });
const profile2= await Profiles.create({ name: 'profile2', player_id: player1.id });
// レコードの取得
const player = await Players.findById(player1.id, { include: Profiles})
console.log(player.get({ plain: true }))
输出结果
{ id: 1,
name: 'player1',
createdAt: 2019-08-29T03:59:30.432Z,
updatedAt: 2019-08-29T03:59:30.432Z,
profile:
{ id: 1,
name: 'profile1',
createdAt: 2019-08-29T03:59:30.448Z,
updatedAt: 2019-08-29T03:59:30.448Z,
player_id: 1 } }
有许多示例
// model(テーブル)を定義
const Players = sequelize.define('players', {
name: Sequelize.STRING,
});
const Profiles= sequelize.define('profiles', {
name: Sequelize.STRING,
});
Players.hasMany(Profiles,{foreignKey:'player_id'})
// modelを元にDBテーブルの作成
await Players.sync({ force: true });
await Profiles.sync({ force: true });
// レコードのcreate
const player1= await Players.create({ name: 'player1' });
const profile1= await Profiles.create({ name: 'profile1', player_id: player1.id });
const profile2= await Profiles.create({ name: 'profile2', player_id: player1.id });
// レコードの取得
const player = await Players.findById(player1.id, { include: Profiles})
// hasOneだと最初の1件しか取得できないがhasManyだと全て取得できる
console.log(player.get({ plain: true }))
输出结果
{ id: 1,
name: 'player1',
createdAt: 2019-08-29T04:13:05.396Z,
updatedAt: 2019-08-29T04:13:05.396Z,
profiles:
[ { id: 1,
name: 'profile1',
createdAt: 2019-08-29T04:13:05.412Z,
updatedAt: 2019-08-29T04:13:05.412Z,
player_id: 1 },
{ id: 2,
name: 'profile2',
createdAt: 2019-08-29T04:13:05.428Z,
updatedAt: 2019-08-29T04:13:05.428Z,
player_id: 1 } ] }
属于多对多关系的示例
// model(テーブル)を定義
// 主キー'id'や'createdAt'、'updatedAt'は勝手に定義されるので記述不要
const Players = sequelize.define('players', {
name: Sequelize.STRING,
});
const Teams = sequelize.define('teams', {
name: Sequelize.STRING,
});
const TeamPlayers = sequelize.define('team_players', {
name: Sequelize.STRING,
});
// 中間テーブル'TeamPlayers'を作成し、そこに'team_id'を追加する
Players.belongsToMany(Teams, { through: TeamPlayers, foreignKey: 'team_id' })
// 中間テーブル'TeamPlayers'を作成し、そこに'team_id'を追加する
Teams.belongsToMany(Players, { through: TeamPlayers, foreignKey: 'player_id' })
await TeamPlayers.sync({ force: true });
await Players.sync({ force: true });
await Teams.sync({ force: true });
// レコードのcreate
const team1 = await Teams.create({ name: 'team1' });
const team2 = await Teams.create({ name: 'team2' });
const player1 = await Players.create({ name: 'player1' });
player1.addTeam(team1,{ status: 'started' })
player1.addTeam(team2,{ status: 'started' })
const player2 = await Players.create({ name: 'player2' });
player2.addTeam(team1,{ status: 'started' })
player2.addTeam(team2,{ status: 'started' })
// レコード取得
const player = await Players.findById(player1.id, { include: Teams })
console.log(player.get({ plain: true }))
const team= await Teams.findById(team1.id, { include: Players})
console.log(team.get({ plain: true }))
输出结果
{ id: 1,
name: 'player1',
createdAt: 2019-08-29T05:56:11.200Z,
updatedAt: 2019-08-29T05:56:11.200Z,
teams:
[ { id: 1,
name: 'team1',
createdAt: 2019-08-29T05:56:11.168Z,
updatedAt: 2019-08-29T05:56:11.168Z,
team_players: [Object] },
{ id: 2,
name: 'team2',
createdAt: 2019-08-29T05:56:11.184Z,
updatedAt: 2019-08-29T05:56:11.184Z,
team_players: [Object] } ] }
{ id: 1,
name: 'team1',
createdAt: 2019-08-29T05:56:11.168Z,
updatedAt: 2019-08-29T05:56:11.168Z,
players:
[ { id: 1,
name: 'player1',
createdAt: 2019-08-29T05:56:11.200Z,
updatedAt: 2019-08-29T05:56:11.200Z,
team_players: [Object] },
{ id: 2,
name: 'player2',
createdAt: 2019-08-29T05:56:11.217Z,
updatedAt: 2019-08-29T05:56:11.217Z,
team_players: [Object] } ] }