Mysql 通过sequelize协会寻找朋友
我对mysql的续集还是比较陌生的,试图更好地理解关联是如何工作的。我已经创建了一个简单的应用程序,用户可以将彼此添加为好友,如果我是正确的,这将是一个多对多关系 我有一个用户表和一个朋友表。users表是一个典型的users表,friend_binds表的创建方式如下:Mysql 通过sequelize协会寻找朋友,mysql,node.js,sequelize.js,Mysql,Node.js,Sequelize.js,我对mysql的续集还是比较陌生的,试图更好地理解关联是如何工作的。我已经创建了一个简单的应用程序,用户可以将彼此添加为好友,如果我是正确的,这将是一个多对多关系 我有一个用户表和一个朋友表。users表是一个典型的users表,friend_binds表的创建方式如下: CREATE TABLE `friend_binds` ( `id` char(36) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, `friend_id` cha
CREATE TABLE `friend_binds` (
`id` char(36) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`friend_id` char(36) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`parent_id` char(36) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `friendKey` (`parent_id`,`friend_id`),
CONSTRAINT `friend_binds_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
我最初的工作方式是每次我添加一个朋友时,会有两个条目进入到朋友绑定(a到B和B到a)。这种方法对我很有效,我可以拉朋友,不管他们是A还是B
原始用户模型关联:
User.associate = models => {
User.hasMany(models.friendBind, {
foreignKey: {
name: 'parentId',
allowNull: false
},
onDelete: 'cascade',
hooks: true
})
}
FriendBind.associate = models => {
FriendBind.belongsTo(models.user, {
foreignKey: {
name: 'parentId',
type: DataTypes.UUID,
allowNull: false
},
onDelete: 'cascade'
})
}
原始模型关联:
User.associate = models => {
User.hasMany(models.friendBind, {
foreignKey: {
name: 'parentId',
allowNull: false
},
onDelete: 'cascade',
hooks: true
})
}
FriendBind.associate = models => {
FriendBind.belongsTo(models.user, {
foreignKey: {
name: 'parentId',
type: DataTypes.UUID,
allowNull: false
},
onDelete: 'cascade'
})
}
我想看看我是否能做到,这样我就只需要在friend_binds表中输入一个条目(即A到B)。我最终想添加一个状态列(sent、seen、rejected等),我觉得每次都要更新两行只是做错了
我现在遇到的问题是,当我使用user.getFriends()时,它只会获取用户是朋友A(父id)的朋友。如果用户是A或B,我认为我应该能够找到记录,这是错误的吗?我是否只需要两次.findAll(),一次搜索parentId,一次搜索friendId
这是新用户协会
User.associate = models => {
User.belongsToMany(models.user, {
as: "friends",
through: "friend_binds",
foreignKey: "userId",
otherKey: "friendId"
})
}
在这个例子中,我在某个地方读到,我甚至不需要定义我的friend_binds表,因为sequelize为我创建了它,所以我就是这样做的
为friend_运行的新查询绑定创建表
CREATE TABLE `friend_binds` (
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`user_id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`friend_id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
PRIMARY KEY (`user_id`,`friend_id`),
KEY `friend_id` (`friend_id`),
CONSTRAINT `friend_binds_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `friend_binds_ibfk_2` FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
查找好友的相关代码
module.exports.getFriendsNew = async (req, res) => {
try {
const user = await db.user
.findByPk(req.user.id)
.catch(error => { throw new Error(error) })
const friends = await user
.getFriends()
.then(results => {
if (results.length === 0) { throw new Error("You have no friends") }
return results
})
.catch(error => { throw new Error(error) })
res.send(friends)
} catch (error) {
res.send(error.message)
}
}res.send(error)
}
使用此代码,我可以找到朋友A记录,但如果我搜索朋友B,它将返回0个朋友。A
用户
可以有许多朋友,而该朋友也是用户
可以有许多同样是用户
的朋友
显然,用户
和用户
之间存在多对多关系
要保持这种关系,您需要定义一个透视表。我称之为UsersFriends
因此,你的关联如下所示
User.belongsToMany(models.User, {
as: 'friends',
foreignKey: 'user_id',
through: UsersFriends
});
User.belongsToMany(models.User, {
as: 'userFriends',
foreignKey: 'friend_id',
through: UsersFriends
});
// UsersFriends
module.exports = (sequelize, DataTypes) => {
const TaskSparePart = sequelize.define('UsersFriends', {
user_id: DataTypes.BIGINT,
friend_id: DataTypes.BIGINT,
created_at: DataTypes.DATE,
updated_at: DataTypes.DATE,
}, {
tableName: 'users_friends',
});
return UsersFriends;
};
// To get friends
module.exports.getFriends = async (req, res) => {
try {
const user = await db.User.findOne({
where: {
id: req.user.id,
},
include: 'friends'
})
if (!user) throw new Error('User not found!');
res.send(user.friends);
} catch (error) {
res.send(error.message)
}
}
一个
用户
可以有很多朋友,而这个朋友,也就是用户
可以有很多朋友,也就是用户
显然,用户
和用户
之间存在多对多关系
要保持这种关系,您需要定义一个透视表。我称之为UsersFriends
因此,你的关联如下所示
User.belongsToMany(models.User, {
as: 'friends',
foreignKey: 'user_id',
through: UsersFriends
});
User.belongsToMany(models.User, {
as: 'userFriends',
foreignKey: 'friend_id',
through: UsersFriends
});
// UsersFriends
module.exports = (sequelize, DataTypes) => {
const TaskSparePart = sequelize.define('UsersFriends', {
user_id: DataTypes.BIGINT,
friend_id: DataTypes.BIGINT,
created_at: DataTypes.DATE,
updated_at: DataTypes.DATE,
}, {
tableName: 'users_friends',
});
return UsersFriends;
};
// To get friends
module.exports.getFriends = async (req, res) => {
try {
const user = await db.User.findOne({
where: {
id: req.user.id,
},
include: 'friends'
})
if (!user) throw new Error('User not found!');
res.send(user.friends);
} catch (error) {
res.send(error.message)
}
}
这仍然只适用于一种方式,它将只查找用户id位于user_id中的关系。因此,friend_id中的用户搜索他们的朋友,它仍然返回0个朋友使用此模型,在my getFriends函数中,我可以同时使用.getFriends和.getUserFriends。这对我来说很有效,我肯定我遗漏了一些关于关联的信息,在这些关联中我可以找到friend\u bind记录,其中用户id是父id或friend\u id。或者其他方式,你必须在
friends
中包含用户朋友
。这仍然只适用于一种方式,它将只查找用户id位于用户id中的关系。因此,在朋友id中的用户搜索他们的朋友时,它仍然返回0个朋友使用此模型,在my getFriends函数中,我可以同时使用.getFriends和.getUserFriends。这对我来说很有效,我肯定我遗漏了一些关于关联的信息,在这些关联中我可以找到friend\u bind记录,其中用户id是父id或friend\u id。另外,您必须将用户朋友
包含在朋友
中。