your programing

Node.js에서 Sequelize를 사용하여 조인 쿼리를 만드는 방법

lovepro 2020. 10. 11. 11:05
반응형

Node.js에서 Sequelize를 사용하여 조인 쿼리를 만드는 방법


sequelize ORM을 사용하고 있습니다. 모든 것이 훌륭하고 깨끗하지만 join쿼리 와 함께 사용할 때 문제가 발생했습니다 . 사용자와 게시물의 두 가지 모델이 있습니다.

var User = db.seq.define('User',{
    username: { type: db.Sequelize.STRING},
    email: { type: db.Sequelize.STRING},
    password: { type: db.Sequelize.STRING},
    sex : { type: db.Sequelize.INTEGER},
    day_birth: { type: db.Sequelize.INTEGER},
    month_birth: { type: db.Sequelize.INTEGER},
    year_birth: { type: db.Sequelize.INTEGER}

});

User.sync().success(function(){
    console.log("table created")
}).error(function(error){
    console.log(err);
})


var Post = db.seq.define("Post",{
    body: { type: db.Sequelize.TEXT },
    user_id: { type: db.Sequelize.INTEGER},
    likes: { type: db.Sequelize.INTEGER, defaultValue: 0 },

});

Post.sync().success(function(){
    console.log("table created")
}).error(function(error){
    console.log(err);
})

나는 그것을 만든 사용자의 정보가 담긴 게시물로 응답하는 쿼리를 원합니다. 원시 쿼리에서 다음을 얻습니다.

db.seq.query('SELECT * FROM posts, users WHERE posts.user_id = users.id ').success(function(rows){
            res.json(rows);
        });

내 질문은 SQL 쿼리 대신 ORM 스타일을 사용하도록 코드를 어떻게 변경할 수 있습니까?


User.hasMany(Post, {foreignKey: 'user_id'})
Post.belongsTo(User, {foreignKey: 'user_id'})

Post.find({ where: { ...}, include: [User]})

당신에게 줄 것입니다

SELECT
  `posts`.*,
  `users`.`username` AS `users.username`, `users`.`email` AS `users.email`,
  `users`.`password` AS `users.password`, `users`.`sex` AS `users.sex`,
  `users`.`day_birth` AS `users.day_birth`,
  `users`.`month_birth` AS `users.month_birth`,
  `users`.`year_birth` AS `users.year_birth`, `users`.`id` AS `users.id`,
  `users`.`createdAt` AS `users.createdAt`,
  `users`.`updatedAt` AS `users.updatedAt`
FROM `posts`
  LEFT OUTER JOIN `users` AS `users` ON `users`.`id` = `posts`.`user_id`;

위의 쿼리는 게시 한 내용에 비해 약간 복잡해 보일 수 있지만 기본적으로 사용자 테이블의 모든 열에 별칭을 지정하여 반환 될 때 올바른 모델에 배치되고 posts 모델과 섞이지 않도록하는 것입니다.

그 외에는 두 테이블에서 선택하는 대신 JOIN을 수행하지만 결과는 동일해야합니다.

추가 읽기 :


받아 들여진 대답은 기술적으로 틀린 것은 아니지만 원래 질문에 대한 대답도 아니고 댓글에있는 후속 질문에도 대답하지 않았습니다. 그러나 나는 그것을 알아 냈습니다.

사용자가있는 모든 게시물 (및 사용자가있는 게시물 만)을 찾으려면 SQL이 다음과 같이 표시됩니다.

SELECT * FROM posts INNER JOIN users ON posts.user_id = users.id

OP의 원래 SQL과 의미 상 동일합니다.

SELECT * FROM posts, users WHERE posts.user_id = users.id

그러면 이것이 당신이 원하는 것입니다.

Posts.findAll({
  include: [{
    model: User,
    required: true
   }]
}).then(posts => {
  /* ... */
});

Setting required to true is the key to producing an inner join. If you want a left outer join (where you get all Posts, regardless of whether there's a user linked) then change required to false, or leave it off since that's the default:

Posts.findAll({
  include: [{
    model: User,
//  required: false
   }]
}).then(posts => {
  /* ... */
});

If you want to find all Posts belonging to users whose birth year is in 1984, you'd want:

Posts.findAll({
  include: [{
    model: User,
    where: {year_birth: 1984}
   }]
}).then(posts => {
  /* ... */
});

Note that required is true by default as soon as you add a where clause in.

If you want all Posts, regardless of whether there's a user attached but if there is a user then only the ones born in 1984, then add the required field back in:

Posts.findAll({
  include: [{
    model: User,
    where: {year_birth: 1984}
    required: false,
   }]
}).then(posts => {
  /* ... */
});

If you want all Posts where the name is "Sunshine" and only if it belongs to a user that was born in 1984, you'd do this:

Posts.findAll({
  where: {name: "Sunshine"},
  include: [{
    model: User,
    where: {year_birth: 1984}
   }]
}).then(posts => {
  /* ... */
});

If you want all Posts where the name is "Sunshine" and only if it belongs to a user that was born in the same year that matches the post_year attribute on the post, you'd do this:

Posts.findAll({
  where: {name: "Sunshine"},
  include: [{
    model: User,
    where: ["year_birth = post_year"]
   }]
}).then(posts => {
  /* ... */
});

I know, it doesn't make sense that somebody would make a post the year they were born, but it's just an example - go with it. :)

I figured this out (mostly) from this doc:


Model1.belongsTo(Model2, { as: 'alias' })

Model1.findAll({include: [{model: Model2  , as: 'alias'  }]},{raw: true}).success(onSuccess).error(onError);

In my case i did following thing. In the UserMaster userId is PK and in UserAccess userId is FK of UserMaster

UserAccess.belongsTo(UserMaster,{foreignKey: 'userId'});
UserMaster.hasMany(UserAccess,{foreignKey : 'userId'});
var userData = await UserMaster.findAll({include: [UserAccess]});

참고URL : https://stackoverflow.com/questions/20460270/how-to-make-join-queries-using-sequelize-on-node-js

반응형