๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Java·๏ปฟServlet·๏ปฟJSP

SQL ์˜์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฌธ์ œ์ ๊ณผ JPA

by Leica 2020. 3. 18.
๋ฐ˜์‘ํ˜•

SQL ์˜์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฌธ์ œ์ ๊ณผ JPA

๊ฐœ์š”

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด SQL์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ JDBC API๋ฅผ ์‚ฌ์šฉํ•ด์„œ SQL์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

JPA๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์˜ ์ด์ ์ด ๋ฌด์—‡์ธ์ง€, SQL์„ ์ง์ ‘ ๋‹ค๋ฃฐ ๋•Œ์˜ ๋ฌธ์ œ์ ์€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ์ž๋ฐ”์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํšŒ์› ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•ด๋ณด์ž.

ํšŒ์› ํ…Œ์ด๋ธ”์€ ์ด๋ฏธ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  CRUD(๋“ฑ๋ก, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œ) ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•ด๋ณด์ž.

 

JDBC ํšŒ์› ๊ด€๋ฆฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜

Member(ํšŒ์›) ๊ฐ์ฒด

์ž๋ฐ”์—์„œ ์‚ฌ์šฉํ•  Member(ํšŒ์›) ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.

public class Member {

    private int no;
    private String email;
    private String name;

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

DAO(Data Access Object, ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ฐ์ฒด)

Member ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๊ด€๋ฆฌํ•  ๋ชฉ์ ์œผ๋กœ Member DAO๋ฅผ ๋งŒ๋“ ๋‹ค.

public class MemberDao {

    // ๋“ฑ๋ก
    public int save(Member member) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "INSERT INTO MEMBERS (EMAIL, MNAME) VALUES (?, ?)";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, member.getEmail());
                pstmt.setString(2, member.getName());

                return pstmt.executeUpdate();

            }
        }
    }

    // ์กฐํšŒ
    public Member find(int no) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "SELECT MNO, EMAIL, MNAME FROM MEMBERS WHERE MNO = ?";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, no);

                try (ResultSet rs = pstmt.executeQuery()) {
                    if (rs.next()) {
                        Member member = new Member();

                        member.setNo(no);
                        member.setEmail(rs.getString("EMAIL"));
                        member.setName(rs.getString("MNAME"));

                        return member;
                    } else {
                        throw new SQLException();
                    }
                }
            }
        }
    }

    // ์ˆ˜์ •
    public int update(Member member) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "UPDATE MEMBERS SET EMAIL = ?, MNAME = ? WHERE MNO = ?";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, member.getEmail());
                pstmt.setString(2, member.getName());
                pstmt.setInt(3, member.getNo());

                return pstmt.executeUpdate();

            }
        }
    }

    // ์‚ญ์ œ
    public int delete(int no) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "DELETE FROM MEMBERS WHERE MNO = ?";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, no);

                return pstmt.executeUpdate();

            }
        }
    }
}

 

์š”๊ตฌ์‚ฌํ•ญ์˜ ์ถ”๊ฐ€ - ํšŒ์› ์—ฐ๋ฝ์ฒ˜

ํšŒ์›์˜ ์—ฐ๋ฝ์ฒ˜๋ฅผ ํ•จ๊ป˜ ์ €์žฅํ•ด๋‹ฌ๋ผ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

 

์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ

ํšŒ์› ํ…Œ์ด๋ธ”์— TEL ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

ALTER TABLE `spms`.`members` 
ADD COLUMN `TEL` VARCHAR(45) NULL AFTER `MNAME`;

 

Member ๊ฐ์ฒด ๋ณ€๊ฒฝ

ํšŒ์› ๊ฐ์ฒด์— tel ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

public class Member {

    private int no;
    private String email;
    private String name;
    private String tel; // ์ถ”๊ฐ€

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }
}

 

DAO ๋ณ€๊ฒฝ

๋“ฑ๋ก, ์กฐํšŒ, ์ˆ˜์ • SQL, JDBC API ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.

public class MemberDao {

    // ๋“ฑ๋ก
    public int save(Member member) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "INSERT INTO MEMBERS (EMAIL, MNAME, TEL) VALUES (?, ?, ?)";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, member.getEmail());
                pstmt.setString(2, member.getName());
                pstmt.setString(3, member.getTel());

                return pstmt.executeUpdate();

            }
        }
    }

    // ์กฐํšŒ
    public Member find(int no) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "SELECT MNO, EMAIL, MNAME, TEL FROM MEMBERS WHERE MNO = ?";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, no);

                try (ResultSet rs = pstmt.executeQuery()) {
                    if (rs.next()) {
                        Member member = new Member();

                        member.setNo(no);
                        member.setEmail(rs.getString("EMAIL"));
                        member.setName(rs.getString("MNAME"));
                        member.setName(rs.getString("TEL"));

                        return member;
                    } else {
                        throw new SQLException();
                    }
                }
            }
        }
    }

    // ์ˆ˜์ •
    public int update(Member member) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "UPDATE MEMBERS SET EMAIL = ?, MNAME = ?, TEL = ? WHERE MNO = ?";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, member.getEmail());
                pstmt.setString(2, member.getName());
                pstmt.setString(3, member.getTel());
                pstmt.setInt(4, member.getNo());

                return pstmt.executeUpdate();

            }
        }
    }

    // ์‚ญ์ œ
    public int delete(int no) throws SQLException {

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/spms?user=leica&password=1234")) {
            String sql = "DELETE FROM MEMBERS WHERE MNO = ?";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, no);

                return pstmt.executeUpdate();

            }
        }
    }
}

 

์š”๊ตฌ์‚ฌํ•ญ์˜ ์ถ”๊ฐ€ - ์†Œ์† ํŒ€

ํšŒ์›์€ ์–ด๋–ค ํ•œ ํŒ€์— ํ•„์ˆ˜๋กœ ์†Œ์†๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

๋‹ค์‹œ ์Šคํ‚ค๋งˆ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ , Member ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ , DAO๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ• ๊ฒƒ์ด๋‹ค.

 

์•„๋ž˜์™€ ๊ฐ™์ด Member ๊ฐ์ฒด์— Team ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

public class Member {

    private int no;
    private String email;
    private String name;
    private String tel;
    private Team team;  // ์ถ”๊ฐ€
    ...

 

์ด ๋•Œ Member ๊ฐ์ฒด๊ฐ€ Team ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ SQL์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

์ฆ‰ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ณ„์ธต์„ ์‚ฌ์šฉํ•ด์„œ SQL์„ ์ˆจ๊ฒจ๋„ ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์–ด์ฉ” ์ˆ˜ ์—†์ด DAO๋ฅผ ์—ด์–ด SQL์„ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.

 

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ SQL์„ ์ง์ ‘ ๋‹ค๋ฃฐ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ 

- ์ง„์ •ํ•œ ์˜๋ฏธ์˜ ๊ณ„์ธต ๋ถ„ํ• ์ด ์–ด๋ ต๋‹ค.
- ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋‹ค.
- SQL์— ์˜์กด์ ์ธ ๊ฐœ๋ฐœ์„ ํ”ผํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

Member๋‚˜ Team์ฒ˜๋Ÿผ ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ชจ๋ธ๋งํ•œ ๊ฐ์ฒด๋ฅผ ์—”ํ‹ฐํ‹ฐ๋ผ ํ•˜๋Š”๋ฐ ์ง€๊ธˆ์ฒ˜๋Ÿผ SQL์— ๋ชจ๋“  ๊ฒƒ์„ ์˜์กดํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‹ ๋ขฐํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

๋Œ€์‹  DAO๋ฅผ ์—ด์–ด ์–ด๋–ค SQL์ด ์‹คํ–‰๋˜๊ณ  ์–ด๋–ค ๊ฐ์ฒด๋“ค์ด ํ•จ๊ป˜ ์กฐํšŒ๋˜๋Š”์ง€ ์ผ์ผ์ด ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

๋ฌผ๋ฆฌ์ ์œผ๋กœ SQL๊ณผ JDBC API๋ฅผ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ณ„์ธต์— ์ˆจ๊ธธ์ˆœ ์žˆ์–ด๋„ ๋…ผ๋ฆฌ์ ์œผ๋กœ๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ์•„์ฃผ ๊ฐ•ํ•œ ์˜์กด ๊ด€๊ณ„๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค.

์ด๋Ÿฐ ๊ฐ•ํ•œ ์˜์กด ๊ด€๊ณ„ ๋•Œ๋ฌธ์— ํšŒ์› ๊ฐ์ฒด์— ํ•„๋“œ๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•  ๋•Œ๋„ DAO์˜ CRUD ์ฝ”๋“œ์™€ SQL ๋Œ€๋ถ€๋ถ„์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

JPA์™€ ๋ฌธ์ œ ํ•ด๊ฒฐ

JPA๋Š” ์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•  ๋•Œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ SQL์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ JPA๊ฐ€ ์ œ๊ณตํ•˜๋Š” API๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด JPA๊ฐ€ ๊ฐœ๋ฐœ์ž ๋Œ€์‹  ์ ์ ˆํ•œ SQL์„ ์ƒ์„ฑํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ „๋‹ฌํ•œ๋‹ค.

 

JPA๊ฐ€ ์ œ๊ณตํ•˜๋Š” CRUD API

์ €์žฅ ๊ธฐ๋Šฅ

jpa.persist(member);	// ์ €์žฅ

persist()๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•œ๋‹ค.

JPA๊ฐ€ ๊ฐ์ฒด์™€ ๋งคํ•‘ ์ •๋ณด๋ฅผ ๋ณด๊ณ  INSERT SQL์„ ์ƒ์„ฑํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ „๋‹ฌํ•œ๋‹ค.

 

์กฐํšŒ ๊ธฐ๋Šฅ

String memberId = "helloId";
Member member = jpa.find(Member.class, memberId);	// ์กฐํšŒ

find()๋Š” ๊ฐ์ฒด ํ•˜๋‚˜๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒํ•œ๋‹ค.

JPA๊ฐ€ ๊ฐ์ฒด์™€ ๋งคํ•‘ ์ •๋ณด๋ฅผ ๋ณด๊ณ  SELECT SQL์„ ์ƒ์„ฑํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ „๋‹ฌํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋กœ Member ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

์ˆ˜์ • ๊ธฐ๋Šฅ

Member member = jpa.find(Member.class, memberId);
member.setName("์ด๋ฆ„๋ณ€๊ฒฝ");	// ์ˆ˜์ •

JPA๋Š” ๋ณ„๋„์˜ ์ˆ˜์ • ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋Œ€์‹  ๊ฐ์ฒด๋ฅผ ์กฐํšŒํ•ด์„œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— UPDATE SQL์ด ์ „๋‹ฌ๋œ๋‹ค.

 

์—ฐ๊ด€๋œ ๊ฐ์ฒด ์กฐํšŒ

Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();	// ์—ฐ๊ด€๋œ ๊ฐ์ฒด ์กฐํšŒ

JPA๋Š” ์—ฐ๊ด€๋œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— SELECT SQL์„ ์‹คํ–‰ํ•œ๋‹ค.

 

References

๐Ÿ“– ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์—์ด์ฝ˜, 2015, ๊น€์˜ํ•œ)

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€