
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
// 또는 MariaDB 사용 시
// runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
}
spring:
datasource:
driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3306/menudb
username: swcamp
password: swcamp
jpa:
show-sql: true
hibernate:
ddl-auto: none
naming:
physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
properties:
hibernate:
format_sql: true
myFieldName → my_field_name 으로 물리 이름 변환none 권장(마이그레이션 도구 사용)주의: 의존성의 DB 드라이버와
driver-class-name은 일치시켜야 한다. (MySQL 커넥터 사용 시com.mysql.cj.jdbc.Driver)
하나의 Category에 여러 Menu가 속하는 관계. 외래키는 Menu(다 쪽)가 가진다.
@Entity(name = "Section01Category")
@Table(name = "tbl_category")
public class Category {
@Id private int categoryCode;
private String categoryName;
private Integer refCategoryCode;
protected Category() {}
}
@Entity(name = "menu_and_category")
@Table(name = "tbl_menu")
public class Menu {
@Id private int menuCode;
private String menuName;
private int menuPrice;
@ManyToOne(cascade = CascadeType.PERSIST) // Menu 저장 시 Category도 함께 저장
@JoinColumn(name = "categoryCode") // FK 컬럼명
private Category category;
private String orderableStatus;
protected Menu() {}
}
| 어노테이션 | 핵심 속성 | 요약 |
|---|---|---|
| @JoinColumn | name, referencedColumnName, nullable, unique, insertable, updatable, columnDefinition, foreignKey | FK 컬럼 제어 |
| @ManyToOne | cascade, fetch, optional | 전이/로딩/필수 여부 |
String jpql =
"SELECT c.categoryName " +
"FROM menu_and_category m JOIN m.category c " +
"WHERE m.menuCode = :menuCode";
FROM에는 테이블명이 아닌 엔티티명을 사용Menu.persist() → FK가 가리키는 Category도 함께 persist → tbl_category insert → tbl_menu insert
Category → Menu 리스트를 직접 참조. 단방향 1:N은 조인 컬럼을 부모 쪽에서 관리해야 하므로 insert 이후에 update가 한 번 더 발생할 수 있다.
@Entity(name = "Section02Menu")
@Table(name = "tbl_menu")
public class Menu {
@Id private int menuCode;
private String menuName;
private int menuPrice;
private int categoryCode; // FK 컬럼
private String orderableStatus;
protected Menu() {}
}
@Entity(name = "category_and_menu")
@Table(name = "tbl_category")
public class Category {
@Id private int categoryCode;
private String categoryName;
private Integer refCategoryCode;
@JoinColumn(name = "categoryCode") // 자식 테이블 FK
@OneToMany(cascade = CascadeType.PERSIST) // 전이 저장
private List<Menu> menuList;
protected Category() {}
}
tbl_category inserttbl_menu inserttbl_menu update(케이스에 따라 발생)실전에서는 양방향(N:1 주인, 1:N mappedBy) 또는 다대일 단방향을 더 권장
외래키를 가진 Menu(@ManyToOne) 가 연관관계의 주인.
반대편 Category는 mappedBy = "category" 로 읽기 전용 뷰.
@Entity(name="bidirection_menu")
@Table(name = "tbl_menu")
public class Menu {
@Id private int menuCode;
private String menuName;
private int menuPrice;
@JoinColumn(name = "categoryCode")
@ManyToOne
private Category category;
private String orderableStatus;
protected Menu() {}
}
@Entity(name = "bidirection_category")
@Table(name = "tbl_category")
public class Category {
@Id private int categoryCode;
private String categoryName;
private Integer refCategoryCode;
@OneToMany(mappedBy = "category") // 주인: Menu.category
private List<Menu> menuList;
protected Category() {}
}
FROM에 엔티티명 사용, 파라미터 바인딩 습관화