schedulev2
lv1의 Schedulev2 crud 중에서 rud 아직 못 만듬, lv2,lv3는 다 했고 lv4의 filter까지 구현, login api 새로 작성완료, 다른 api 수정중
lv4의 인증처리만 적용하면 거의 다 할 것 같고 코드는 너무 많아서 깃허브 주소를 남기겠습니다.
깃허브 주소 -> https://github.com/byeongtaek12/ScheduleProject-Spring-JPA
DB는 상속관계 없음

관계형 DB에서는 Data를 슈퍼타입, 서브타입 관계로 설정
테이블의 연관관계는 외래 키를 사용
객체의 연관관계는 참조를 사용
조회 SQL
객체 지향 언어에서 데이터와 동작을 함께 캡슐화하는 방식과, RDB가 데이터를 정규화된 테이블에 관계 중심으로 저장하는 방식의 차이에서 발생하여 객체를 데이터베이스에 저장하거나 조회할 때 복잡한 매핑과 변환이 필요해지고 코드의 복잡성과 개발자의 부담이 증가
SELECT p.*, c.* FROM product p JOIN category c ON p.category_id = c.id;
Product product1 = productRepository.findById(productId);
Product product2 = productRepository.findById(productId);
product1 == product2; // false
Collection에 저장하면 편하게 사용할 수 있음
객체 지향 프로그래밍 언어인 Java와 관계형 데이터베이스 간의 패러다임 불일치 문제를 해결하여 데이터베이스 작업을 객체 지향적으로 수행할 수 있도록 지원
Java의 ORM 기술 표준(인터페이스)

ORM(Object-Relational Mapping)

개발자가 아닌 JPA가 JDBC API를 내부적으로 사용하여 중간에서 개발자의 역할을 함
Hibernate가 사용하는 데이터베이스 방언(dialect)을 지정하는 설정으로 데이터베이스와 Hibernate가 상호작용할 때 특정 데이터베이스에 맞게 SQL 구문을 자동으로 조정하는 역할을 수행
데이터베이스에서 Entity란 저장할 수 있는 데이터의 집합

비영속, 영속, 준영속, 삭제 상태로 나뉘며 영속 상태일 때만 JPA의 영속성 컨텍스트가 데이터를 관리
Tutor tutor = new Tutor(1L, "이름", 100);
em.persist(tutor);
transaction.commit();
em.detach()em.clear()em.close()em.remove(tutor);
// 비영속
Tutor tutor = new Tutor(1L, "이름", 100);
// 영속, 1차 캐시에 저장
em.persist(tutor);
// 1차 캐시에서 조회
Tutor findTutor = em.find(Tutor.class, 1L);
1차 캐시가 없다면?
// 데이터베이스에서 조회 후 1차 캐시에 저장
Tutor findTutor = em.find(Tutor.class, 1L);
✔1차 캐시는 동일한 트랜잭션에서만 사용 가능
영속성 컨텍스트가 엔티티의 초기 상태를 저장하고 트랜잭션 커밋 시점에 현재 상태와 비교해 변경 사항이 있는지 확인하는 기능
Tutor tutor = em.find(Tutor.class, 1L);
tutor.setName("수정된 이름");
✔오히려 쓰게 되면 에러가 날 수도 있어서 사용하지 않아야 실수 방지 가능

클래스에 @Entity를 붙이면 JPA가 관리하는 Entity가 됨
namecatalogschemauniqueConstraintscreate: 기존 테이블을 삭제(DROP) 후 다시 생성(CREATE)
create-drop: DROP 후 CREATE 하고 종료시점에 테이블을 삭제(DROP), 테스트 시 사용
update: 변경된 사항만 DDL에 반영
validate: Entity와 테이블이 정상적으로 매핑 되었는지 확인. 실패 시 예외 발생
none: 속성 사용X
@Column(unique = true, length = 20, nullable = false)
JPA로 관리되는 클래스인 Entity의 필드는 테이블의 컬럼과 매핑
JPA Entity를 생성할 때 기본키는 필수로 생성해야 함
Tutor tutor = new Tutor(1L, "이름"); @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;Long Type의 기본 키를 사용하는 것GenerationTypeIDENTITY : MySQL, PostgreSQL에서 사용, 데이터베이스가 PK 자동 생성SEQUENCE : Oracle에서 사용, @SequenceGenerator 와 함께 사용TABLE : 키 생성용 테이블을 사용, @TableGenerator 와 함께 사용AUTO : dialect에 따라 자동 지정, 기본값IDENTITY, Oracle이면 SEQUENCE 로 설정✅ 기본적으로 AUTO_INCREMENT는 DB에 INSERT SQL이 실행된 이후 PK를 알 수 있지만 IDENTITY 전략은 트랜잭션 Commit 후가 아닌 em.persist() 시점에 즉시 INSERT SQL을 실행하여 PK를 바로 조회할 수 있음


@ManyToOne, @JoinColumn을 사용Tutor findTutor = em.find(Tutor.class, 1L);
Company findCompany = findTutor.getCompany();
// 단방향 연관관계에서 아래 코드는 실행이 불가능
findCompany.getTutor();

mappedBy 속성을 설정company 필드와 매핑CrudRepository, JpaRepository 인터페이스를 제공EntityManager를 직접 호출하지 않아도 기본적인 CRUD 기능을 손쉽게 구현@Query 를 사용하여 JPQL 또는 Native Query를 정의할 수 있음public interface MemberRepository extends JpaRepository<Member, Long> {
} // <"@Entity 클래스", "@Id 데이터 타입">

출처: 쿼리 공식문서 https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html
@MappedSuperclass
public class BaseEntity{
@Column(updatable = false)
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
@PrePersist
public void prePersist(){
LocalDateTime now = LocalDateTime.now();
created_at = now;
updated_at = now;
}
@PreUpdate
public void preUpdate() {
updated_at = LocalDateTime.now();
}
}
@EnableJpaAuditing // JPA Auditing 기능을 활성화
@SpringBootApplication
public class SpringDataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDataJpaApplication.class, args);
}
}
@Getter
@MappedSuperclass // 해당 어노테이션이 선언된 클래스를 상속받는 Entity에 공통 매핑 정보를 제공
@EntityListeners(AuditingEntityListener.class) // Entity를 DB에 적용하기 전, 커스텀 콜백을 요청할 수 있는 어노테이션
public abstract class BaseEntity {
@CreatedDate // 생성 시점의 날짜를 자동으로 기록
@Column(updatable = false)
@Temporal(TemporalType.TIMESTAMP) // 날짜 타입을 세부적으로 지정
private LocalDateTime createdAt;
@LastModifiedDate // 수정 시점의 날짜를 자동으로 기록
@Temporal(TemporalType.TIMESTAMP)
private LocalDateTime modifiedAt;
}
@EntityListeners(AuditingEntityListener.class)
@PrePersist 을 사용확실히 배우면 배울수록 재밌는 것 같다. 이 바닥 희로애락이 다 담겨있어서 나쁘지 않네요. 직업으로 삼기에 내일은 필수 마무리 짓고 도전 조금 맛만 보겠습니다. 아 맞다 오늘 zep에서 오토바이 한대 뽑았습니다. 포인트 열심히 모아서~
소확행이네요ㅎㅎ 😁 차 여러 대 뽑으려면 포인트 많이 모아야겠습니다. 화이팅!