一、生成模型 Game(游戏表)GameGrades(游戏成绩表)GameUser(用户表)
1.1 对非中间表 做多对多逻辑处理
- Game模型
static associate(models) {
// define association here
models.GameUser.belongsToMany(models.Game, {
through: models.GameGrade,
foreignKey: 'userId',
as: 'GameGradesUser'
})
}
- GameUser模型
static associate(models) {
// define association here
models.GameUser.belongsToMany(models.Game, {
through: models.GameGrade,
foreignKey: 'userId',
as: 'GameGradesUser'
})
}
对中间表 做逻辑处理
- GameGrades 模型
models.GameGrade.belongsTo(models.Game, {foreignKey: 'gameId'})
models.GameGrade.belongsTo(models.GameUser, {foreignKey: 'userId'})
二、某一游戏根据游戏降序排名
主要代码:通过搜索中间表关联 两张表
const query = req.query;
const currentPage = Math.abs(Number(query.currentPage)) || 1;
const pageSize = Math.abs(Number(query.pageSize)) || 10;
const offset = (currentPage - 1) * pageSize;
const gameList = await GameGrade.findAll({
where: {
gameId: IsExistGame.id
},
attributes: ['grade'], // GameGrade表中要显示的字段
order: [['grade', 'desc']], // 排序方式
limit: pageSize, // 一页多少条
offset, // 偏移量
include: [{
model: Game, attributes: ['name'] // 关联表 及显示的字段
}, {
model: GameUser, attributes: ['name', 'avatar'] // 关联表 及显示的字段
}]
})
完整代码:
router.get('/', async function (req, res) {
// currentPage pageSize gameName
try {
const query = req.query;
const currentPage = Math.abs(Number(query.currentPage)) || 1;
const pageSize = Math.abs(Number(query.pageSize)) || 10;
const offset = (currentPage - 1) * pageSize;
// 是否存在游戏
const IsExistGame = await Game.findOne({
where: {
name: query.gameName
}
})
// 数据库没有游戏
if (!IsExistGame) {
throw new NotFound(`ID: ${ query.gameName}不存在。`)
}
const rankList = await GameGrade.findAll({
where: {
gameId: IsExistGame.id
},
attributes: ['grade'],
order: [['grade', 'desc']],
limit: pageSize,
offset,
include: [{
model: Game, attributes: ['name']
}, {
model: GameUser, attributes: ['name', 'avatar']
}]
})
// 格式化数据
const formattedRankList = rankList.map(item => ({
username: item.GameUser.name,
game: item.Game.name,
grade: item.grade,
avatar: item.GameUser.avatar
}));
success(res, '查询成功', formattedRankList)
} catch
(error) {
failure(res, error);
}
})
格式化后