skarltjr / Memory_Write_Record

나의 모든 학습 기록
0 stars 0 forks source link

다대다 연관관계를 일대다 다대일로 풀어나가기 #18

Open skarltjr opened 3 years ago

skarltjr commented 3 years ago

다대다를 풀어나가는 과정 간단히 정리 / remind

account entity

@Entity @Builder
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "'id")
public class Account {
    @Id
    @GeneratedValue
    @Column(name ="account_id")
    private Long id;

    private String username;
    private String password;

}

tag entity

@Entity @Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "'id")
public class Tag {
    @Id
    @GeneratedValue
    @Column(name = "tag_id")
    private Long id;

    private String title;
}

둘 사이의 연결다리를 위한 AccountTagItem entity ★각각 단방향

@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "'id")
public class AccountTagItem {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private Account account;

    @ManyToOne(fetch = FetchType.LAZY)
    private Tag tag;
}

간단한 실험을 위한 controller

@RestController
@RequiredArgsConstructor
public class AccountController {
    private final ATIRepository atiRepository;
    private final AccountRepository accountRepository;
    private final TagRepository tagRepository;

// 초기데이터 저장용
    @GetMapping("/data")
    public String setData() {
        if (accountRepository.count() != 0 && tagRepository.count() != 0) {
            return "already";
        }
        for (int i = 0; i < 5; i++) {
            Account account = Account.builder()
                    .username("user" + i)
                    .password("123")
                    .build();
            accountRepository.save(account);

            Tag tag = Tag.builder()
                    .title("tagTitle" + i)
                    .build();
            tagRepository.save(tag);
        }
        return "save data";
    }

// 계정에 태그를 추가하는 경우를 가정 
// 다대다였다면  account가 tag를 참조했겠지만 일대다 다대일로 풀어나갔다
// 따라서 account가 갖는 tag에 대한 정보는 AccountTagItem으로 가져간다.
    @GetMapping("/withTag/{username}/{title}")
    public String withTag(@PathVariable String username, @PathVariable String title) {
        Account account = accountRepository.findByUsername(username);
        Tag tag = tagRepository.findByTitle(title);

        AccountTagItem build = AccountTagItem.builder()
                .account(account)
                .tag(tag)
                .build();
        AccountTagItem save = atiRepository.save(build);
        return save.getAccount().getUsername() + " +++ " + save.getTag().getTitle();
    }

// A 유저의 태그목록을 가져오기 
// AccountTagItem 레퍼지토리에서 findByAccount를 통해 account가 A인  AccountTagItem들의 tag를 리턴해주면 된다.
    @GetMapping("/{username}/tags")
    public String getTagsOfUser(@PathVariable String username) {
        Account account = accountRepository.findByUsername(username);
        List<AccountTagItem> list = atiRepository.findByAccount(account);
        String name = "";
        for (AccountTagItem accountTagItem : list) {
            name = name + " " + accountTagItem.getTag().getTitle();
        }
        return name;
    }
}