場景回顧
數據庫:Mysql5
Sequelize版本:5.21.5
我們有兩個表,分別爲 用戶表(user)和文章表(article),建立Sequelize模型如下
User.js
module.exports = function (sequelize, DataTypes) {
return sequelize.define('user', {
id: { // 編號
type: DataTypes.BIGINT,
primaryKey: true,
autoIncrement: true
},
name: { // 暱稱
type: DataTypes.STRING(32),
defaultValue: ''
},
avatar: { // 頭像
type: DataTypes.STRING(1000),
defaultValue: ''
},
});
};
Article.js
module.exports = function (sequelize, DataTypes) {
return sequelize.define('article', {
id: { // 編號
type: DataTypes.BIGINT,
primaryKey: true,
autoIncrement: true
},
title: { // 標題
type: DataTypes.STRING(32),
defaultValue: ''
},
user_id: { // 玩家ID
type: DataTypes.STRING(1000),
defaultValue: '',
references: {
model: 'User',
key: 'id'
},
},
});
};
模型關係如下:
association.js
User.hasMany(Article, {foreignKey: 'user_id', as:'article'});
Article.belongsTo(User, {foreignKey: 'user_id'});
我們使用findAndCountAll進行分頁查詢User列表,如下:
const page = 1, count = 20;
const { count, rows } = await User.findAndCountAll({
offset: (page - 1) * count,
limit: count,
where: filters,
});
生成對應的SQL語句如下
SELECT `id`,`name`, `avatar` FROM `user` AS `user` LIMIT 0, 20;
如果希望在用戶列表顯示該用戶的文章數量,我們使用include進行關聯查詢,如下:
const page = 1, count = 20;
const { count, rows } = await User.findAndCountAll({
offset: (page - 1) * count,
limit: count,
attributes:['id', 'name', 'avatar', , [sequelize.fn('COUNT', sequelize.col('article.id')), 'article.count']]
include:[{
model: Article,
as: "article",
attributes: []
}],
group: ['user.id']
});
生成SQL語句如下
SELECT `user`.*
FROM (SELECT `user`.`name`, `user`.`avatar`, COUNT(`article`.`id`) AS `article.count`
FROM `user` AS `user` WHERE GROUP BY `user`.`id` LIMIT 0, 20) AS `user`
LEFT OUTER JOIN `article` AS `article` ON `user`.`id` = `article`.`user_id`;
並且報錯:Unknown column 'article.id' in 'field list'
加入沒有進行分頁查詢,如下:
const page = 1, count = 20;
const { count, rows } = await User.findAndCountAll({
attributes:['id', 'name', 'avatar', , [sequelize.fn('COUNT', sequelize.col('article.id')), 'article.count']]
include:[{
model: Article,
as: "article",
attributes: []
}],
group: ['user.id']
});
生成的SQL語句
SELECT `user`.`name`, `user`.`avatar`, COUNT(`article`.`id`) AS `article.count`
FROM `user` AS `user` LEFT OUTER JOIN `article` AS `article` ON `user`.`id` = `article`.`user_id`
GROUP BY `user`.`id`;
這正是我們想要的,問題就在於分頁查詢。
其實我們只需要在include裏面設置一下duplicating屬性爲false就可以了,如下
const page = 1, count = 20;
const { count, rows } = await User.findAndCountAll({
offset: (page - 1) * count,
limit: count,
attributes:['id', 'name', 'avatar', , [sequelize.fn('COUNT', sequelize.col('article.id')), 'article.count']]
include:[{
model: Article,
as: "article",
duplicating:false,
attributes: []
}],
group: ['user.id']
});
得到的SQL語句
SELECT `user`.`name`, `user`.`avatar`, COUNT(`article`.`id`) AS `article.count`
FROM `user` AS `user` LEFT OUTER JOIN `article` AS `article` ON `user`.`id` = `article`.`user_id`
GROUP BY `user`.`id` LIMIT 0, 20;
大功告成!