Unity의 Culling Mask란 원하는 Layer를 가진 Object들만 카메라로 볼 수 있게 하는 기능입니다.

image

우선 여러개의 Cube를 생성하여 그룹을 나눕니다. (Group1, Group2)

구별을 위해 Group1에는 파란색, Group2에는 빨간색 Material을 넣었습니다.

 

그리고 그룹 간 구분을 위해 Layer -> Add Layer에서 Layer를 두개 만들어줍니다.
저는 "Group1"과 "Group2"를 생성하였습니다.

imageimage

 

그 다음 Group1에 "Group1" 이라는 Layer를, Group2에 "Group2" 라는 Layer를 추가해 넣어줍니다.

imageimage

이제 Culling Mask 사용을 위한 준비가 끝났습니다.

 

Main Camera의 Inspector -> Camera Component에 Culling Mask가 있습니다.
현재 Everything이 default로 지정이 되어있으며, 모든 Object를 카메라로 보여주고 있습니다.

image

그리고 현재 메인 카메라에 보이는 모습입니다.

 

이제 Culling Mask에서 Group1을 지우겠습니다.

Group1을 체크 해제하는 순간 Culling Mask는 Everything -> Mixed가 되는 것을 볼 수 있으며

Scene 창에서는 Group1이 보이지만 메인 카메라 화면에는 보이지 않는 것을 확인할 수 있습니다.

 

다만 카메라에는 안보이지만 실제로 존재하는 Object이므로 충돌 판정은 있습니다.

Collider를 없애서 그냥 통과하게 만들거나 하는 응용도 가능해보입니다.

'Etc' 카테고리의 다른 글

GitLab -> GitHub Mirroring  (0) 2022.06.12
Unity Script로 카메라 Culling Mask 기능 사용하기  (2) 2021.10.29
TypeScript 실행  (0) 2021.08.30
TypeScript 설치  (0) 2021.08.30
Windows 10 에서 WSL을 이용한 우분투 설치  (0) 2021.08.29

https://www.acmicpc.net/problem/1253

 

1253번: 좋다

첫째 줄에는 수의 개수 N(1 ≤ N ≤ 2,000), 두 번째 줄에는 i번째 수를 나타내는 Ai가 N개 주어진다. (|Ai| ≤ 1,000,000,000, Ai는 정수)

www.acmicpc.net

투 포인터를 이용하여 배열 내의 어떤 수를 다른 두개의 합으로 나타낼 수 있는지 확인합니다.

투 포인터 사용을 위해 배열을 오름차순으로 정렬하고, 0번 인덱스부터 N - 1번 인덱스까지 전부 확인합니다.

초기 값은 left = 0, right = N - 1이며, 합이 list[i]와 같으면 바로 break, 합이 더 크면 right를 1 감소, 합이 더 작으면 left를 1 증가시킵니다.

 

이 문제에서 주의할 점은 "수의 위치가 다르면 값이 같아도 다른 수이다" 부분입니다.

자기 자신과 0을 더하는 경우가 나올 수 있는 left 또는 right가 i와 일치한 경우만 제외하였습니다.

 

 

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
#include <iostream>
#include <algorithm>
#define MAX 2000
using namespace std;
 
int list[MAX];
int N;
 
void func() {
    int ans = 0;
    for (int i = 0; i < N; i++) {
        int l = 0;
        int r = N - 1;
        while (l < r) {
            if (l == i) {
                l++;
                continue;
            }
            if (r == i) {
                r--;
                continue;
            }
 
            int sum = list[l] + list[r];
            if (sum == list[i]) {
                ans++;
                break;
            }
            else if (sum > list[i]) {
                r--;
            }
            else {
                l++;
            }
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> list[i];
    }
    sort(list, list + N);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > Two-Pointer' 카테고리의 다른 글

boj 9024 두 수의 합  (0) 2021.10.21
boj 17609 회문  (0) 2021.03.29
boj 2559 수열  (0) 2021.02.12
boj 1806 부분합  (0) 2021.01.22
boj 2003 수들의 합 2  (0) 2021.01.22

https://www.acmicpc.net/problem/9024

 

9024번: 두 수의 합

프로그램은 표준입력으로 입력을 받는다. 프로그램 입력은 t 개의 테스트 케이스로 구성된다. 입력의 첫 번째 줄에 테스트 케이스의 개수를 나타내는 정수 t 가 주어진다. 두 번째 줄부터 두 줄

www.acmicpc.net

배열에서 합이 K에 가장 가까운 서로 다른 두 개의 정수 조합의 갯수를 구하는 문제입니다.

이 문제는 투 포인터를 이용하여 해결할 수 있습니다.

 

투 포인터 사용을 위해 배열을 오름차순으로 정렬합니다.

그리고 left = 0, right = N - 1에서 시작합니다.

 

두 정수의 합(list[l] + list[r])이 K에 더 가까우면 합(ans)을 갱신, 갯수를 의미하는 cnt를 1로 초기화합니다.

만약 두 정수의 합과 갱신된 합이 같으면 cnt를 1 증가합니다.

그리고 두 정수의 합이 K보다 크면 값을 작게 해야하므로 right를 1 감소,

두 정수의 합이 K보다 작으면 값을 크게 해야하므로 left를 1 증가시킵니다.

 

최종으로 K에 가장 가까운 두 정수의 조합의 갯수인 cnt를 출력합니다.

 

 

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
#include <iostream>
#include <algorithm>
#define MAX 1000000
using namespace std;
 
int list[MAX];
int N, K;
 
void func() {
    int l = 0;
    int r = N - 1;
    int ans = 2e8;
    int cnt = 0;
    while (l < r) {
        int sum = list[l] + list[r];
        if (abs(sum - K) < abs(ans - K)) {
            ans = sum;
            cnt = 1;
        }
        else if (abs(sum - K) == abs(ans - K)) {
            cnt++;
        }
 
        if (sum > K) r--;
        else l++;
    }
 
    cout << cnt << '\n';
}
 
void input() {
    cin >> N >> K;
    for (int i = 0; i < N; i++) {
        cin >> list[i];
    }
    sort(list, list + N);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    int tc;
    cin >> tc;
    while (tc--) {
        input();
        func();
    }
 
    return 0;
}
cs

'algorithm > Two-Pointer' 카테고리의 다른 글

boj 1253 좋다  (0) 2021.10.21
boj 17609 회문  (0) 2021.03.29
boj 2559 수열  (0) 2021.02.12
boj 1806 부분합  (0) 2021.01.22
boj 2003 수들의 합 2  (0) 2021.01.22

https://www.acmicpc.net/problem/16120

 

16120번: PPAP

첫 번째 줄에 문자열이 주어진다. 문자열은 대문자 알파벳 P와 A로만 이루어져 있으며, 문자열의 길이는 1 이상 1,000,000 이하이다.

www.acmicpc.net

P는 PPAP 문자열이며, P를 PPAP로 바꾼 문자열 역시 PPAP 문자열입니다.

이 조건과 문자열 주어졌을 때 PPAP 문자열인지 판별하는 문제입니다.

 

우선 문자열의 처음부터 순회를 합니다.

해당 위치의 문자가

'P'이면 cnt를 1 증가합니다.

'A'이면 cnt가 2 이상이고, 다음 문자가 'P'이면 PPAP문자열이므로 PPAP를 P로 변경합니다.

실제 로직으로는 cnt를 1 감소하고, 다음 인덱스가 P인것을 확인했으니 인덱스도 1 증가합니다.

만약 'A'일때 cnt가 2보다 작거나, 마지막 인덱스이거나, 다음 문자가 'P'가 아니면 NP를 출력합니다.

 

순회가 끝났을때 남는 문자열은 P여야하므로 cnt가 1일때만 PPAP를 출력, 아니면 NP를 출력합니다.

 

 

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
#include <iostream>
#include <string>
using namespace std;
 
string str;
int N;
 
void func() {
    int cnt = 0;
    for (int i = 0; i < N; i++) {
        if (str[i] == 'P') cnt++;
        else {
            if (cnt >= 2 && i < N - 1 && str[i + 1== 'P') {
                cnt--;
                i++;
            }
            else {
                cout << "NP\n";
                return;
            }
        }
    }
 
    if (cnt == 1cout << "PPAP\n";
    else cout << "NP\n";
}
 
void input() {
    cin >> str;
    N = str.size();
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > Greedy' 카테고리의 다른 글

boj 1263 시간 관리  (0) 2024.07.03
boj 18185 라면 사기 (Small)  (0) 2024.07.02
boj 2262 토너먼트 만들기  (0) 2021.10.16
boj 13904 과제  (0) 2021.09.30
boj 1826 연료 채우기  (0) 2021.02.22

https://www.acmicpc.net/problem/2262

 

2262번: 토너먼트 만들기

월드시에서는 매년 n명의 사람들이 모여 월드 크래프트라는 게임의 토너먼트 대회를 치른다. 이 게임은 특성상 실력만이 승패를 좌우하기 때문에, 아무리 실력이 엇비슷한 사람이 시합을 치러

www.acmicpc.net

주어지는 랭킹은 중복이 없으며, 랭킹이 높은 사람 (숫자가 낮은 사람)이 무조건 이깁니다.

문제에서 요구하는 것은 이 토너먼트에서 각 경기에 임하는 선수들의 랭킹의 차이의 합이 최소가 되도록 대진을 구성해야합니다.

 

랭킹이 낮을수록 (숫자가 클수록) 랭킹의 차이의 합이 커지므로 랭킹이 낮은 선수는 빠르게 경기를 하는 것이 이득입니다.

따라서 랭킹이 낮은 선수부터 차례대로 본인의 좌우 선수들 중 랭킹이 낮은 선수와 경기를 하게 만들면 랭킹의 차이의 합이 최소가 됩니다.

 

 

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
#include <iostream>
#include <algorithm>
#define MAX 256
using namespace std;
 
int list[MAX];
int N;
 
void func() {
    int ans = 0;
    for (int i = N; i > 1; i--) {
        int j = 0;
        for (; j <= N; j++) {
            if (i == list[j]) break;
        }
 
        ans += (i - max(list[j - 1], list[j + 1]));
 
        for (; j < N; j++) {
            list[j] = list[j + 1];
        }
        N--;
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> list[i];
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > Greedy' 카테고리의 다른 글

boj 18185 라면 사기 (Small)  (0) 2024.07.02
boj 16120 PPAP  (0) 2021.10.16
boj 13904 과제  (0) 2021.09.30
boj 1826 연료 채우기  (0) 2021.02.22
boj 8980 택배  (0) 2021.02.16

https://www.acmicpc.net/problem/13904

 

13904번: 과제

예제에서 다섯 번째, 네 번째, 두 번째, 첫 번째, 일곱 번째 과제 순으로 수행하고, 세 번째, 여섯 번째 과제를 포기하면 185점을 얻을 수 있다.

www.acmicpc.net

그리디는 많이 안풀어봐서 어렵네요..

이 문제는 정렬 + 그리디 문제입니다.

 

우선 마감일, 과제 점수를 담은 list배열을

  1. 과제 점수가 높은 순 (내림차순)
  2. 마감일이 적게 남은 순 (오름차순)

으로 정렬합니다.

 

그 다음 과제 점수가 가장 높은 0번 인덱스부터 과제를 진행합니다.

여기서 확인해야할 것은 마감일 안에 과제를 할 수 있는지에 대한 여부입니다.

d일부터 1일까지 visit[d]=true인지 확인해서 해당 일에 과제를 했는지 체크합니다.

과제를 했다면 전날 과제를 했는지 체크하는 방식으로 1일까지 확인합니다.

 

과제를 하지않은 날이 있다면 과제를 진행하고 방문체크 해주면 되고,

d ~ 1일 모두 이미 과제를 한 상태면 해당 과제를 진행할 수 없다는 뜻입니다.

 

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
#include <iostream>
#include <algorithm>
#define MAX 1000
using namespace std;
typedef pair<intint> pi;
 
pi list[MAX];
bool visit[MAX + 1];
int N;
 
bool cmp(pi a, pi b) {
    if (a.second == b.second) return a.first < b.first;
    else return a.second > b.second;
}
 
void func() {
    int ans = 0;
    for (int i = 0; i < N; i++) {
        int d = list[i].first;
        for (int j = d; j > 0; j--) {
            if (visit[j]) continue;
            
            visit[j] = true;
            ans += list[i].second;
            break;
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> list[i].first >> list[i].second;
    }
    sort(list, list + N, cmp);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > Greedy' 카테고리의 다른 글

boj 16120 PPAP  (0) 2021.10.16
boj 2262 토너먼트 만들기  (0) 2021.10.16
boj 1826 연료 채우기  (0) 2021.02.22
boj 8980 택배  (0) 2021.02.16
boj 11000 강의실 배정  (0) 2021.02.16

https://www.acmicpc.net/problem/1849

 

1849번: 순열

1부터 N까지의 수들이 한 번씩 쓰인 수열이 있다. 그 수열에서 i 앞에 있는 수 들 중, i보다 큰 수들의 개수를 A[i]라고 정의하자. A[i]가 주어져 있을 때, 원래 수열을 구하는 프로그램을 작성하여라

www.acmicpc.net

사탕 상자 문제와 비슷한 방법인 구간합을 이용하여 해결하였습니다.

https://emoney96.tistory.com/93 (사탕 상자 문제풀이)

 

먼저 1 ~ N 만큼의 리프노드가 모두 1로 이루어진 세그먼트 트리를 구합니다.

입력으로는 1 ~ N 까지 자신보다 왼쪽에 있는 수 중에 자신보다 큰 수의 갯수가 주어집니다.

 

가장 작은 숫자인 1부터 입력으로 주어진 자신보다 큰 수의 갯수 + 1이 되는 자리를 찾습니다.

만약 cnt[1] = 5면 1의 자리는 6이 됩니다.

자리를 찾게 되면 해당 자리의 리프노드의 값을 0으로 하고 구간 값도 갱신합니다.

이 과정을 반복한 후에 결과를 출력해주시면 됩니다.

 

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
#include <iostream>
#define MAX 100000
using namespace std;
 
int list[MAX + 1], tree[(MAX + 1* 4];
int cnt[MAX + 1];
int N;
 
int init(int node, int s, int e) {
    if (s == e) {
        return tree[node] = 1;
    }
 
    int m = (s + e) / 2;
    return tree[node] = init(node * 2, s, m) + init(node * 2 + 1, m + 1, e);
}
 
void query(int node, int s, int e, int idx, int k) {
    if (s == e) {
        tree[node] = 0;
        list[s] = idx;
        return;
    }
 
    int m = (s + e) / 2;
    if (k <= tree[node * 2]) query(node * 2, s, m, idx, k);
    else query(node * 2 + 1, m + 1, e, idx, k - tree[node * 2]);
 
    tree[node] = tree[node * 2+ tree[node * 2 + 1];
}
 
void func() {
    for (int i = 1; i <= N; i++) {
        query(11, N, i, cnt[i] + 1);
    }
 
    for (int i = 1; i <= N; i++) {
        cout << list[i] << '\n';
    }
}
 
void input() {
    cin >> N;
    init(11, N);
    for (int i = 1; i <= N; i++) {
        cin >> cnt[i];
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > SegmentTree' 카테고리의 다른 글

boj 16993 연속합과 쿼리  (0) 2022.08.29
boj 12846 무서운 아르바이트  (0) 2022.08.19
boj 14719 빗물  (0) 2021.03.15
boj 2304 창고 다각형  (0) 2021.02.25
boj 14438 수열과 쿼리 17  (0) 2021.02.21

TypeScript를 설치했으니 이제 실행을 테스트 해야합니다.

 

TypeScript 실행에는 두 가지 방법이 있습니다.

  1. TypeScript를 JavaScript로 변환하여 실행하는 방법
  2. TypeScript를 바로 실행하는 방법

 

간단하게 작성된 코드를 실행합니다.

 

TypeScript를 JavaScript로 변환하여 실행하는 방법

아래의 명령어를 입력하여 JavaScript로 변환합니다.

tsc test.ts

그러면 같은 폴더에 test.js라는 JavaScript 파일이 생기고

 

열어보면 TypeScript에서 작성했던 코드가 변환되어 있음을 알 수 있습니다.

이제 아래의 명령어로 test.js를 실행합니다.

node test.js

이렇게 실행이 잘되는 것을 확인할 수 있습니다.

 

 

TypeScript를 바로 실행하는 방법

구글링을 하던 도중 ts-node를 통해 실행한다는 것을 알게되어 따라 해보았습니다.

 

ts-node는 아래의 명령어를 통해 설치합니다.

npm install -g ts-node

 

그 다음 아래의 명령어로 바로 실행을 합니다.

ts-node test.ts

네 그러면 에러가 발생합니다.

이를 해결하기 위해서는 tsconfig.json 이라는 TypeScript 설정 파일이 필요합니다.

직접 작성해도 되지만 아래의 명령어를 통해 자동 생성을 하였습니다.

그러면 Successfully 메시지와 함께 tsconfig.json 파일이 생깁니다.

 

이제 ts-node test.ts로 실행합니다.

이제 실행이 잘되는 것을 확인할 수 있습니다.

'Etc' 카테고리의 다른 글

Unity Script로 카메라 Culling Mask 기능 사용하기  (2) 2021.10.29
Unity 카메라 Culling Mask  (0) 2021.10.29
TypeScript 설치  (0) 2021.08.30
Windows 10 에서 WSL을 이용한 우분투 설치  (0) 2021.08.29
C++ cout 소수점 고정  (0) 2021.08.05

TypeScript를 설치하기 위해서는 nodejs가 먼저 설치되어 있어야합니다.

 

https://nodejs.org/ko/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

여기서 nodejs를 설치합니다.

 

cmd에 node -v나 node --version을 쳐서 버전이 나오면 설치가 된겁니다.

 

그 다음 밑의 명령어를 통해 TypeScript를 설치합니다.

npm install -g typescript

설치 이후에 tsc -v나 tsc --version을 쳐서 버전이 나오면 설치가 된겁니다.

 

 

혹시 vscode에서 tsc -v 입력 시 이런 에러가 발생한다면 Windows 정책으로 PowerShell 실행에 제한이 있기 때문입니다.

 

그런 경우에는 Windows PowerShell을 켜서 Set-ExecutionPolicy Unrestricted를 입력 후 y를 입력합니다.

 

그러면 버전이 잘 뜨는것을 확인할 수 있습니다.

'Etc' 카테고리의 다른 글

Unity 카메라 Culling Mask  (0) 2021.10.29
TypeScript 실행  (0) 2021.08.30
Windows 10 에서 WSL을 이용한 우분투 설치  (0) 2021.08.29
C++ cout 소수점 고정  (0) 2021.08.05
Java 문자열이 정수인지 확인  (0) 2021.06.01

Windows 10에 WSL이라는 Linux용 Windows 하위 시스템 기능을 이용하여 우분투를 설치하는 과정입니다.

 

먼저 Windows 기능 켜기/끄기 라는 프로그램을 실행시킵니다.

 

Linux용 Windows 하위 시스템을 체크하고 확인을 누릅니다.

 

그러면 PC를 재부팅 해라고 합니다.

재부팅을 해줍니다.

 

그 다음 Microsoft Store 앱을 켜줍니다.

 

WSL을 검색하여 Ubuntu를 설치하고 실행합니다.

 

첫 화면으로는 몇 분 동안 설치를 진행합니다.

 

그 다음 새 계정정보를 입력하면 설치가 완료됩니다!

 

 

싸피에서 우분투를 쓸 기회가 있었지만 이 부분은 다른 팀원분이 맡아주셨기에 처음이네요.

익숙해질 정도로 써봐야할 것 같습니다.

'Etc' 카테고리의 다른 글

TypeScript 실행  (0) 2021.08.30
TypeScript 설치  (0) 2021.08.30
C++ cout 소수점 고정  (0) 2021.08.05
Java 문자열이 정수인지 확인  (0) 2021.06.01
localStorage를 이용한 데이터 저장  (0) 2021.05.11

보통 Controller에서 Dto를 받을 때는 @RequestBody를 주로 사용합니다.

그리고 File을 받을 때는 MultipartFile 객체를 사용하며, @RequestParam을 사용합니다.

 

하지만 File과 Dto를 같이 받기 위해서는 @RequestPart라는 어노테이션이 필요합니다.

File은 @RequestParam, Dto는 @RequestBody를 사용해서 받을려고 했지만 몇번을 시도해도 안되더라고요..

그래서 구글링을 통해 RequestPart라는 어노테이션을 찾아냈습니다.

 

우선 Controller입니다.

File과 Dto 모두 @RequestPart 어노테이션으로 받도록 합니다.

 

그리고 Dto인 UserInsertPostReq는 이렇게 구성되어 있습니다.

이전글 에서 사용했던 Dto와 동일합니다.

 

그리고 Controller에서 호출할 Service의 insertUser 메소드입니다.

파일을 저장할 경로를 지정한 후에 지정한 경로에 파일을 저장하고 DB에 유저 정보를 추가하는 로직입니다.

 

저는 이를 수행하기 위해 포스트맨을 사용하였습니다.

Key name은 @RequestPart 에서 value로 지정해준 name과 동일한 Key name으로 넣어줍니다.

이제 저기있는 Send를 눌러볼까요?

 

네 역시나 400에러가 발생합니다.

 

구글링을 통해 value에 json형식으로 넣는 방법을 알게되었고, 그대로 따라해보았습니다.

이런식으로 Key name은 userInsertPostReq, value는 json 방식으로 작성하였습니다.

다시 Send를 눌러보겠습니다.

 

이번에는 415 에러가 발생합니다..

 

한 두 시간 동안은 400, 415에러만 봤던것 같습니다.

 

이 에러들을 해결하기 위해 구글링을 해본 결과로는

여기서 Dto인 userInsertPostReq는 content type을 application/json으로 지정하면 해결할 수 있습니다.

userInsertPostReq의 content type을 application/json으로 지정한 후 Send를 누릅니다.

 

그럼 입력한 정보가 잘 들어가는 것을 확인할 수 있습니다.

 

File과 Dto를 같이 받아올 때 Key name과 content type 설정을 잘못하여 나온 에러 상황이었습니다.

이 방법 외에 다른 방법이 있는지는 잘 모르겠습니다. 더 많은 공부가 필요할 것 같습니다.

 

지금까지 단일 File과 Dto를 요청하는 것에 대해 알아보았고, 다수의 File과 Dto 요청에 관해서는 아래 링크에서 확인하시면 됩니다.

https://emoney96.tistory.com/375

 

Postman을 이용한 다수의 File, Dto 동시 Post 요청

https://emoney96.tistory.com/258 Postman을 이용한 MultipartFile, Dto 동시 Post요청 보통 Controller에서 Dto를 받을 때는 @RequestBody를 주로 사용합니다. 그리고 File을 받을 때는 MultipartFile 객체를 사..

emoney96.tistory.com

 

프로젝트 진행 중 JpaRepository에서 Pagenation을 적용한 Page객체를 받은 이후 Collections.sort로 정렬을 하였습니다.

하지만 이와 관련된 문제점 하나를 발견하게 되었고 포스팅으로 남길려고 합니다.

 

우선 db에 유저의 정보를 저장해줍니다.

profile_url은 file저장을 공부하면서 사용해본 것이며 이 글과는 상관 없는 file입니다.

내일쯤 file 저장관련 글을 포스팅할 예정입니다.

 

각 유저들의 점수(score)를 같이 저장해줍니다.

이 유저들을 score기준 내림차순으로 조회를 하는데 Pagenation을 적용시키려고 합니다.

 

 

UserRepository에서는 Page 객체로 리턴하는 findAll 메소드를 작성합니다.

 

UserServiceImpl에서 UserRepository의 findAll 메소드를 호출하는 findAllUser 메소드를 작성합니다.

userRepository.findAll로 Page객체를 가져오고, UserGetRes의 of 메소드에서 정렬을 진행합니다.

 

Pagenation을 적용했기 때문에 변수를 많이 사용하였지만 of 메소드의 정렬하는 부분이 핵심입니다.

Page객체를 가져와서 score기준 내림차순으로 정렬을 진행합니다.

 

그리고 Controller에서는 page와 size를 RequestParam으로 받아서 UserService의 findAllUser 메소드를 호출합니다.

 

이제 스웨거를 통해 테스트를 합니다.

확인할 페이지는 0페이지, 즉 첫번째 페이지를 조회하며 최대 3개의 데이터를 조회하려고 합니다.

 

결과는...

네.. 이렇게 나왔습니다.

 

원래 의도한 대로라면 score가 120인 id10부터 score가 100인 id2까지 나오는게 맞습니다.

여기서 확인해봐도 id는 10 -> 5 -> 2 순서대로 조회가 되어야합니다.

 

이 과정에서 제가 치명적인 실수를 한 것이 있습니다.

바로 Repository에서 Page객체를 가져온 이후에 정렬을 진행했다는 것입니다.

 

Page객체에 있는 데이터는 조회 가능한 모든 리스트가 있는것이 아니라 size만큼의 데이터만 있는 것이었습니다.

따라서 제가 Service에서 Repository를 호출할 때 Sort 기준을 아무것도 주지 않았기 때문에 먼저 추가된 데이터부터 size만큼 데이터가 조회된 것이었습니다.

 

그럼 이제 알맞게 수정을 해야겠죠?

우선 UserRepository의 findAll 메소드에 OrderByScore를 추가하거나 Pageable에 Sort를 추가합니다.

그 후에 UserGetRes의 정렬하는 부분을 지웁니다.

 

일단 UserGetRes의 of 메소드의 정렬부분을 지웁니다.

 

 

먼저 UserRepository의 findAll 메소드 수정하는 방법입니다.

findAllUsers로는 자동완성이 안뜨길래 findUsersByOrderByScoreDesc로 수정합니다.

뒤에 Desc를 안붙이면 default로 Asc가 적용됩니다.

 

 

다음은 UserService의 PageRequest에 Sort를 추가하는 방법입니다.

UserRepository에 있는 findAll 메소드는 그대로 두고 Sort를 추가합니다.

score 기준 DESC를 추가합니다.

 

 

둘 중 아무방법이나 사용한 다음 스웨거를 통해 테스트를 합니다.

그러면 이렇게 올바르게 조회를 할 수가 있습니다.

 

저는 두 번째 방법을 선호하기는 합니다만 두 방법 중 어떤 방법이 더 좋을지는 잘 모르겠습니다.

앞으로 로직을 구현할 때 생각이라는 것을 많이 해야겠다는 생각이 듭니다.

 

정렬을 적용하는 시점이 잘못되어 생긴 문제였습니다.

+ Recent posts