프로젝트 준비하기
- IntelliJ 실행
- New Project 클릭
- Spring initializr 클릭 후
- Name: jpa-advance
- Language: Java
- Build system: Gradle - Groovy
- Group:
- JDK: 17
- Next 클릭
- Dependencies 추가
- Spring Data JPA
- Spring Web
- MySQL Driver
- Lombok
프로젝트 설정 추가
- src > main > resources > application.properties
- application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/orderapp spring.datasource.username=root spring.datasource.password={비밀번호} spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true
- IntelliJ DB 연동
CREATE DATABASE orderapp;
- Database 클릭 후, + 버튼 클릭
- Data Source > MySQL 클릭
- User, Password, Database 정보 추가
- 완료!
고객(users) 테이블
id name 1 Robbie 2 Robbert create table users ( id bigint not null auto_increment, name varchar(255), primary key (id) );
음식(food) 테이블
id name price 1 후라이드 치킨 15000 2 양념 치킨 20000 3 고구마 피자 30000 4 아보카도 피자 50000 create table food ( id bigint not null auto_increment, name varchar(255), price float(53) not null, primary key (id) );
고객이 음식을 주문 시, 주문 정보는 어느 테이블에 들어가야 할까?
한명의 고객은 음식을 여러개 주문 가능
주문한 음식의 정보를 파악하기 위해 food_id 컬럼 추가
고객 테이블에 주문 정보를 넣음
id | name | food_id |
---|---|---|
1 | Robbie | 1 |
2 | Robbert | 1 |
3 | Robbie | 2 |
Robbie는 후라이드 치킨, 양념 치킨 주문
하나의 음식은 여러명의 고객에게 주문될 수 있음
주문한 음식의 정보를 파악하기 위해 user_id 컬럼 추가
음식 테이블에 주문 정보를 넣음
id | name | price | user_id |
---|---|---|---|
1 | 후라이드 치킨 | 15000 | 1 |
2 | 후라이드 치킨 | 15000 | 2 |
3 | 양념 치킨 | 20000 | 1 |
후라이드 치킨을 여러 사람이 주문하게 되었을 때
불칠요하게 음식의 이름이 중복되는 문제 발생
주문에 대한 정보를 기록할 orders 테이블 추가
create table orders
(
id bigint not null auto_increment,
user_id bigint,
food_id bigint,
order_date date,
primary key (id)
);
주문 테이블을 사용하여 테이블들의 연관 관계 해결
drop table if exists food;
drop table if exists users;
create table users
(
id bigint not null auto_increment,
name varchar(255),
primary key (id)
);
create table food
(
id bigint not null auto_increment,
name varchar(255),
price float(53) not null,
primary key (id)
);
alter table orders
add constraint orders_user_fk
foreign key (user_id)
references users (id);
alter table orders
add constraint orders_food_fk
foreign key (food_id)
references food (id);
INSERT INTO users (name) VALUES ('Robbie');
INSERT INTO users (name) VALUES ('Robbert');
INSERT INTO food (name, price) VALUES ('후라이드 치킨', 15000);
INSERT INTO food (name, price) VALUES ('양념 치킨', 20000);
INSERT INTO food (name, price) VALUES ('고구마 피자', 30000);
INSERT INTO food (name, price) VALUES ('아보카도 피자', 50000);
INSERT INTO orders (user_id, food_id, order_date) VALUES (1, 1, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 1, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 2, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (1, 4, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 3, SYSDATE());
고객
id | name |
---|---|
1 | Robbie |
2 | Robbert |
음식
id | name | price |
---|---|---|
1 | 후라이드 치킨 | 15000 |
2 | 양념 치킨 | 20000 |
3 | 고구마 피자 | 30000 |
4 | 아보카도 피자 | 50000 |
주문
id | user_id | food_id | 주문일 |
---|---|---|---|
1 | 1 | 1 | 2023-01-01 |
2 | 2 | 1 | 2023-01-01 |
3 | 2 | 2 | 2023-01-01 |
4 | 1 | 3 | 2023-01-01 |
5 | 2 | 3 | 2023-01-01 |
고객 1명은 음식 N개 주문 가능
음식 1개는 고객 N명에게 주문될 수 있음
결론적으로 고객과 음식은 N : M 관계
이렇듯 N : M 관계인 테이블들의 연관 관계를 해결하기 위해 orders 테이블처럼 중간 테이블 사용 가능
SELECT u.name as username, f.name as foodname, o.order_date as orderdate
FROM users u
INNER JOIN orders o on u.id = o.user_id
INNER JOIN food f on o.food_id = f.id
WHERE o.user_id = 1;
SELECT u.name as username, f.name as foodname, o.order_date as orderdate
FROM food f
INNER JOIN orders o on f.id = o.food_id
INNER JOIN users u on o.user_id = u.id
WHERE o.user_id = 1;
JPA Entity에서는 테이블간의 연관 관계를 어떻게 표현할까?
음식 : 고객 = N : 1
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();
}
List<Food> foodList = new ArrayList<>()
로 표현 가능단방향 관계는 어떻게 표현될까
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}