2023.09.15
JPA(Java Persistent API)란?
: JPA는 자바 진영의 ORM(Object-Relational Mapping. 객체와 관계형 DB를 매핑) 기술 표준을 의미합니다.
즉, 데이터를 영구적으로 저장할 수 있도록 Java 진영에서 정해진 규칙이며, SQL문을 직접 작성하지 않고 코드 내에서 CRUD작업을 할 수 있도록 해 줍니다. Hibernate가 JPA를 구현해줍니다.
(주의/ JPA를 사용하려면 해당 클래스의 기본 생성자를 꼭 만들어줘야 합니다.)
Spring Data JPA란?
: 복잡한 JPA코드를 스프링으로 쉽게 사용할 수 있도록 도와주는 라이브러리입니다.
JPA를 사용합니다.
왜 필요한가?
- SQL문을 사람이 직접 작성하면 문법 실수가 나올 수 있고, 해당 실수는 컴파일 시점이 아니라 런타임 시점에 발견되므로 발견까지 시간이 오래 걸립니다.
- DB마다 문법이 다르므로 추후 DB변경이 필요할 때 일일이 수정하는 데에 비용과 시간이 많이 들기 때문에 특정 DB에 종속될 가능성이 큽니다.
- 테이블이 생성될 때 마다 새로운 CRUD 연산이 필요하므로 반복 작업이 많아집니다.
JPA는 단순 규칙이며, 해당 규칙을 구현해주는 구현체인 Hibernate를 통해 구현할 수 있습니다.
Hibernate는 내부적으로 JDBC를 사용합니다.
application.yml 설정
: JPA를 사용하려면 application.yml 파일에 다음과 같은 설정을 해 주어야 한다.
spring:
datasource:
url: "jdbc:mysql://localhost/library"
username: "root"
password: ""
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: none
//스프링 시작 시 DB의 테이블 처리에 대한 옵션
//create : 기존 테이블 삭제 후 재생성
//create-drop : 스프링 종료 시 테이블 모두 제거
//update : 객체와 테이블이 동일한지 확인
//none : 별다른 조치 하지 않음
properties:
hibernate:
show_sql: true
//JSA로 SQL을 날릴 때 SQL문을 보여주는지 여부
format_sql: true
//SQL문을 보여줄 때 포맷팅 할 것인지 여부
dialect: org.hibernate.dialect.MySQL8Dialect
//DB 종류를 설정하면 자동으로 문법에 맞게 SQL문을 수정해줌.
//위는 MySQL8.0버전으로 설정한 것.
JPA 관련 어노테이션들
@Entity | 스프링이 객체와 테이블을 같은 것으로 바라보게 함. |
@Id | 해당 필드를 Primary Key로 간주함. |
@GeneratedValue | Primary Key를 자동 생성되는 값으로 설정. @GeneratedValue(strategy = GenerationType.IDENTITY) : Mysql의 auto_increment와 동일 |
@Column | 객체의 필드와 테이블의 필드를 매핑. 생략 가능함. null 가능 여부, 길이 제한, DB의 컬럼명 설정 등. (객체와 DB 컬럼명이 동일하면 생략 가능함.) |
Fruit 객체와 Fruit 테이블을 조작하는 예시
테이블 구조
CREATE TABLE fruit{
id int auto_increment,
name varchar(20),
primary key(id)
)
fruit 객체
@Entity //--> 객체와 테이블을 매핑하도록 하는 어노테이션
public class Fruit {
@Id //-->id를 객체에 추가해줌.
@GenerateValue(strategy = GenerationRype.IDENTITY) //->primary key 표시
private Integer id = null;
@Column(nullable = false, length = 20, name = "name")
//Column에 붙이는 어노테이션.
//주로 null 여부, 길이제한, DB에서의 column이름을 설정.(이름이 다를 경우)
private String name;
protected Fruit() {}
//JPA에 의해 테이블과 매핑된 객체는 파라미터가 없는 기본 생성자가 꼭 필요함.
public Fruit(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
사용자 입력 받는 request 객체
public class FruitsaveRequest {
private String name;
public String getName() {
return name;
}
}
JPA 사용하지 않는 경우
//FruitService.java
public class FruitService {
private final FruitRepository fruitRepository;
//service에서 repository 선언
public FruitService(JdbcTemplate jdbcTemplate) {
this.fruitRepository = new fruitRepository(jdbcTemplate);
}
public void saveFruit(FruitSaveRequest request){
fruitRepository.saveFruit(request.getName());
}
--------------------------------------------------------------------
//FruitRepository.java
public class FruitRepository {
private final JdbcTemplate jdbcTemplate;
public FruitRepository(JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
}
public void saveFruit(String name){
String sql = "INSERT INTO fruit (name) VALUES (?)";
//코드 내에서 SQL문을 직접 작성해야 함.
jdbcTemplate.update(sql, name);
}
}
JPA 사용하는 경우
//FruitService.java
@Service
public class FruitService2 {
private final FruitRepository fruitRepository;
public FruitService2(FruitRepository fruitRepository){
this.fruitRepository = fruitRepository;
}
public void saveFruit(FruitSaveRequest request) {
fruitRepository.save(new Fruit(request.getName()));
//save 메소드를 호출하면 INSERT문이 자동으로 날아감.
}
}
------------------------------------------------------------------
//FruitRepository.java
public interface FruitRepository extends JpaRepository<Fruit, Integer> {
//JpaRepository<객체, 객체의 id 자료형> 으로 설정
// Spring Data JPA가 자동으로 해당 메서드를 구현.
}
'오늘의 취준 > 오늘의 공부' 카테고리의 다른 글
MVC 패턴 (0) | 2023.09.16 |
---|---|
비대칭키 암호화, 대칭키 암호화 (0) | 2023.09.16 |
[Java] comparable 인터페이스 (0) | 2023.08.12 |
[Java/Queue] 큐 사용하기 (0) | 2023.08.09 |
[JAVA/VScode] 자바 개발환경 세팅하기 (0) | 2023.08.08 |