백엔드 13일차 - 스프링부트 : JPA

parang·2025년 4월 24일

LG CNS AM Inspire Camp 2기

목록 보기
24/50

JPA란?

JPA란 ORM 프레임워크 기술에 대한 표준 명세로, 객체 - 관계형 데이터베이스를 매핑하는데 사용되는 인터페이스이다.
JPA를 이용하면, 자바 클래스와 DB 테이블 간 매핑을 쉽게 처리할 수 있기 때문에 유지보수가 쉽고, DB종류에 상관없이 코드 작성 가능하다.

초기 설정

spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect 
-> mariaDB용 sql 문법 세팅
spring.jpa.hibernate.ddl-auto=update
-> (Entity) update는 기존 테이블 유지 후 값만 변경하는 것
-> create는 실행할때마다 테이블 재생성
-> none은 자동 실행 x , 운영에서 많이 사용.
spring.jpa.show-sql=true
-> 디버깅 용으로, 생성한 sql 콘솔에서 확인할 수 있는 코드
spring.jpa.properties.hibernate.format_sql=true 
->sql 포맷팅 코드
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
-> 컬럼명이 다른 예약어와 겹칠 때 자동으로 백틱이나 따옴표를 써줌

---
#설명 없는 코드 전체

spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true 
spring.jpa.properties.hibernate.globally_quoted_identifiers=true

properties에 이 5가지 코드는 필수이다!

Entity

Entity는 단순하게 표현하자면 객체이다. 이 곳에 코드를 작성하게 되면, 데이터베이스에 테이블이 생성된다.
Entity - DB의 컬럼 이름은, 카멜케이스 - 스네이크 케이스로 매칭이 된다.

@Entity
@Id 
@GenaratedValue(strategy = GenerationType.IDENTITY) -> 자동으로 인덱스 매겨짐.
@Table(테이블이름)
@Column -> 컬럼과 관련된 속성 지정.
  • @Entity @Id 는 필수!
  • column에서, 기본 자료형은 널값을 허용하지 않고 참조 자료형은 널값을 허용한다. 보통, 참조 자료형을 많이 사용한다고 한다.
  • Date + @Temporal(날짜만 / 시간만 / 날짜 + 시간)
  • LocalDate / LocalTime/ LocalDateTime (추천)
  • Date의 import는 java.util.Date
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity(name = "table_exam1")
public class TableExam1 {

    @Id
    Integer id;

    @Column(length = 100, nullable = false)
    String title;

    @Column(name = "description", length = 1000, nullable = true)
    String content;
    Long price;
    String brand;
    

}

CRUD

Repository

Entity 객체를 만든 후에는, 레파지토리를 만들어 데이터를 제어할 준비를 한다. 데이터를 입력, 조회, 수정, 삭제할 수 있는 CRUD 상태를 만들어 주기 위해서 사용되고, 객체와 db를 매핑하여 sql을 자동 생성해준다.

Repository에는 입력/수정 save(), 삭제 delete(), 조회 findById() findAll() 메소드를 포함하고 있다.

findAll() -> list

findById() -> optional (null을 해결하기 위해 만들어 놓은 자료형)

cf) optional랑 같이 쓰이는 코드


Optional<Exam1> opt = ExamRepository.findById(1000);

opt가 존재하면,
1. if(opt.isPresent()) {
	Exam ex = opt.get();
}

.

opt가 존재하지 않으면
2. Exam ex2 = opt.orElse(null)

.

값이 있으면 뒤 코드를 동작시키지 않음 (효율)
3. Exam ex3 = opt.orElseGet(() => { null;});

.
값이 없으면 예외 던지기
4. opt.orElseThrow()

Repository는 JpaRepository와 상속관계의 인터페이스이다. Jpa가 레파지토리를 상속한 후 구현하게 된다. 코드는 꽤 간단한 편인데,

public interface TableExam1Repository 
		extends JpaRepository<TableExam1, Integer> {   }

여기서 주의할 점은, JpaRepository<Entity 클래스 이름, 그 클래스 pk의 자료형> 을 명시해 주어야 한다는 점이다.

그리고, Entity 클래스에서 getter, setter 할 수 있는 @Data를 꼭 써줘야 객체를 조작할 수 있다.

이제 다음 단계는 controller에 가서 데이터를 가지고 노는 것이다!

삽입

@RestController
public class TableExam1Controller {
    @Autowired TableExam1Repository tableExam1Repository;

    @GetMapping("/exam1/add")
    public TableExam1 ExamAdd(@ModelAttribute TableExam1 ta) {
        TableExam1 result = tableExam1Repository.save(ta);
            return result;
        }
  }

조회

@GetMapping("/exam1/list")
public List<TableExam1> ExamLIst() {
     List<TableExam1> list = tableExam1Repository.findAll();
     return list;
}

삭제

@GetMapping("/exam1/delete")
public String ExamDelete(@ModelAttribute TableExam1 ta) {
      tableExam1Repository.delete(ta);
      return "삭제완료";
} -> 삭제할 떄는 id를 검색을 기반으로 함

페이징

@GetMapping("/exam/list")
public List<TableExam1> AssList(
@RequestParam(defaultValue = "1" ) int page, 
@RequestParam(defaultValue = "10" ) int count) {
   Order order = Order.desc("id");
   Sort sort = Sort.by(order);
   Pageable pageable = PageRequest.of(page - 1, count, sort); 
   
   
Page<TableExam1> list = assemblyRepository.findAll(pageable);
-> 페이징 쓰지 않을 때 한번에 출력함 -> 로딩 느림

return list.getContent();
}

Junit

단위 테스트 프레임워크.
@Test annotation이 있는 메소드 단위로 테스트가 가능해진다.

profile
파랑입니다.

0개의 댓글