👉 기본 환경

- Language: Java

- DB: MySQL

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
 
@RestController
public class ApiController {
 
    @GetMapping(value = "/getMidFcst")
    public Object midFcstInfoAPI() {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
 
        String midFcstInfo_url = "https://apis.data.go.kr/1360000/MidFcstInfoService/{fcst}";
 
        UriComponents uri = UriComponentsBuilder
                .fromHttpUrl(midFcstInfo_url)
                .queryParam("fcst""getMidFcst")
                .queryParam("serviceKey""")
                .queryParam("numOfRows"5)
                .queryParam("pageNo"1)
                .queryParam("dataType""XML")
                .queryParam("stnId""")
                .queryParam("tmFc""")
                .build();
 
        ResponseEntity<String> result = restTemplate.exchange(uri.toUriString(), HttpMethod.GET, new HttpEntity<String>(headers), String.class);
 
        return result;
    }
 
}
 
 
 

😮 http://localhost:8080/getMidFcst 호출

 

 

🖨️오류

java.lang.IllegalArgumentException: Not enough variable values available to expand 'fcst'

 

 

📡 원인

{fcsg}는 queryParam으로 처리함

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
 
@RestController
public class ApiController {
 
    @GetMapping(value = "/getMidFcst")
    public Object midFcstInfoAPI() {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
 
        String midFcstInfo_url = "https://apis.data.go.kr/1360000/MidFcstInfoService/{fcst}";
 
        UriComponents uri = UriComponentsBuilder
                .fromHttpUrl(midFcstInfo_url)
                .queryParam("serviceKey""")
                .queryParam("numOfRows"5)
                .queryParam("pageNo"1)
                .queryParam("dataType""XML")
                .queryParam("stnId""")
                .queryParam("tmFc""")
                .buildAndExpand("getMidFcst");
 
        ResponseEntity<String> result = restTemplate.exchange(uri.toUriString(), HttpMethod.GET, new HttpEntity<String>(headers), String.class);
 
        return result;
    }
 
}
 
 
 

buildAndExpand()

    - fcst는 queryParam(A=B 형식)으로 처리하는 것이 아닌 변수에 fcst 변수에 대입하는 방법으로 처리해야함

 

👉 기본 환경

- Language: Java

- DB: MySQL

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RestController
public class ApiController {
 
    @GetMapping(value = "/getMidFcst")
    public void getMidFcst() {
 
        ...
 
        String response = result.block();
 
        JSONObject obj = XML.toJSONObject(response.toString());
        JSONObject items = obj.getJSONObject("response")
                .getJSONObject("body")
                .getJSONObject("items");
 
        JSONObject item = items.getJSONObject("item");
 
    }
 
}
 
 
 

 

 

🖨️오류

org.json.JSONException: JSONObject["response"] not found.

 

📡 원인

API 호출에 따라 return data에는 response가 있지만, data type을 xml이 아닌 json으로 요청함

 

 

📰 해결 방법

요청 데이터 타입을 JSON ▶ XML 수정

 

👉 기본 환경

- Language: Java

- DB: MySQL

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
public class ApiController {
 
    @GetMapping(value = "/getMidFcst")
    public void getMidFcst() {
    }
 
    @GetMapping(value = "/getMidFcst")
    public void getMidFcst() {
    }
 
}
 
 
 

 

 

🖨️오류

java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'apiController' method 

 

 

📡 원인

apiController에 value가 동일한 method가 2개 존재

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
public class ApiController {
 
    @GetMapping(value = "/getMidFcst")
    public void getMidFcst() {
    }
 
    @GetMapping(value = "/getMidFcst2")
    public void getMidFcst2() {
    }
 
}
 
 
 

중복된 value 수정

 

👉 기본 환경

- Language: Java

- DB: MySQL

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.14'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
 
group = 'com.example'
version = '0.0.1-SNAPSHOT'
 
java {
    sourceCompatibility = '11'
}
 
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
 
repositories {
    mavenCentral()
}
 
dependencies {
    implementation 'org.springframework.boot:spring-boot-devtools'
    implementation 'org.springframework.boot:spring-boot-starter-web'
 
    compileOnly 'org.projectlombok:lombok'
 
    runtimeOnly 'com.mysql:mysql-connector-j'
 
    annotationProcessor 'org.projectlombok:lombok'
 
}
 
tasks.named('test') {
    useJUnitPlatform()
}
 
 
 

 

 

🖨️오류

1
2
3
4
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
 
Reason: Failed to determine a suitable driver class
 
 
 

 

 

📡 원인

DB 연결 정보가 설정되지 않음

 

 

📰 해결 방법

application.yml에 DB 정보 설정

* application.properties와 동일하나, 문법이 다름

1
2
3
4
5
6
7
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Seoul
    username: DB_생성_시_입력한_username
    password: DB_생성_시_입력한_password 
 
 
 

 

 

 

📚 참고 자료

 

Spring error - Failed to configure a DataSource 에러 원인과 해결 방법

Failed to configure a DataSource 에러와 원인과 해결 방법 메시지 Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. *************************** APPLICATION FAILED TO START ********

7942yongdae.tistory.com

 

이 글은 김영한의 [자바 ORM 표준 JPA 프로그래밍 - 기본편] 수강하며 정리한 글입니다.

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

ERD

 

 

Member Entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
 
@Entity
public class Member {
 
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
 
    private String name;
    private String city;
    private String street;
    private String zipcode;
 
    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();
 
}
 
 
 

 

 

Order Entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
 
@Entity
@Table(name = "ORDERS")
public class Order {
 
    @Id @GeneratedValue
    @Column(name = "ORDER_ID")
    private Long id;
 
    @ManyToOne
    @JoinColumn(name = "MEMBER_ID")
    private Member member;
 
    @OneToMany(mappedBy = "order")
    private List<OrderItem> orderItems = new ArrayList<>();
 
    @OneToOne
    @JoinColumn(name = "DELIVERY_ID")
    private Delivery delivery;
 
    private LocalDateTime orderDate;
 
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
 
}
 
 
 

- @ManyToOne + @JoinColumn

    - 다대일 관계에서 다의 위치가 연관관계 주인

 

- @OneToMany(mappedBy)

    - 일대다 관계에서 일의 위치가 조회를 위한 임의 매핑

 

- @OneToOne

   - 일대일 관계에서 연관관계 주인은 상황에 따라 선택 가능

 

- @Enumerated(EnumType.STRING)

    - enum type 사용 시, @Enumerated type.STRING 지정 필수

 

 

Delivery Entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import javax.persistence.*;
 
@Entity
public class Delivery {
 
    @Id @GeneratedValue
    @Column(name = "DELIVERY_ID")
    private Long id;
 
    @OneToOne(mappedBy = "delivery")
    private Order order;
 
    private String city;
    private String street;
    private String zipcode;
 
    @Enumerated(EnumType.STRING)
    private DeliveryStatus status;
 
}
 
 
 

 

 

OrderItem Entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import javax.persistence.*;
 
@Entity
public class OrderItem {
 
    @Id @GeneratedValue
    @Column(name = "ORDER_ITEM_ID")
    private Long id;
 
    @ManyToOne
    @JoinColumn(name = "ORDER_ID")
    private Order order;
 
    @ManyToOne
    @JoinColumn(name = "ITEM_ID")
    private Item item;
 
    @Column(name = "ORDER_PRICE")
    private int price;
    private int count;
 
}
 
 
 

 

 

Item Entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
 
@Entity
public class Item {
 
    @Id @GeneratedValue
    @Column(name = "ITEM_ID")
    private Long id;
 
    private String name;
    private int price;
    private int stockQuantity;
 
    @ManyToMany(mappedBy = "items")
    private List<Category> categories = new ArrayList<>();
 
}
 
 
 

- @ManyToMany

  ⭐ 관계형 데이터베이스에서 다대다 (Many-to-Many) 관계를 직접적으로 표현하는 것은 불가능

        ▶ 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야 함

 

 

 

Category Entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
 
@Entity
public class Category {
 
    @Id @GeneratedValue
    @Column(name = "CATEGORY_ID")
    private Long id;
 
    private String name;
 
    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Category parent;
 
    @OneToMany(mappedBy = "parent")
    private List<Category> children = new ArrayList<>();
 
    @ManyToMany
    @JoinTable(name = "CATEGORY_ITEM",
        joinColumns = @JoinColumn(name = "CATEGORY_ID"),
        inverseJoinColumns = @JoinColumn(name = "ITEM_ID")
    )
    private List<Item> items = new ArrayList<>();
}
 
 
 

- private Category parent

- private List<Category> children = new ArrayList<>()

    - 한 카테고리가 다른 카테고리를 부모로 가지는 계층 구조를 표현

    - 부모 : 자식 = 일 : 다

 

- @JoinTable

    - CATEGORY와 ITEM의 PK로 이뤄진 연결 테이블 생성

    - joinColumns

        - 현재 엔티티(Category)와 연결되는 외래키

    - inverseJoinColumns

        - 상대 엔티티(Item)와 연결되는 외래키

 

 

실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
Hibernate: 
    
    create table Category (
       CATEGORY_ID bigint not null,
        name varchar(255),
        PARENT_ID bigint,
        primary key (CATEGORY_ID)
    )
 
Hibernate: 
    
    create table CATEGORY_ITEM (
       CATEGORY_ID bigint not null,
        ITEM_ID bigint not null
    )
 
Hibernate: 
    
    create table Delivery (
       DELIVERY_ID bigint not null,
        city varchar(255),
        status varchar(255),
        street varchar(255),
        zipcode varchar(255),
        primary key (DELIVERY_ID)
    )
 
Hibernate: 
    
    create table Item (
       ITEM_ID bigint not null,
        name varchar(255),
        price integer not null,
        stockQuantity integer not null,
        primary key (ITEM_ID)
    )
 
Hibernate: 
    
    create table Member (
       MEMBER_ID bigint not null,
        city varchar(255),
        name varchar(255),
        street varchar(255),
        zipcode varchar(255),
        primary key (MEMBER_ID)
    )
 
Hibernate: 
    
    create table OrderItem (
       ORDER_ITEM_ID bigint not null,
        count integer not null,
        price integer not null,
        ITEM_ID bigint,
        ORDER_ID bigint,
        primary key (ORDER_ITEM_ID)
    )
 
Hibernate: 
    
    create table ORDERS (
       ORDER_ID bigint not null,
        orderDate timestamp,
        status varchar(255),
        DELIVERY_ID bigint,
        MEMBER_ID bigint,
        primary key (ORDER_ID)
    )
 
 
 
Hibernate: 
    
    alter table Category 
       add constraint FK8tepc1qkmluodspg6tnliwhit 
       foreign key (PARENT_ID) 
       references Category
 
Hibernate: 
    
    alter table CATEGORY_ITEM 
       add constraint FKf1uerpnmn49vl1spbbplgxaun 
       foreign key (ITEM_ID) 
       references Item
 
Hibernate: 
    
    alter table CATEGORY_ITEM 
       add constraint FKjip0or3vemixccl6vx0kluj03 
       foreign key (CATEGORY_ID) 
       references Category
 
Hibernate: 
    
    alter table OrderItem 
       add constraint FKabge9eqalspcejij53rat7pjh 
       foreign key (ITEM_ID) 
       references Item
 
Hibernate: 
    
    alter table OrderItem 
       add constraint FKk7lmf97wukpquk6d8blxy5neq 
       foreign key (ORDER_ID) 
       references ORDERS
 
Hibernate: 
    
    alter table ORDERS 
       add constraint FKdbs21f1yi0coxy9y0kxw4g9jf 
       foreign key (DELIVERY_ID) 
       references Delivery
 
Hibernate: 
    
    alter table ORDERS 
       add constraint FKh0db7kqr88ed8hqtcqw3jkcia 
       foreign key (MEMBER_ID) 
       references Member