Server/SpringBoot

[์›น๊ฐœ๋ฐœ์˜ ๋ด„, Spring] 2์ฃผ์ฐจ ๊ฐœ๋ฐœ์ผ์ง€(2) - JPA์˜ CRUD์™€ Repository

meeeeejin 2021. 7. 6. 21:20

[์›น๊ฐœ๋ฐœ์˜ ๋ด„, Spring] 2์ฃผ์ฐจ ๊ฐœ๋ฐœ์ผ์ง€(1) - RDBMS, H2, SQL

 

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ ์ •๋ฆฌํ•  ๋ถ€๋ถ„์€ JPA์™€ Repository์— ๊ด€ํ•œ ๋‚ด์šฉ์ด๋‹ค. 

 

 

 

JPA

๐Ÿ’ก JPA๋ž€?

JPA๋Š” SQL์„ ์“ฐ์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๋ฒˆ์—ญ๊ธฐ์ด๋‹ค. 

 

JPA๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์ž๋ฐ”๋กœ ์ฝ”๋“œ ์ž‘์„ฑ์„ ํ•˜๋‹ค๊ฐ€ ๊ฐ‘์ž๊ธฐ SQL์„ ์งœ๊ณ , ๋˜ ๊ทธ๊ฑธ ์ž˜ ๋งž์ถ”์–ด ๋„ฃ์–ด์•ผ ํ•˜๋Š” ๋ณต์žกํ•œ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค. ๋ฐ˜๋ฉด์— JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•œ ์„ค์ •๊ณผ ํ•จ๊ป˜ ๋ช…๋ น๋„ ์ž๋ฐ”๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ตฟ๊ตฟ~

 

 

๐Ÿ’ก JPA ์‚ฌ์šฉํ•ด๋ณด๊ธฐ

ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ Dependencies์— JPA๋ฅผ ์ถ”๊ฐ€ํ–ˆ์œผ๋ฏ€๋กœ ๋”ฐ๋กœ ์„ค์ •์—†์ด ๋ฐ”๋กœ JPA๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

DB์—์„œ์˜ "ํ…Œ์ด๋ธ”"์€ ์ž๋ฐ”์—์„œ Domain, "SQL"์€ Repository๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. SQL ์‹ค์Šต ๋•Œ, courses๋ผ๋Š” ํ…Œ์ด๋ธ”์— title, tutor๋ผ๋Š” ์ปฌ๋Ÿผ์„ ๋งŒ๋“ค์—ˆ๋˜ ๊ฒƒ์„ ์ž๋ฐ”๋กœ ํ‘œํ˜„ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋ฉด ๋œ๋‹ค. 

 

1. src > main > java > com.sparta.week02์— domain ์ด๋ผ๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ ๋‹ค. 

2. Course.java ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ ๋‹ค. 

@NoArgsConstructor // ๊ธฐ๋ณธ์ƒ์„ฑ์ž๋ฅผ ๋Œ€์‹  ์ƒ์„ฑ
@Entity // ํ…Œ์ด๋ธ”์ž„์„ ๋‚˜ํƒ€๋ƒ„
public class Course {

    @Id // ID ๊ฐ’, Primary Key๋กœ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ
    @GeneratedValue(strategy = GenerationType.AUTO) // ์ž๋™ ์ฆ๊ฐ€ ๋ช…๋ น
    private Long id;

    @Column(nullable = false) // ์ปฌ๋Ÿผ ๊ฐ’์ด๊ณ  ๋ฐ˜๋“œ์‹œ ๊ฐ’์ด ์กด์žฌํ•ด์•ผ ํ•จ์„ ๋‚˜ํƒ€๋ƒ„
    private String title;

    @Column(nullable = false)
    private String tutor;

    public String getTitle() {
        return this.title;
    }

    public String getTutor() {
        return this.tutor;
    }

    public Course(String title, String tutor) {
        this.title = title;
        this.tutor = tutor;
    }
}

3. CourseRepository.java ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ ๋‹ค. 

public interface CourseRepository extends JpaRepository<Course, Long> {
}

 

์ฐธ๊ณ ) Interface๋ž€?

 - JPA๋Š” Repository๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

 - ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํด๋ž˜์Šค์—์„œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๊ฐ€ ๋น ์ง„, ๋ฉ”์†Œ๋“œ ๋ชจ์Œ์ง‘์ด๋ผ ํ•  ์ˆ˜ ์žˆ์Œ

 

4. SQL์ด ๋ณด์ด๋„๋ก application.properties๋ฅผ ์„ค์ •ํ•œ๋‹ค. 

5. Week02Application.java์˜ main ํ•จ์ˆ˜ ์•„๋ž˜์— JPA ์‹คํ–‰ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. 

6. H2 ์›น์ฝ˜์†”์— ์ ‘์†ํ•ด์„œ ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ course ํ…Œ์ด๋ธ”์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. 

 

 

 

 

์ƒ์†์„ ํ•ด๋ณด์ž

๐Ÿ’ก ์ƒ์†์ด๋ž€?

"extends"๊ฐ€ ๋ญ˜๊นŒ? ์ด๊ฒƒ์€ "ํด๋ž˜์Šค์˜ ์ƒ์†"์ด๋ผ๋Š” ๊ฐœ๋…์ด๋‹ค. ์ƒ์†์ด๋ผ๋Š” ๊ฒƒ์€ "์ด๋ฏธ ๋งŒ๋“ค์–ด๋‘”๊ฑฐ ๊ฐ€์ ธ๋‹ค ์“ฐ์ž!"๋ผ๊ณ  ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

Course ํด๋ž˜์Šค์— ์ƒ์„ฑ์ผ์ž/์ˆ˜์ •์ผ์ž ๋ฉค๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด๋ฉฐ ์ƒ์†์„ ์—ฐ์Šตํ•ด๋ดค๋‹ค. 

 

1. Timestamped.java ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. 

@MappedSuperclass // ์ƒ์†ํ–ˆ์„ ๋•Œ ์ปฌ๋Ÿผ์œผ๋กœ ์ธ์‹ํ•˜๊ฒŒ ํ•จ
@EntityListeners(AuditingEntityListener.class) // ์ƒ์„ฑ/์ˆ˜์ • ์‹œ๊ฐ„์„ ์ž๋™์œผ๋กœ ๋ฐ˜์˜ํ•˜๋„๋ก ์„ค์ •
public class Timestamped {

    @CreatedDate // ์ƒ์„ฑ์ผ์ž์ž„์„ ๋‚˜ํƒ€๋ƒ„
    private LocalDateTime createdAt;

    @LastModifiedDate // ๋งˆ์ง€๋ง‰ ์ˆ˜์ •์ผ์ž์ž„์„ ๋‚˜ํƒ€๋ƒ„
    private LocalDateTime modifiedAt;
}

2. Course ํด๋ž˜์Šค๊ฐ€ Timestamped๋ฅผ ์ƒ์†๋ฐ›๋„๋ก ํ•œ๋‹ค. 

class Course extends Timestamped {

3. JPA๊ฐ€ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก Week02Application.java ํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•œ๋‹ค. 

@EnableJpaAuditing
@SpringBootApplication
public class Week02Application {

4. H2 ์›น์ฝ˜์†”์—์„œ course๋ฅผ ์กฐํšŒํ•œ ๋’ค, ์ƒ์„ฑ/์ˆ˜์ •์ผ์ž๊ฐ€ ์ž˜ ๋“ค์–ด๊ฐ”๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. 

 

 

 

 

JPA์˜ CRUD

๐Ÿ’ก CRUD

CRUD๋ž€ ์ •๋ณด๊ด€๋ฆฌ์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์œผ๋กœ, ์ƒ์„ฑ(Create), ์กฐํšŒ(Read), ๋ณ€๊ฒฝ(Update), ์‚ญ์ œ(Delete)๋ฅผ ๋งํ•œ๋‹ค. JPA๋กœ CRUD ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ๋ ๊นŒ?

 

 

๐Ÿ’ก Create & Read

Repository์˜ save์™€ findAll ๋“ฑ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ ๋ฐ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. 

// ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ
repository.save(new Course("ํ”„๋ก ํŠธ์—”๋“œ์˜ ๊ฝƒ, ๋ฆฌ์•กํŠธ", "์ž„๋ฏผ์˜"));

// ๋ฐ์ดํ„ฐ ์ „๋ถ€ ์กฐํšŒํ•˜๊ธฐ
List<Course> courseList = repository.findAll();
for (int i=0; i<courseList.size(); i++) {
    Course course = courseList.get(i);
    System.out.println(course.getId());
    System.out.println(course.getTitle());
    System.out.println(course.getTutor());
}

// ๋ฐ์ดํ„ฐ ํ•˜๋‚˜ ์กฐํšŒํ•˜๊ธฐ
Course course = repository.findById(1L).orElseThrow(
        () -> new IllegalArgumentException("ํ•ด๋‹น ์•„์ด๋””๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")
);

 

 

๐Ÿ’ก Service

Update๋Š” Service ๋ถ€๋ถ„์— ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— Service์˜ ๊ฐœ๋…์„ ๋จผ์ € ์•Œ์•„์•ผ ํ•œ๋‹ค.

 

์Šคํ”„๋ง์˜ ๊ตฌ์กฐ๋Š” 3๊ฐ€์ง€ ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค. 

  1. Controller: ๊ฐ€์žฅ ๋ฐ”๊นฅ ๋ถ€๋ถ„, ์š”์ฒญ/์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•จ
  2. Service: ์ค‘๊ฐ„ ๋ถ€๋ถ„, ์‹ค์ œ ์ค‘์š”ํ•œ ์ž‘๋™์ด ๋งŽ์ด ์ผ์–ด๋‚˜๋Š” ๋ถ€๋ถ„
  3. Repo: ๊ฐ€์žฅ ์•ˆ์ชฝ ๋ถ€๋ถ„, DB์™€ ๋งž๋‹ฟ์•„ ์žˆ์Œ

 

Update๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ ์ „์— Service๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค. 

1. Course ํด๋ž˜์Šค์— update ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. 

2. src > main > java > com.sparta.week02 > service ํŒจํ‚ค์ง€ ์ƒ์„ฑํ•œ๋‹ค. 

3. CourseService ํด๋ž˜์Šค ๋งŒ๋“ ๋‹ค. 

@Service // ์Šคํ”„๋ง์—๊ฒŒ ์ด ํด๋ž˜์Šค๋Š” ์„œ๋น„์Šค์ž„์„ ๋ช…์‹œํ•จ
public class CourseService {

	// final: ์„œ๋น„์Šค์—๊ฒŒ ๊ผญ ํ•„์š”ํ•œ ๋…€์„์ž„์„ ๋ช…์‹œํ•จ
    private final CourseRepository courseRepository;

	// ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด, Service ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ๊ผญ Repository๋ฅผ ๋„ฃ์–ด์ฃผ๋„๋ก
	// ์Šคํ”„๋ง์—๊ฒŒ ์•Œ๋ ค์คŒ
    public CourseService(CourseRepository courseRepository) {
        this.courseRepository = courseRepository;
    }

    @Transactional // SQL ์ฟผ๋ฆฌ๊ฐ€ ์ผ์–ด๋‚˜์•ผ ํ•จ์„ ์Šคํ”„๋ง์—๊ฒŒ ์•Œ๋ ค์คŒ
    public Long update(Long id, Course course) {
        Course course1 = courseRepository.findById(id).orElseThrow(
                () -> new IllegalArgumentException("ํ•ด๋‹น ์•„์ด๋””๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")
        );
        course1.update(course);
        return course1.getId();
    }
}

 

 

๐Ÿ’ก Update & Delete

Week02Application.java์—์„œ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œ์ผœ update์™€ delete๋ฅผ ํ™•์ธํ–ˆ๋‹ค. 

@Bean
public CommandLineRunner demo(CourseRepository courseRepository, CourseService courseService) {
    return (args) -> {
        courseRepository.save(new Course("ํ”„๋ก ํŠธ์—”๋“œ์˜ ๊ฝƒ, ๋ฆฌ์•กํŠธ", "์ž„๋ฏผ์˜"));

        System.out.println("๋ฐ์ดํ„ฐ ์ธ์‡„");
        List<Course> courseList = courseRepository.findAll();
        for (int i=0; i<courseList.size(); i++) {
            Course course = courseList.get(i);
            System.out.println(course.getId());
            System.out.println(course.getTitle());
            System.out.println(course.getTutor());
        }

        Course new_course = new Course("์›น๊ฐœ๋ฐœ์˜ ๋ด„, Spring", "์ž„๋ฏผ์˜");
        courseService.update(1L, new_course);
        courseList = courseRepository.findAll();
        for (int i=0; i<courseList.size(); i++) {
            Course course = courseList.get(i);
            System.out.println(course.getId());
            System.out.println(course.getTitle());
            System.out.println(course.getTutor());
        }

        courseRepository.deleteAll();
    };
}

 

์ฐธ๊ณ ) Repository์—” update๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— update๋Š” service์— ์ž‘์„ฑํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. 

 

 

 

 

 

 

์ฐธ๊ณ  ์ž๋ฃŒ: ์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ ์›น๊ฐœ๋ฐœ์˜ ๋ด„, Spring 2์ฃผ์ฐจ ๊ฐ•์˜์ž๋ฃŒ

 

 

728x90