๐Ÿ’พ Database

[JPA] ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘

์—ฐ_์šฐ๋ฆฌ 2022. 2. 20. 23:27
๋ฐ˜์‘ํ˜•

๋ชฉ์ฐจ

     

     

     

    ๋ชฉํ‘œ : "๊ฐ์ฒด์˜ ์ฐธ์กฐ์™€ ํ…Œ์ด๋ธ”์˜ ์™ธ๋ž˜ํ‚ค๋ฅผ ๋งคํ•‘"

     

     

    ์‹œ๋‚˜๋ฆฌ์˜ค

     - ํšŒ์›๊ณผ ํŒ€์€ ๋‹ค๋Œ€์ผ ๊ด€๊ณ„์ด๋‹ค.

     - N๋ช…์˜ ํšŒ์›์€ 1๊ฐœ์˜ ํŒ€์— ์†Œ์†๋  ์ˆ˜ ์žˆ๋‹ค.

     - 1๊ฐœ์˜ ํŒ€์€ N๋ช…์˜ ํšŒ์›์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

     

     

    ๊ฐ์ฒด๋ฅผ ํ…Œ์ด๋ธ”์— ๋งž์ถ”์–ด ๋ชจ๋ธ๋ง : ์™ธ๋ž˜ํ‚ค๋ฅผ ๊ทธ๋Œ€๋กœ ๊ฐ์ฒด์— ๊ตฌํ˜„

    Team team = new Team();
    team.setName("TeamA");
    em.persist(team);
    
    Member member = new Member();
    member.setName("member1");
    member.setTeamId(team.getId());	//โญโญโญ ์‹๋ณ„์ž ์ €์žฅ
    em.persist(member);
    
    
    Member findMember = em.find(Member.class, member.getId());
    Team findTeam = em.find(Team.class, team.getId());	//โญโญโญ ์‹๋ณ„์ž ์กฐํšŒ

     

    ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ๋ชจ๋ธ๋ง์˜ ๋ฌธ์ œ์ 

    ํ…Œ์ด๋ธ”์€ ์™ธ๋ž˜ํ‚ค๋กœ ์กฐ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ด€๋œ ํ…Œ์ด๋ธ”์„ ์ฐพ๋Š”๋‹ค.

    ํ•˜์ง€๋งŒ ๊ฐ์ฒด๋Š”? ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ด€๋œ ๊ฐ์ฒด๋ฅผ ์ฐพ๋Š”๋‹ค.

    => ์–ด๋””์—..๋งž์ถ”์ง€?!

     

     

     

    ๊ฐ์ฒด ์ง€ํ–ฅ ๋ชจ๋ธ๋ง : ๊ฐ์ฒด ์—ฐ๊ด€๊ด€๊ณ„ ์‚ฌ์šฉ

    JPA์—๊ฒŒ ๊ฐ์ฒด ๊ฐ„ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ์•Œ๋ ค์ฃผ์–ด์„œ ํ…Œ์ด๋ธ”์—๋„ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์ ์šฉ๋˜๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

     

     

    ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘

    1. ์—ฐ๊ด€๊ด€๊ณ„ ํŒŒ์•… : ๋ˆ„๊ฐ€ 1์ด๊ณ  ๋ˆ„๊ฐ€ N์ธ๊ฐ€?

                            Team์ด 1์ด๊ณ  Member๊ฐ€ N์ด๋‹ค. 

                            Teamํ…Œ์ด๋ธ”์— PK๊ฐ€ ์žˆ๊ณ  Memberํ…Œ์ด๋ธ”์— FK๊ฐ€ ์žˆ๋‹ค.

     

    2. N์— @ManyToOne, @JoinColumn์„ ์ž‘์„ฑํ•œ๋‹ค

     

    @Entity
    public class Member{
    	@Id @GeneratedValue
        private Long id;
        private String username;
        @ManyToOne				//โญโญโญ Member๊ฐ€ N(many), Team์ด 1(one)์ด๋‹ค.
        @JoinColumn(name = "team_id")	//โญโญโญ team_id๋กœ FK ์„ค์ •ํ•œ๋‹ค.
        private Team team;
    }
    
    @Entity
    public class Team{
    	@Id @GeneratedValue
        private Long id;
        private String name;
    }
    Team team = new Team();
    team.setName("TeamA");
    em.persist(team);
    
    Member member = new Member();
    member.setName("member1");
    member.setTeam(team);	//โญโญโญ ์ฐธ์กฐ ์ €์žฅ
    em.persist(member);
    
    
    Member findMember = em.find(Member.class, member.getId());
    Team findTeam = fiindMember.getTeam();		//โญโญโญ ์ฐธ์กฐ ์กฐํšŒ

     

    ์–‘๋ฐฉํ–ฅ ๋งคํ•‘

    1. ์—ฐ๊ด€๊ด€๊ณ„ ํŒŒ์•… : ๋ˆ„๊ฐ€ 1์ด๊ณ  ๋ˆ„๊ฐ€ N์ธ๊ฐ€?

                            Team์ด 1์ด๊ณ  Member๊ฐ€ N์ด๋‹ค. 

                            Teamํ…Œ์ด๋ธ”์— PK๊ฐ€ ์žˆ๊ณ  Memberํ…Œ์ด๋ธ”์— FK๊ฐ€ ์žˆ๋‹ค.

                            Team๊ฐ์ฒด๋Š” List<Member>๊ฐ€ ์žˆ๊ณ  Member๊ฐ์ฒด๋Š” Team์ด ์žˆ๋‹ค.

                            Team์ด ์ƒ๋Œ€(Member)๋ฅผ N๊ฐœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ณ , Member๋Š” ์ƒ๋Œ€(Team)์„ 1๊ฐœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

     

    2. N์— @ManyToOne, @JoinColumn์„ ์ž‘์„ฑํ•œ๋‹ค

       1์— @OneToMany(mappedBy="~")๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

     

    @Entity
    public class Member{
    	@Id @GeneratedValue
        private Long id;
        private String username;
        @ManyToOne				//โญโญโญ Member๊ฐ€ N(many), Team์ด 1(one)์ด๋‹ค.
        @JoinColumn(name = "team_id")	//โญโญโญ team_id๋กœ FK ์„ค์ •ํ•œ๋‹ค.
        private Team team;
    }
    
    @Entity
    public class Team{
    	@Id @GeneratedValue
        private Long id;
        private String name;
        @OneToMany(mappedBy = "team")	//โญโญโญ Team์ด 1(one), Member๊ฐ€ N(many)์ด๋‹ค.
        private List<Member> members = new ArrayList<>();	//addํ• ๋•Œ NullPointerException์•ˆ๋œจ๊ฒŒ!
        //mappedBy์—๋Š” One์— ํ•ด๋‹น๋˜๋Š” ๊ฐ์ฒด์˜ ์–ด๋–ค ํ•„๋“œ์™€ ์—ฐ๊ด€๋˜์–ด์žˆ๋Š”์ง€ ์ž‘์„ฑ
    }
    Team team = new Team();
    team.setName("TeamA");
    em.persist(team);
    
    Member member = new Member();
    member.setName("member1");
    member.setTeam(team);	//โญโญโญ ์ฐธ์กฐ ์ €์žฅ
    em.persist(member);
    
    
    Member findMember = em.find(Member.class, member.getId());
    Team findTeam = fiindMember.getTeam();		//โญโญโญ ์ฐธ์กฐ ์กฐํšŒ
    List<Member> members = findTeam.getMembers();	//โญโญโญ ์ฐธ์กฐ ์กฐํšŒ

     

     

    ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ

    ๊ฐ์ฒด์˜ ์—ฐ๊ด€๊ด€๊ณ„์—๋Š” ๋ฐฉํ–ฅ์ด ์žˆ์ง€๋งŒ, ํ…Œ์ด๋ธ”์˜ ์—ฐ๊ด€๊ด€๊ณ„์—๋Š” ๋ฐฉํ–ฅ์ด ์—†๋‹ค!

     

     

    ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์˜ ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž.

    ๊ฐ์ฒด ํ…Œ์ด๋ธ”
    Member → Team ๋‹จ๋ฐฉํ–ฅ 1๊ฐœ
    Member ← Team ๋‹จ๋ฐฉํ–ฅ 1๊ฐœ
    Member ↔ Team ์–‘๋ฐฉํ–ฅ 1๊ฐœ

    ๊ฐ์ฒด์˜ ์–‘๋ฐฉํ–ฅ๊ด€๊ณ„๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋‹จ๋ฐฉํ–ฅ๊ด€๊ณ„ 2๊ฐœ์ด๋‹ค.

    ํ…Œ์ด๋ธ”์€ ์™ธ๋ž˜ํ‚ค ํ•˜๋‚˜๋กœ ๋‘ ํ…Œ์ด๋ธ”์˜ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. (์กฐ์ธ)

     

    ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ : ํ…Œ์ด๋ธ”์—์„œ ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ณณ์„ ์ฃผ์ธ์œผ๋กœ ํ•˜์ž

    ์–‘๋ฐฉํ–ฅ ๋งคํ•‘ ๊ทœ์น™

     - ๋‘ ๊ฐ์ฒด ์ค‘ ํ•˜๋‚˜๋งŒ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์œผ๋กœ ์ง€์ •

     - ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ๋งŒ์ด ์™ธ๋ž˜ํ‚ค๋ฅผ ๊ด€๋ฆฌ(๋“ฑ๋ก, ์ˆ˜์ •)

     - ์ฃผ์ธ์ด ์•„๋‹Œ ์ชฝ์€ ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅ

     - ์ฃผ์ธ์ด ์•„๋‹Œ์ชฝ์ด mappedBy์†์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค. (์ด๋ฏธ ๋ˆ„๊ตฐ๊ฐ€์— ์˜ํ•ด ์—ฐ๊ด€์ด ๋˜์–ด์ ธ์žˆ๋‹ค.)

     

     

    ํ…Œ์ด๋ธ”์—์„œ ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ณณ์˜ ๋ฐ˜๋Œ€๋ฅผ ์ฃผ์ธ์œผ๋กœํ•˜๋ฉด??

    ์—ฌ๊ธฐ์„œ Team์„ ์ฃผ์ธ์œผ๋กœ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž.

    List<Member>๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด Team์— ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๋Š” ๊ฒƒ์ด ์•„๋‹Œ Member์— ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๊ฒŒ๋œ๋‹ค. (์ˆ˜์ • ์ฃผ์ฒด๋Š” Team์ธ๋ฐ..)

     

     

    ์–‘๋ฐฉํ–ฅ ๋งคํ•‘ ์‹œ ๊ฐ€์žฅ ๋งŽ์ด ํ•˜๋Š” ์‹ค์ˆ˜!

    ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด ์•„๋‹Œ ๊ณณ์— ๊ฐ’์„ ๋„ฃ๋Š” ๊ฒƒ

    ํ˜„์žฌ Member๊ฐ€ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด๊ณ , Team์€ ์ฃผ์ธ์ด ์•„๋‹ˆ๋‹ค.

    Member member = new Member();
    member.setName("member1");
    //member.setTeam(team);	//โญโญโญ ์ฃผ์„์ฒ˜๋ฆฌ
    em.persist(member);
    
    
    Team team = new Team();
    team.setName("TeamA");
    team.getMembers().add(member);	//โญโญโญ ์ฐธ์กฐ์ €์žฅ
    em.persist(team);

    ์ฃผ์ธ์ด ์•„๋‹Œ ๊ณณ(Team)์— Member๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

    ์œ„ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋Š”?

    Team์— null์ด ๋“ค์–ด๊ฐ”๋‹ค.

    ์ฃผ์ธ์ด ์•„๋‹Œ ๊ณณ(Team)์— Member๋ฅผ ์ถ”๊ฐ€ํ•ด๋„ DB์— ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š”๋‹ค.

     

     

    Team team = new Team();
    team.setName("TeamA");
    //team.getMembers().add(member);	//โญโญโญ ์ฃผ์„์ฒ˜๋ฆฌ
    em.persist(team);
    
    
    Member member = new Member();
    member.setName("member1");
    member.setTeam(team);	//โญโญโญ ์ฐธ์กฐ์ €์žฅ
    em.persist(member);

    ์ฃผ์ธ์ธ ๊ณณ(Member)์— Team์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

    ์œ„ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋Š”?

    ๊ฐ’์ด ์ •์ƒ์ ์œผ๋กœ ๋“ค์–ด๊ฐ”๋‹ค.

     

    (..์ผ๋‹จ ํ—ท๊ฐˆ๋ฆฐ๋‹ค.)

     

    ๊ฐ์ฒด์ž…์žฅ์—์„œ ์ƒ๊ฐํ•ด๋ณด์ž.

    Member์ž…์žฅ์—์„œ๋Š” setTeam(team)์„ ํ•ด์ฃผ์–ด์•ผ Team๊ฐ’์ด ์ž…๋ ฅ๋˜๊ณ 

    Team์ž…์žฅ์—์„œ๋Š” add(member)์„ ํ•ด์ฃผ์–ด์•ผ Member๊ฐ€ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ๋œ๋‹ค.

     

    ๊ฒฐ๋ก  : ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์€ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด๋˜ ์•„๋‹ˆ๋˜ ๋‘˜๋‹ค ๊ฐ’์„ ๋„ฃ์–ด์ฃผ์ž!!

     

     

    ์•„๋‹ˆ๋ฉด, ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ธ Member์˜ setTeam()๋ฉ”์„œ๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์ž

    (์•„์˜ˆ ๋ฆฌ์ŠคํŠธ์— ๋„ฃ์–ด์ฃผ๋Š” ๋กœ์ง๊นŒ์ง€ ์ถ”๊ฐ€!)

    public class Member{
    	public void setTeam(Team team){
        	this.team = team;
            team.getMembers().add(this);
        }
    }

     

     

     

    ์–‘๋ฐฉํ–ฅ ๋งคํ•‘ ์‹œ ๋ฌดํ•œ๋ฃจํ”„ ์กฐ์‹ฌ!

     - toString()

    public class Member{
        @Override
        public String toString(){
        	return "Member{" + "id=" + id + ", username=" + username + ", team=" + team + "}";
        }
    }
    
    public class Team{
        @Override
        public String toString(){
        	return "Team{" + "id=" + id + ", name=" + name + ", members=" + members + "}";
        }
    }

    Member์˜ team์—์„œ Team์„ ํ˜ธ์ถœ

    Team์˜ members์—์„œ ๋‹ค์‹œ ๋ฆฌ์ŠคํŠธ์˜ ํฌ๊ธฐ๋งŒํผ Memberํ˜ธ์ถœ....

     

    ์ปจํŠธ๋กค๋Ÿฌ์—์„œ Entity๋ฅผ JSON์œผ๋กœ ๋ฐ”๊ฟ”์„œ ๊ทธ๋Œ€๋กœ ์‘๋‹ตํ•ด์ฃผ๊ฒŒ๋˜๋ฉด

    JSON์ƒ์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ณ„์† ๋ฌดํ•œ๋ฃจํ”„๋กœ ํ˜ธ์ถœํ•˜๊ฒŒ๋œ๋‹ค!

     

     

     

    ์ •๋ฆฌ

     - ๋˜๋„๋ก ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘์œผ๋กœ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์„ ๋๋‚ด์ž

     - ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์€ ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ ๊ฒƒ ๋ฟ์ด๋‹ค.

     - ์ •๋ง ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ! ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์„ ๊ฑธ์–ด์ฃผ์ž

     

     

     

     

     

    ์ฐธ๊ณ  : ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ
    ๋ฐ˜์‘ํ˜•
    • ๋„ค์ด๋ฒ„ ๋ธ”๋Ÿฌ๊ทธ ๊ณต์œ ํ•˜๊ธฐ
    • ํŽ˜์ด์Šค๋ถ ๊ณต์œ ํ•˜๊ธฐ
    • ํŠธ์œ„ํ„ฐ ๊ณต์œ ํ•˜๊ธฐ
    • ๊ตฌ๊ธ€ ํ”Œ๋Ÿฌ์Šค ๊ณต์œ ํ•˜๊ธฐ
    • ์นด์นด์˜คํ†ก ๊ณต์œ ํ•˜๊ธฐ