Skip to content

๐Ÿš์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์ถ”์ฒœ ์›น ์„œ๋น„์Šค

Notifications You must be signed in to change notification settings

2024-pre-onboarding-backend-F/yellow-ribbon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Yellow-Ribbon

โœจ Backend TechStack โœจ

Java Spring Boot Spring Data JPA Spring Security Spring Batch Querydsl
MySQL Redis Amazon RDS Amazon EC2 Docker Github Actions

๐Ÿ€ ์„œ๋น„์Šค ๊ฐœ์š” ๐Ÿ€

๊ณต๊ณต๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ์œ„์น˜ ๊ธฐ๋ฐ˜ ์ง€์—ญ ์Œ์‹์  ์กฐํšŒ ๋ฐ ์ถ”์ฒœ ์„œ๋น„์Šค ์˜๋กœ๋ฆฌ๋ณธ(Yellow Ribbon)
์˜๋กœ๋ฆฌ๋ณธ์—์„œ ์Œ์‹์  ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๊ณ , ๋ฆฌ๋ทฐ๋ฅผ ๋‚จ๊ฒจ๋ณด์„ธ์š”!
์œ ์ €๋“ค์—๊ฒŒ ์ธ๊ธฐ ๋งŽ์€ ์Œ์‹์ ์ด ๊ถ๊ธˆํ•˜์‹œ๋‚˜์š”? ์ธ๊ธฐ ๋ง›์ง‘ ๋ฐ ์ธ๊ธฐ ๊ธ‰์ƒ์Šน ๋ง›์ง‘๋„ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์กฐํšŒ ๋ฐ ์ถ”์ฒœ ์„œ๋น„์Šค๊นŒ์ง€!

โฐ ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„ โฐ

2024.10.18 ~ ์„œ๋น„์Šค ์šด์˜์ค‘
(V2) 2024.10.01 - 2024.10.18
(V1) 2024.08.31 - 2024.09.03


๐Ÿ™‹โ€โ™€๏ธ ํŒ€์›

์ด๋ฆ„ Github ๋‹ด๋‹น
๊น€์˜์ฃผ K-0joo ํšŒ์› API ์ „๋ฐ˜
์ •์€๊ฒฝ jeongeungyeong ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ์ „๋ฐ˜
์ด์ง€์› jw427 ์‹œ๊ตฐ๊ตฌ ๋ชฉ๋ก, ๋ง›์ง‘ ์ƒ์„ธ ์ •๋ณด, ๋ง›์ง‘ ํ‰๊ฐ€ ์ƒ์„ฑ, ์ธ๊ธฐ ๋ง›์ง‘ ์กฐํšŒ API
์ •์ง„ํฌ rhaehf ์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์กฐํšŒ, ์ถ”์ฒœ API

[๋ชฉ์ฐจ]

  1. ๐Ÿ“ ERD ๋ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ
  2. ๐Ÿ–ฅ๏ธ ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜ ๋ฐ ๋ฐฐํฌ
  3. ๐Ÿ“‘ ๊ตฌํ˜„ ๋‚ด์šฉ
  4. ๐Ÿ’Œ API ๋ช…์„ธ
  5. ๐Ÿค” ๊ณ ๋ฏผ ํ”์ 
  6. ๐Ÿ™€ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

๐Ÿ“ ERD ๋ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ

ERD
๋ง›์ง‘ erd
๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ
src
โ”œโ”€โ”€โ”€main
โ”‚   โ”œโ”€โ”€โ”€generated
โ”‚   โ”‚   โ””โ”€โ”€โ”€wanted
โ”‚   โ”‚       โ””โ”€โ”€โ”€ribbon
โ”‚   โ”‚           โ”œโ”€โ”€โ”€datapipe
โ”‚   โ”‚           โ”‚   โ””โ”€โ”€โ”€domain
โ”‚   โ”‚           โ”‚           QGenrestrt.java
โ”‚   โ”‚           โ”‚           
โ”‚   โ”‚           โ”œโ”€โ”€โ”€store
โ”‚   โ”‚           โ”‚   โ””โ”€โ”€โ”€domain
โ”‚   โ”‚           โ”‚           QCity.java
โ”‚   โ”‚           โ”‚           QReview.java
โ”‚   โ”‚           โ”‚           QStore.java
โ”‚   โ”‚           โ”‚           
โ”‚   โ”‚           โ””โ”€โ”€โ”€user
โ”‚   โ”‚               โ””โ”€โ”€โ”€domain
โ”‚   โ”‚                       QRefreshToken.java
โ”‚   โ”‚                       QUser.java
โ”‚   โ”‚                       
โ”‚   โ”œโ”€โ”€โ”€java
โ”‚   โ”‚   โ””โ”€โ”€โ”€wanted
โ”‚   โ”‚       โ””โ”€โ”€โ”€ribbon
โ”‚   โ”‚           โ”‚   RibbonApplication.java
โ”‚   โ”‚           โ”‚   
โ”‚   โ”‚           โ”œโ”€โ”€โ”€datapipe
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€component
โ”‚   โ”‚           โ”‚   โ”‚       DataFetchTasklet.java
โ”‚   โ”‚           โ”‚   โ”‚       DataPipeJobScheduler.java
โ”‚   โ”‚           โ”‚   โ”‚       DataPipeTasklet.java
โ”‚   โ”‚           โ”‚   โ”‚       JobCompletionNotificationListener.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€config
โ”‚   โ”‚           โ”‚   โ”‚       AppConfig.java
โ”‚   โ”‚           โ”‚   โ”‚       BatchConfig.java
โ”‚   โ”‚           โ”‚   โ”‚       DataPipeJobConfig.java
โ”‚   โ”‚           โ”‚   โ”‚       OpenApiJobConfig.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€controller
โ”‚   โ”‚           โ”‚   โ”‚       OpenApiController.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€domain
โ”‚   โ”‚           โ”‚   โ”‚       Genrestrt.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€dto
โ”‚   โ”‚           โ”‚   โ”‚       GenrestrtApiResponse.java
โ”‚   โ”‚           โ”‚   โ”‚       GyeongGiList.java
โ”‚   โ”‚           โ”‚   โ”‚       RawData.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€mapper
โ”‚   โ”‚           โ”‚   โ”‚       RawDataRowMapper.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreDataRowMapper.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€repository
โ”‚   โ”‚           โ”‚   โ”‚       GenrestrtRepository.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ””โ”€โ”€โ”€service
โ”‚   โ”‚           โ”‚           DataProcessor.java
โ”‚   โ”‚           โ”‚           GenrestrtService.java
โ”‚   โ”‚           โ”‚           RawDataSaveService.java
โ”‚   โ”‚           โ”‚           RawDataService.java
โ”‚   โ”‚           โ”‚           
โ”‚   โ”‚           โ”œโ”€โ”€โ”€exception
โ”‚   โ”‚           โ”‚   โ”‚   BadRequestException.java
โ”‚   โ”‚           โ”‚   โ”‚   BaseException.java
โ”‚   โ”‚           โ”‚   โ”‚   ConflictException.java
โ”‚   โ”‚           โ”‚   โ”‚   ErrorCode.java
โ”‚   โ”‚           โ”‚   โ”‚   ErrorResponse.java
โ”‚   โ”‚           โ”‚   โ”‚   ForbiddenException.java
โ”‚   โ”‚           โ”‚   โ”‚   GenrestrtException.java
โ”‚   โ”‚           โ”‚   โ”‚   InternalServerException.java
โ”‚   โ”‚           โ”‚   โ”‚   NotFoundException.java
โ”‚   โ”‚           โ”‚   โ”‚   
โ”‚   โ”‚           โ”‚   โ””โ”€โ”€โ”€handler
โ”‚   โ”‚           โ”‚           GlobalExceptionHandler.java
โ”‚   โ”‚           โ”‚           
โ”‚   โ”‚           โ”œโ”€โ”€โ”€global
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€config
โ”‚   โ”‚           โ”‚   โ”‚       QueryDslConfig.java
โ”‚   โ”‚           โ”‚   โ”‚       RedisConfig.java
โ”‚   โ”‚           โ”‚   โ”‚       SwaggerConfig.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ””โ”€โ”€โ”€response
โ”‚   โ”‚           โ”‚           ResponseCode.java
โ”‚   โ”‚           โ”‚           ResponseDto.java
โ”‚   โ”‚           โ”‚           
โ”‚   โ”‚           โ”œโ”€โ”€โ”€store
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€controller
โ”‚   โ”‚           โ”‚   โ”‚       CityController.java
โ”‚   โ”‚           โ”‚   โ”‚       ReviewController.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreController.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€domain
โ”‚   โ”‚           โ”‚   โ”‚       Category.java
โ”‚   โ”‚           โ”‚   โ”‚       City.java
โ”‚   โ”‚           โ”‚   โ”‚       Review.java
โ”‚   โ”‚           โ”‚   โ”‚       Store.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€dto
โ”‚   โ”‚           โ”‚   โ”‚       CityResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       CreateReviewRequestDto.java
โ”‚   โ”‚           โ”‚   โ”‚       CreateReviewResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       PopularStoreListResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       ReviewListResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       RisingPopularStoreListResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       RisingStoreResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreDetailResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreListResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreResponseDto.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ”œโ”€โ”€โ”€repository
โ”‚   โ”‚           โ”‚   โ”‚       CityRepository.java
โ”‚   โ”‚           โ”‚   โ”‚       ReviewRepository.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreRepository.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreRepositoryCustom.java
โ”‚   โ”‚           โ”‚   โ”‚       StoreRepositoryImpl.java
โ”‚   โ”‚           โ”‚   โ”‚       
โ”‚   โ”‚           โ”‚   โ””โ”€โ”€โ”€service
โ”‚   โ”‚           โ”‚           CityService.java
โ”‚   โ”‚           โ”‚           ReviewService.java
โ”‚   โ”‚           โ”‚           StoreService.java
โ”‚   โ”‚           โ”‚           
โ”‚   โ”‚           โ””โ”€โ”€โ”€user
โ”‚   โ”‚               โ”œโ”€โ”€โ”€config
โ”‚   โ”‚               โ”‚   โ”‚   TokenAuthenticationFilter.java
โ”‚   โ”‚               โ”‚   โ”‚   TokenProvider.java
โ”‚   โ”‚               โ”‚   โ”‚   WebSecurityConfig.java
โ”‚   โ”‚               โ”‚   โ”‚   
โ”‚   โ”‚               โ”‚   โ””โ”€โ”€โ”€jwt
โ”‚   โ”‚               โ”‚           JwtProperties.java
โ”‚   โ”‚               โ”‚           
โ”‚   โ”‚               โ”œโ”€โ”€โ”€controller
โ”‚   โ”‚               โ”‚       TokenApiController.java
โ”‚   โ”‚               โ”‚       UserApiController.java
โ”‚   โ”‚               โ”‚       UserOauthController.java
โ”‚   โ”‚               โ”‚       
โ”‚   โ”‚               โ”œโ”€โ”€โ”€domain
โ”‚   โ”‚               โ”‚       RefreshToken.java
โ”‚   โ”‚               โ”‚       SocialType.java
โ”‚   โ”‚               โ”‚       User.java
โ”‚   โ”‚               โ”‚       
โ”‚   โ”‚               โ”œโ”€โ”€โ”€dto
โ”‚   โ”‚               โ”‚       CreateAccessTokenResponse.java
โ”‚   โ”‚               โ”‚       CreateRefreshTokenRequest.java
โ”‚   โ”‚               โ”‚       LoginRequest.java
โ”‚   โ”‚               โ”‚       LoginResponse.java
โ”‚   โ”‚               โ”‚       ProfileRequest.java
โ”‚   โ”‚               โ”‚       ProfileResponse.java
โ”‚   โ”‚               โ”‚       SignUpRequest.java
โ”‚   โ”‚               โ”‚       SignUpResponse.java
โ”‚   โ”‚               โ”‚       UpdateProfileRequest.java
โ”‚   โ”‚               โ”‚       UpdateProfileResponse.java
โ”‚   โ”‚               โ”‚       
โ”‚   โ”‚               โ”œโ”€โ”€โ”€repository
โ”‚   โ”‚               โ”‚       RefreshTokenRepository.java
โ”‚   โ”‚               โ”‚       UserRepository.java
โ”‚   โ”‚               โ”‚       
โ”‚   โ”‚               โ””โ”€โ”€โ”€service
โ”‚   โ”‚                       CustomUserDetail.java
โ”‚   โ”‚                       KakaoOAuth2UserService.java
โ”‚   โ”‚                       RefreshTokenService.java
โ”‚   โ”‚                       TokenService.java
โ”‚   โ”‚                       UserDetailService.java
โ”‚   โ”‚                       UserOauthService.java
โ”‚   โ”‚                       UserService.java
โ”‚   โ”‚                       
โ”‚   โ””โ”€โ”€โ”€resources
โ”‚       โ”‚   application-secret.yml
โ”‚       โ”‚   application.yml
โ”‚       โ”‚   
โ”‚       โ”œโ”€โ”€โ”€static
โ”‚       โ””โ”€โ”€โ”€templates
โ””โ”€โ”€โ”€test
    โ””โ”€โ”€โ”€java
        โ””โ”€โ”€โ”€wanted
            โ””โ”€โ”€โ”€ribbon
                โ”‚   RibbonApplicationTests.java
                โ”‚   
                โ””โ”€โ”€โ”€user
                    โ””โ”€โ”€โ”€config
                        โ””โ”€โ”€โ”€jwt
                                JwtFactory.java

๐Ÿ–ฅ๏ธ ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜ ๋ฐ ๋ฐฐํฌ

์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜

์„œ๋น„์Šค ์•„ํ‚คํ…์ณ

๋ฐฐํฌ ์ด๋ฏธ์ง€

๋ฐฐํฌgif Swagger API ์บก์ณ ์ „์ฒด

๐Ÿ“‘ ๊ตฌํ˜„ ๋‚ด์šฉ

๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž…

  • ์ผ๋ฐ˜ ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ
  • ์นด์นด์˜ค ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ
  • Access ๋ฐ Refresh Token ์ƒ์„ฑ
  • ๊ฒฝ๋„ ๋ฐ ์œ„๋„, ์ ์‹ฌ ์ถ”์ฒœ ํ”„๋กœํ•„(์ •๋ณด ์—…๋ฐ์ดํŠธ/์กฐํšŒ) ๊ธฐ๋Šฅ

๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ

  • ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ์€ ์ž๋™ํ™” ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ์ฒ˜๋ฆฌ
  • ๊ฒฝ๊ธฐ๋„ ๊ณต๊ณต๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ๋ฐ ์›๋ณธ ๋ฐ์ดํ„ฐ ์ €์žฅ
  • ์›๋ณธ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ
  • ์šด์˜ํ…Œ์ด๋ธ”๋กœ ๊ฐ€๊ณต ๋ฐ์ดํ„ฐ ์ €์žฅ
    • ์‹ ๊ทœ ๋ฐ์ดํ„ฐ๋Š” JDBC BATCH ๋„์ž…
    • ๊ธฐ์กด ๋ฐ์ดํ„ฐ๋Š” JPA UPDATE ๋„์ž…
  • ์ •๋ณด์˜ ์ตœ์‹ ํ™”๋ฅผ ์œ„ํ•ด ์Šค์ผ€์ค„๋Ÿฌ ๋„์ž…
    • ๊ณต๊ณต๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ JOB: ๋งค์ฃผ ์›”์š”์ผ ์ƒˆ๋ฒฝ 3์‹œ
    • ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ๋ฐ ์šด์˜ JOB: ๋งค์ฃผ ์›”์š”์ผ ์ƒˆ๋ฒฝ 5์‹œ

์‹œ๊ตฐ๊ตฌ ๋ชฉ๋ก ์กฐํšŒ

  • ์‹œ๊ตฐ๊ตฌ ๋ชจ๋“  ๋ชฉ๋ก ์กฐํšŒ

๋ง›์ง‘ ์กฐํšŒ

  • ํšŒ์›์€ ๋ง›์ง‘ ๋ชฉ๋ก ์กฐํšŒ ๊ฐ€๋Šฅ
  • ๋ง›์ง‘ ์ƒ์„ธ ์ •๋ณด ์กฐํšŒ ์‹œ ๋ง›์ง‘์˜ ๋ชจ๋“  ํ•„๋“œ์™€ ํ•ด๋‹น ๋ง›์ง‘์˜ ํ‰๊ฐ€ ๋ชฉ๋ก ์กฐํšŒ
  • ํ‰๊ฐ€ ๋ชฉ๋ก ์กฐํšŒ ์‹œ ์ž‘์„ฑํ•œ ํšŒ์›์˜ ๊ณ„์ •๋ช…, ํ‰๊ฐ€ ์ ์ˆ˜, ํ‰๊ฐ€ ๋‚ด์šฉ ์ถœ๋ ฅ

๋ง›์ง‘ ํ‰๊ฐ€ ์ƒ์„ฑ

  • ๋กœ๊ทธ์ธํ•œ ํšŒ์›๋งŒ ํ‰๊ฐ€ ์ƒ์„ฑ ๊ฐ€๋Šฅ
  • ํ‰๊ฐ€ ์ ์ˆ˜์™€ ๋‚ด์šฉ ์ž…๋ ฅ
  • ํ‰๊ฐ€ ์ƒ์„ฑ์‹œ ํ•ด๋‹น ๋ง›์ง‘์˜ ํ‰์  ๋ฐ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ ์—…๋ฐ์ดํŠธ

์ธ๊ธฐ ๋ง›์ง‘ ๋ฐ ์ธ๊ธฐ ๊ธ‰์ƒ์Šน ๋ง›์ง‘ ์กฐํšŒ

  • ํšŒ์›์€ ์ธ๊ธฐ ๋ง›์ง‘ ๋ฐ ์ธ๊ธฐ ๊ธ‰์ƒ์Šน ๋ง›์ง‘ ๋ชฉ๋ก ์กฐํšŒ ๊ฐ€๋Šฅ
  • ์ธ๊ธฐ ๋ง›์ง‘์˜ ๊ธฐ์ค€์€ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜์™€ ํ‰์ 
  • ์ „์ฒด ์ธ๊ธฐ ๋ง›์ง‘ ์™ธ์— ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„, ์ง€์—ญ๋ณ„ ์ธ๊ธฐ ๋ง›์ง‘ ์กฐํšŒ ๊ฐ€๋Šฅ
  • ์ธ๊ธฐ ๊ธ‰์ƒ์Šน ๋ง›์ง‘ ๊ธฐ์ค€์€ ์ „๋‚  ์ƒ์„ฑ๋œ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜
  • ์ธ๊ธฐ ๋ง›์ง‘๊ณผ ์ธ๊ธฐ ๊ธ‰์ƒ์Šน ๋ง›์ง‘์€ ์ž์ฃผ ์กฐํšŒ๋˜๊ณ  ๊ฐ’์ด ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์กฐํšŒ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด redis cache๋ฅผ ์ ์šฉ
  • ์ •๋ณด์˜ ์ตœ์‹ ํ™”๋ฅผ ์œ„ํ•ด ์บ์‹œ ๋งŒ๋ฃŒ๊ธฐ๊ฐ„์„ ๋‹ค์Œ๋‚  ์ž์ •๊นŒ์ง€๋กœ ์„ค์ •

์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์กฐํšŒ

  • ๊ฒฝ๋„(lon)์™€ ์œ„๋„(lat)๋กœ ์„ค์ •๋œ ์‚ฌ์šฉ์ž์˜ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ, ์ฃผ์–ด์ง„ ๋ฒ”์œ„(range) ๋‚ด์—์„œ ๊ฒ€์ƒ‰ํ•˜๊ณ , ์ •๋ ฌํ•˜์—ฌ ๋ง›์ง‘์˜ ๊ฐœ์ˆ˜์™€ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์‘๋‹ต
  • ์ •๋ ฌ ๊ธฐ์ค€
    • ๊ฑฐ๋ฆฌ์ˆœ: ์‚ฌ์šฉ์ž ์œ„์น˜์™€ ๋ง›์ง‘ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ์งง์€ ์ˆœ์„œ๋กœ ์ •๋ ฌ (๊ธฐ๋ณธ ์ •๋ ฌ ๊ฐ’)
    • ํ‰์ ์ˆœ: ๋ง›์ง‘์˜ ํ‰์ ์ด ๋†’์€ ์ˆœ์„œ๋กœ ์ •๋ ฌ
  • ์ฃผ์–ด์ง„ ๋ฒ”์œ„ ๋‚ด์—์„œ ๋ง›์ง‘์„ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ ํƒ€์ž… Point์™€ ๊ณต๊ฐ„ ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉ

์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์ถ”์ฒœ

  • ์‚ฌ์šฉ์ž ์œ„์น˜์—์„œ 1km ๋ฐ˜๊ฒฝ ๋‚ด์˜ ๋ง›์ง‘์„ ๊ฒ€์ƒ‰ํ•˜๊ณ , ํ‰์ ๊ณผ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๋กœ ๊ณ„์‚ฐํ•œ ์‹์˜ ๊ธฐ์ค€์„ ๋„˜์œผ๋ฉด ์ถ”์ฒœ
  • ํ‰์ ๊ณผ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๋ฅผ ํ™œ์šฉํ•œ ๊ณ„์‚ฐ์‹์„ ์ ์šฉํ•ด ์ถ”์ฒœ ๋ง›์ง‘์„ ํ•„ํ„ฐ๋ง
    • ๊ณ„์‚ฐ์‹: ํ‰์  * 0.7 + (๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ / 3000) * 0.3
    • ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๊ฐ€ 3,000๊ฐœ๋ฅผ ์ดˆ๊ณผํ•  ๊ฒฝ์šฐ, (๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ / 3000)๋Š” 1๋กœ ์ฒ˜๋ฆฌ
    • ๊ณ„์‚ฐ์‹ ๊ฒฐ๊ณผ๊ฐ€ 3.0 ์ด์ƒ์ธ ๊ฒฝ์šฐ์—๋งŒ ์ถ”์ฒœ

๐Ÿ’Œ API ๋ช…์„ธ

๋Œ€๋ถ„๋ฅ˜ ๊ธฐ๋Šฅ Method URL ๋‹ด๋‹น์ž
์œ ์ €
์‚ฌ์šฉ์ž ํ”„๋กœํ•„
์—…๋ฐ์ดํŠธ
PUT /api/users/settings/{userId} ๊น€์˜์ฃผ
์œ ์ € ํ† ํฐ ์ƒ์„ฑ POST /api/users/token ๊น€์˜์ฃผ
์œ ์ € ์‚ฌ์šฉ์ž ํšŒ์›๊ฐ€์ž… POST /api/users/signup ๊น€์˜์ฃผ
์œ ์ € ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ POST /api/users/login ๊น€์˜์ฃผ
์œ ์ € ์‚ฌ์šฉ์ž ํ”„๋กœํ•„
ํ™•์ธ
GET /api/users/profile/{userId} ๊น€์˜์ฃผ
์œ ์ € ์‚ฌ์šฉ์ž ์นด์นด์˜คํ†ก
ํšŒ์›๊ฐ€์ž…
GET /api/oauth/kakao/login ๊น€์˜์ฃผ
๋ง›์ง‘
์กฐํšŒ
์‹œ๊ตฐ๊ตฌ ๋ชฉ๋ก ์กฐํšŒ GET /api/city ์ด์ง€์›
๋ง›์ง‘
์กฐํšŒ
๋ง›์ง‘ ์ƒ์„ธ ์ •๋ณด
์กฐํšŒ
GET /api/stores/:storeId ์ด์ง€์›
ํ‰๊ฐ€ ๋ง›์ง‘ ํ‰๊ฐ€ ์ƒ์„ฑ POST /api/reviews/:storeId ์ด์ง€์›
๋ง›์ง‘
์กฐํšŒ
์ธ๊ธฐ ๋ง›์ง‘ ์กฐํšŒ GET /api/stores/popular ์ด์ง€์›
๋ง›์ง‘
์กฐํšŒ
์ธ๊ธฐ ๊ธ‰์ƒ์Šน
๋ง›์ง‘ ์กฐํšŒ
GET /api/stores/rising ์ด์ง€์›
๋ง›์ง‘
์กฐํšŒ
์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜
๋ง›์ง‘ ์กฐํšŒ
GET ๊ฑฐ๋ฆฌ์ˆœ : /api/stores?lon=127.1108000763&lat=37.3503950812&range=1
ํ‰์ ์ˆœ : /api/stores?lon=127.1108000763&lat=37.3503950812&range=1&orderBy=rating
์ •์ง„ํฌ
๋ง›์ง‘
์กฐํšŒ
์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜
๋ง›์ง‘ ์ถ”์ฒœ
GET /api/stores/recommend?lon=127.1108000763&lat=37.3503950812 ์ •์ง„ํฌ

๐Ÿค” ๊ณ ๋ฏผ ํ”์ 

๊น€์˜์ฃผ

๐Ÿ’ญ ์นด์นด์˜คํ†ก Token์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ vs ์ง์ ‘ Token์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ ์ค‘ ์–ด๋–ค๊ฒŒ ์ข‹์„๊นŒ?

๐Ÿ—จ ์นด์นด์˜คํ†ก API๋งŒ ์‚ฌ์šฉ

  • ์žฅ์ 
    • ์นด์นด์˜ค ์ธก์—์„œ ๋ฐœํ–‰ํ•œ ํ† ํฐ์€ ์ด๋ฏธ ์ธ์ฆ๊ณผ ๊ถŒํ•œ ๋ถ€์—ฌ๊ฐ€ ์™„๋ฃŒ๋œ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋ณ„๋„์˜ ์ธ์ฆ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • OAuth 2.0๊ณผ ๊ฐ™์€ ์™ธ๋ถ€ ์„œ๋น„์Šค ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณด์•ˆ์„ฑ์ด ๋” ๋†’๊ณ , ์ธ์ฆ ์„œ๋ฒ„๋ฅผ ์šด์˜ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋˜ํ•œ, ์นด์นด์˜ค์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ณด์•ˆ ์ •์ฑ…(ํ† ํฐ ๊ฐฑ์‹ , ๋งŒ๋ฃŒ ๋“ฑ)์ด ๊ทธ๋Œ€๋กœ ์ ์šฉ๋œ๋‹ค.
  • ๋‹จ์ 
    • ์นด์นด์˜ค์˜ ํ† ํฐ ๊ด€๋ฆฌ ์ •์ฑ…์— ์˜์กดํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ํ† ํฐ ๊ฐฑ์‹  ์ฃผ๊ธฐ๋‚˜ ๋งŒ๋ฃŒ ์ •์ฑ… ๋“ฑ์—์„œ ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.
    • ์นด์นด์˜ค ์™ธ์˜ ๋‹ค๋ฅธ ๋กœ๊ทธ์ธ ์ˆ˜๋‹จ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ(์˜ˆ: ์ž์ฒด ๋กœ๊ทธ์ธ), ๋‹ค๋ฅธ ๋ฐฉ์‹์˜ ํ† ํฐ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
    • ์นด์นด์˜ค์—์„œ ์ œ๊ณตํ•˜๋Š” ํ† ํฐ์€ API ์‚ฌ์šฉ์— ์ ํ•ฉํ•˜์ง€๋งŒ, ๋‚ด๋ถ€ ์‹œ์Šคํ…œ์—์„œ ์—ฌ๋Ÿฌ ์„œ๋น„์Šค ๊ฐ„์˜ ์ธ์ฆ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์ถ”๊ฐ€ ๋กœ์ง์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’™ JWT๋ฅผ ์ด์šฉํ•œ ์ง์ ‘ Token ์ƒ์„ฑ

  • ์žฅ์ 
    • ๋…๋ฆฝ์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ธ์ฆ ์ˆ˜๋‹จ์ด๋ฉฐ, ์‚ฌ์šฉ์ž ์ •๋ณด(์˜ˆ : ๊ถŒํ•œ, ์œ ํšจ ๊ธฐ๊ฐ„)๋ฅผ ์ž์ฒด์ ์œผ๋กœ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ํ™˜๊ฒฝ์—์„œ ๋น ๋ฅด๊ฒŒ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์นด์นด์˜ค ์™ธ์˜ ๋‹ค์–‘ํ•œ ๋กœ๊ทธ์ธ ์ˆ˜๋‹จ์„ ํ†ตํ•ฉ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์šฉ์ดํ•˜๋ฉฐ, ํ† ํฐ ๋ฐœ๊ธ‰ ๋ฐ ๋งŒ๋ฃŒ ์ •์ฑ…์„ ์œ ์—ฐํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • Refresh ํ† ํฐ์„ ํ†ตํ•ด ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ ์ƒˆ๋กœ์šด Access ํ† ํฐ์„ ์‰ฝ๊ฒŒ ๋ฐœ๊ธ‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹จ์ 
    • ์ธ์ฆ ์„œ๋ฒ„๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ์ถ”๊ฐ€์ ์ธ ๋ณด์•ˆ ์„ค์ •(์˜ˆ: ํ† ํฐ ์•”ํ˜ธํ™”, ์ €์žฅ์†Œ ๊ด€๋ฆฌ)์ด ํ•„์š”ํ•˜๋‹ค.
    • ํ† ํฐ ๊ด€๋ฆฌ์™€ ๋ณด์•ˆ์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์ฑ…์ž„์ด ์ƒ๊ธฐ๋ฉฐ, ์ž˜๋ชป๋œ ์„ค์ • ์‹œ ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

โž• ๋‘ ๋ฐฉ์‹ ํ˜ผํ•ฉ

  • ์นด์นด์˜ค API์—์„œ ๋ฐœ๊ธ‰๋œ ํ† ํฐ์„ ์‚ฌ์šฉํ•ด ์ดˆ๊ธฐ ์ธ์ฆ์„ ์ง„ํ–‰ํ•˜๊ณ , ์ดํ›„์—๋Š” ์ž์ฒด์ ์œผ๋กœ ๋ฐœ๊ธ‰ํ•œ JWT๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด ์žˆ๋‹ค.
  • ์นด์นด์˜ค API์™€ ํ†ตํ•ฉ๊ณผ ๋‚ด๋ถ€์ ์ธ ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ๋ชจ๋‘ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘ฉโ€๐Ÿ’ป ChatGPT๊ฐ€ ์•Œ๋ ค์ค€ ์ถ”๊ฐ€ ์˜๊ฒฌ

  • ์ผ๋ฐ˜์ ์œผ๋กœ ์™ธ๋ถ€ OAuth ์ธ์ฆ์„ ์‚ฌ์šฉํ•  ๋•Œ ์™ธ๋ถ€ Access/Refresh ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ณด์•ˆ๊ณผ ํŽธ์˜์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ ์ธ์ฆ ์ˆ˜๋‹จ์„ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๊ฑฐ๋‚˜, ํ† ํฐ ์‚ฌ์šฉ ๋ฒ”์œ„๊ฐ€ ๋” ๋„“์€ ๊ฒฝ์šฐ์—๋Š” JWT๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์นด์นด์˜ค ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ OAuth ์ธ์ฆ์„ ์™„๋ฃŒํ•œ ํ›„, ๋‚ด๋ถ€ ์‹œ์Šคํ…œ์—์„œ๋Š” ์ž์ฒด JWT ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด ๋ณด์•ˆ์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์œ ์—ฐํ•œ ํ† ํฐ ๊ด€๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค.
๐Ÿ’ญ ์นด์นด์˜คํ†ก ๋กœ๊ทธ์ธ ์‹œ ํŒจ์Šค์›Œ๋“œ ์ •๋ณด๋Š” ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•ด์•ผ ํ• ๊นŒ?

๐Ÿ—จ ์นด์นด์˜คํ†ก API ๊ณ„์ •๋งŒ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋น„์›Œ๋‘๊ธฐ

  • ์นด์นด์˜ค API๋กœ ๋กœ๊ทธ์ธํ•˜๋Š” ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ, ๋ณ„๋„์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ ์—†์ด ์†Œ์…œ ๋กœ๊ทธ์ธ๋งŒ์œผ๋กœ ์ธ์ฆ์ด ์ด๋ฃจ์–ด์ง€๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ, ์†Œ์…œ ๋กœ๊ทธ์ธ์œผ๋กœ ๋“ค์–ด์˜จ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๋น„์›Œ๋‘”๋‹ค.
  • ์†Œ์…œ ๋กœ๊ทธ์ธ๊ณผ ์ผ๋ฐ˜ ๋กœ๊ทธ์ธ์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒฝ์šฐ์—๋Š” ๊ตฌ๋ถ„ํ•ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์นด์นด์˜ค ๋กœ๊ทธ์ธ์œผ๋กœ ์ฒ˜์Œ ํšŒ์›๊ฐ€์ž… ์‹œ ์†Œ์…œ ๋กœ๊ทธ์ธ ํ”Œ๋ž˜๊ทธ๋ฅผ ์„ค์ •ํ•˜๊ณ , ์ž์ฒด ๋กœ๊ทธ์ธ ์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ•„์ˆ˜์ ์œผ๋กœ ์ž…๋ ฅ๋ฐ›๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“ฑ ์™ธ๋ถ€ OAuth ์‚ฌ์šฉ์ž์—๊ฒŒ ๋น„๋ฐ€๋ฒˆํ˜ธ ์š”๊ตฌ

  • ์™ธ๋ถ€ OAuth ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„ ๋น„๋ฐ€๋ฒˆํ˜ธ ์„ค์ • ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •ํ•˜๋„๋ก ์œ ๋„ํ•œ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋กœ๊ทธ์ธ ์‹œ ์นด์นด์˜ค ์†Œ์…œ ๋กœ๊ทธ์ธ ์™ธ์—๋„ ์ž์ฒด ๋กœ๊ทธ์ธ ์‹œ์Šคํ…œ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ ํƒ์˜ ํญ์„ ๋„“ํž ์ˆ˜ ์žˆ๋‹ค.

๐ŸŽจ ์ง์ ‘ ์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋žœ๋ค์œผ๋กœ ์ƒ์„ฑ ํ›„ ์ €์žฅ

  • ์žฅ์ 
    • ํ†ต์ผ๋œ ๊ด€๋ฆฌ : ํ•˜๋‚˜์˜ ์ธ์ฆ ์ฒด๊ณ„๋กœ ๊ด€๋ฆฌ๊ฐ€ ํ†ต์ผ๋  ์ˆ˜ ์žˆ๋‹ค.
    • ์ด์ค‘ ์ธ์ฆ ๊ฐ€๋Šฅ : ์†Œ์…œ ๋กœ๊ทธ์ธ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ธฐ๋ฐ˜์˜ ์ธ์ฆ์„ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์—ฐํ•˜๊ฒŒ ์ „ํ™˜์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ž์ฒด ๋กœ๊ทธ์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋‹จ์  ๋ฐ ์ฃผ์˜์ 
    • ๋ณด์•ˆ ๋ฌธ์ œ : ๋žœ๋ค ์ƒ์„ฑ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋งŒ์•ฝ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ์ „๋‹ฌํ•˜๊ณ  ๊ด€๋ฆฌํ• ์ง€๊ฐ€ ๋ฌธ์ œ์ด๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์ ˆ๋Œ€ ๋…ธ์ถœ๋˜์–ด์„œ๋Š” ์•ˆ ๋˜๋ฉฐ, ์ „๋‹ฌ ๊ณผ์ •์—์„œ์˜ ๋ณด์•ˆ์ด ๋งค์šฐ ์ค‘์š”ํ•˜๋‹ค.
    • ์˜๋ฏธ ์—†๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ด€๋ฆฌ : ์†Œ์…œ ๋กœ๊ทธ์ธ์„ ์‚ฌ์šฉํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ, ๊ตณ์ด ๋žœ๋ค ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์ผ ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ์ž ์ธ์ฆ์€ ์ด๋ฏธ ์นด์นด์˜ค์—์„œ ๋ณด์žฅ๋˜๋ฏ€๋กœ, ๋ถˆํ•„์š”ํ•œ ๋ณต์žก์„ฑ์„ ๋”ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค.

์ •์€๊ฒฝ

๐Ÿ’ญย ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹œ JDBC Batch Insert ๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ• ๊นŒ?

์ดˆ๊ธฐ์— ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•  ๋•Œ, ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— JDBC Batch Insert๋ฅผ ํ™œ์šฉํ–ˆ๋‹ค. ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์–ด ํšจ์œจ์ ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ์ž๋™ํ™” ์ดํ›„, JDBC๋ฅผ ์‚ฌ์šฉํ•œ ๊ธฐ์กด ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ ๋ฐฉ์‹์—์„œ ๋น„ํšจ์œจ์„ฑ์ด ๋“œ๋Ÿฌ๋‚ฌ๋‹ค. ๊ฐ ๋ ˆ์ฝ”๋“œ์˜ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ผ์ผ์ด ๋น„๊ตํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋กœ ์ธํ•ด ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ, ๋ณต์žกํ•œ ์ฝ”๋“œ ๋กœ์ง, ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹œ ์„ฑ๋Šฅ ์ €ํ•˜ ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ์˜ˆ์ƒ๋๋‹ค.

๊ทธ๋ž˜์„œ ๋‹ค๋ฅธ ๋กœ์ง์„ ๊ณ ๋ฏผํ•˜๋˜ ์ค‘ JPA ๋ณ€๊ฒฝ ๊ฐ์ง€ ๊ธฐ๋Šฅ์„ ์ „๋žต์ ์œผ๋กœ ํ™œ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. JPA๋Š” ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์ž๋™์œผ๋กœ ์ถ”์ ํ•˜์—ฌ ํ•„์š”ํ•œ ์—…๋ฐ์ดํŠธ๋งŒ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ๋ณต์žก์„ฑ ๊ฐ์†Œ, ์ตœ์ ํ™”๋œ ์ฟผ๋ฆฌ ์ƒ์„ฑ, ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ ๋“ฑ์˜ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋˜ํ•œ JPA์˜ ์œ ๋‹ˆํฌ ํ‚ค ๊ธฐ๋Šฅ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ค‘๋ณต ์‚ฝ์ž… ๋ฌธ์ œ๋„ ํ•ด๊ฒฐํ–ˆ๋‹ค.

JDBC Batch Insert์™€ JPA ๋ณ€๊ฒฝ ๊ฐ์ง€๋ฅผ ๊ฒฐํ•ฉํ•œ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ฑ„ํƒํ–ˆ๋‹ค:

  • JDBC: ์ƒˆ๋กœ์šด ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ ์‚ฝ์ž…์— ํ™œ์šฉ
  • JPA: ๊ธฐ์กด ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ์— ํ™œ์šฉ

์ดˆ๊ธฐ JDBC Batch๋งŒ ์ ์šฉํ–ˆ์„ ๋•Œ์˜ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด๋‹ค. image

๊ทธ๋ฆฌ๊ณ  ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๋ฐฉ์‹์„ ์ ์šฉํ•œ ํ›„์˜ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด๋‹ค. image

๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์•ฝ 23์ดˆ์—์„œ 15์ดˆ๋กœ ์•ฝ 34.8% ๋‹จ์ถ•๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Š” ์ค‘๊ตญ์ง‘ ์นดํ…Œ๊ณ ๋ฆฌ ํ•˜๋‚˜๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ํ•œ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ์ด๋‹ค. ์‹ค์ œ ์„œ๋น„์Šค์—์„œ๋Š” 10๊ฐœ ์ด์ƒ์˜ ๋‹ค์–‘ํ•œ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ˆ˜์ง‘ํ•˜๋ฏ€๋กœ, ์ด ์ตœ์ ํ™” ์ „๋žต์„ ์ „์ฒด ์‹œ์Šคํ…œ์— ์ ์šฉํ•  ๊ฒฝ์šฐ ์„ฑ๋Šฅ ๊ฐœ์„  ํšจ๊ณผ๊ฐ€ ๋”์šฑ ๊ทน๋Œ€ํ™”๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋œ๋‹ค.

๐Ÿ’ญย ๋ฐ์ดํ„ฐ ์ž๋™ํ™” ์‹œ๊ฐ„์€ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•˜๋Š” ๊ฒŒ ์ข‹์„๊นŒ?

์•ˆ๊ฑด

  • ์„œ๋ฒ„๋ถ€ํ•˜๋ฅผ ๋ง‰์œผ๋ฉด์„œ ๋ฐ์ดํ„ฐ์˜ ์‹ ์„ ๋„ ์œ ์ง€ํ•˜๋Š” ๋ฒ•

์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํ•ด๊ฒฐ๋ฒ•

  • ๊ณต๊ณต๋ฐ์ดํ„ฐ ๊ฐฑ์‹  ์ฃผ๊ธฐ์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ ์ž๋™ํ™”

์„ ํƒํ•œ ๋ฐฉ๋ฒ•

  1. ๊ณต๊ณต๋ฐ์ดํ„ฐ์˜ ์ผ์ฃผ์ผ ๊ฐฑ์‹  ์ฃผ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•ด ์„œ๋น„์Šค๋„ 1์ฃผ์ผ ๋‹จ์œ„๋กœ ์„ค์ •
  2. ๋Œ€๋ถ€๋ถ„์ด ์ ์‹ฌ๋ฉ”๋‰ด๋ฅผ ์ฐพ๋Š” ์ด์šฉ์ž์ž„์„ ๊ณ ๋ คํ•ด ํ‰์ผ ์ƒˆ๋ฒฝ ์‹œ๊ฐ„๋Œ€๋กœ ์„ค์ •
  3. ๊ณต๊ณต๋ฐ์ดํ„ฐ๊ฐ€ ์ž์ฃผ ๊ฐฑ์‹ ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ณ ๋ ค
  4. ๊ณต๊ณต๋ฐ์ดํ„ฐ ์ˆ˜์ง‘๊ณผ ์ „์ฒ˜๋ฆฌ ์‹œ๊ฐ„์„ ๋ถ„๋ฆฌํ•ด ์„œ๋ฒ„ ๋ถ€ํ•˜ ๋ฐฉ์ง€

์ด์ง€์›

๐Ÿ’ญ ์ธ๊ธฐ ๋ง›์ง‘์„ ๋งค๋ฒˆ ์กฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ง๊ณ  ๋‹ค๋ฅธ ๋ฐฉ๋ฒ• ์—†์„๊นŒ?

ํŒ€์›๋“ค๊ณผ ์ธ๊ธฐ ๋ง›์ง‘์„ ์กฐํšŒํ•˜๋Š” ๊ธฐ์ค€์„ ํ‰์ ๊ณผ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๋กœ ์ •ํ–ˆ๋‹ค.

์ดํ›„ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ฏผํ•˜๋ฉด์„œ ๊ฐ€์žฅ ๊ฑฑ์ •๋๋˜ ๊ฒƒ์€ ์ธ๊ธฐ ๋ง›์ง‘์˜ ๊ฒฝ์šฐ ํ•˜๋ฃจ๋‚˜ ์ผ์ฃผ์ผ ๋‹จ์œ„๋กœ ๋ณด์—ฌ์ค„ ํ…๋ฐ DB์— ์ €์žฅ๋œ ๋ชฉ๋ก์„ ์กฐํšŒํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๋งค๋ฒˆ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ด์„œ ์„ฑ๋Šฅ ๋ฉด์—์„œ ๋น„ํšจ์œจ์ ์ผ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ ์ด์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด๋˜ ์ค‘ Redis์˜ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ „๋žต์„ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

์บ์‹œ๋Š” DB์— ์ž์ฃผ ์ ‘๊ทผํ•ด์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ž„์‹œ๋กœ ์ €์žฅํ•ด ๋‘” ๋’ค, ์ดํ›„ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ DB์— ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ  ๋ฏธ๋ฆฌ ์ €์žฅํ•ด ๋‘” ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ธ๊ธฐ ๋ง›์ง‘์€ ์ผ์ • ๊ธฐ๊ฐ„ ๋™์•ˆ ๊ฐ™์€ ๊ฐ’์„ ์กฐํšŒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฟผ๋ฆฌ ์‹คํ–‰์„ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์„œ ์ ์šฉํ•˜๊ธฐ ์•Œ๋งž์€ ๋ฐฉ๋ฒ•์ด๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

์บ์‹œ์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ํ•˜๋ฃจ๋กœ ์„ค์ •ํ•ด ์ธ๊ธฐ ๋ง›์ง‘์ด ํ•˜๋ฃจ ๋‹จ์œ„๋กœ ๋ณ€๋™๋˜๊ฒŒ ์„ค์ •ํ–ˆ๋‹ค.

์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์˜ ์‘๋‹ต ์‹œ๊ฐ„์ด๋‹ค.
์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์˜ ์‘๋‹ต ์‹œ๊ฐ„

๊ทธ๋ฆฌ๊ณ  ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•œ ํ›„์˜ ์‘๋‹ต ์‹œ๊ฐ„์ด๋‹ค.
์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•œ ํ›„์˜ ์‘๋‹ต ์‹œ๊ฐ„

์‘๋‹ต ์‹œ๊ฐ„์ด 67ms์—์„œ 16ms๋กœ ์•ฝ 75% ๋‹จ์ถ•๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ž„์‹œ๋กœ ์ ์€ ๋ฐ์ดํ„ฐ๋กœ ํ…Œ์ŠคํŠธ ํ–ˆ์„ ๋•Œ ๋‚˜์˜จ ๊ฒฐ๊ณผ์ด๋‹ค. ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋กœ ์บ์‹œ๋ฅผ ์ ์šฉํ•œ๋‹ค๋ฉด ์„ฑ๋Šฅ ๋ฉด์—์„œ ๋” ํšจ๊ณผ์ ์ผ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•œ๋‹ค.

๐Ÿ’ญ ์ธ๊ธฐ ๊ธ‰์ƒ์Šน ๋ง›์ง‘ ์กฐํšŒ๋Š” ์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ• ๊นŒ?

์ธ๊ธฐ ๊ธ‰์ƒ์Šน ๋ง›์ง‘ ์กฐํšŒ ๊ธฐ์ค€์€ ์ „๋‚  ์ƒ์„ฑ๋œ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๋กœ ์ •ํ–ˆ๋‹ค.

๊ณ ๋ฏผํ•œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€. store ์—”ํ‹ฐํ‹ฐ์— ํ•˜๋ฃจ๋™์•ˆ ์ถ”๊ฐ€๋œ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ ๋‹ด๋Š” ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ review ์—”ํ‹ฐํ‹ฐ์— ์ž‘์„ฑ์ผ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ „๋‚  ์ž‘์„ฑ๋œ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•.

๋จผ์ € ํ•˜๋ฃจ๋™์•ˆ ์ถ”๊ฐ€๋œ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ ๋‹ด๋Š” ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์กฐํšŒ ์‹œ ๋ณ„๋„์˜ ๊ณ„์‚ฐ์ด ํ•„์š”๊ฐ€ ์—†์–ด์„œ ์„ฑ๋Šฅ ๋ฉด์—์„œ ์ข‹๊ณ , ์ฟผ๋ฆฌ๋„ ๊ฐ„๋‹จํ•ด์ง„๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฆฌ๋ทฐ๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ํ•„๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์ค˜์•ผ ํ•˜๊ณ , ๋งค์ผ ํ•ด๋‹น ํ•„๋“œ๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์ค˜์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์กด์žฌํ–ˆ๋‹ค. store ๋ฐ์ดํ„ฐ๊ฐ€ ์ ๋‹ค๋ฉด ๊ดœ์ฐฎ์€ ๋ฐฉ๋ฒ•์ด์—ˆ๊ฒ ์ง€๋งŒ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์— ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒ๋  ๊ฒƒ์ด๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

๋”ฐ๋ผ์„œ review ์—”ํ‹ฐํ‹ฐ์— ์ž‘์„ฑ์ผ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฑ„ํƒํ–ˆ๋‹ค. ๋ฆฌ๋ทฐ๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ์ถ”๊ฐ€์ž‘์—…์„ ํ•  ํ•„์š”๊ฐ€ ์—†์–ด ์ฝ๊ธฐ ์„ฑ๋Šฅ๋งŒ ๊ฐœ์„ ํ•˜๋ฉด ๋œ๋‹ค๋Š” ์ด์ ์ด ์žˆ์–ด์„œ๋‹ค.

๋‹ค์Œ์œผ๋กœ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋œ ์ฝ๊ธฐ ์„ฑ๋Šฅ ๊ฐœ์„  ๋ฐฉ๋ฒ•. ํ•ด๋‹น ๋ฐฉ๋ฒ•์€ ์กฐํšŒ ์‹œ ๋ฆฌ๋ทฐ์˜ ์ž‘์„ฑ ๋‚ ์งœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ง‘๊ณ„ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์„ฑ๋Šฅ์ด ๋น„๊ต์  ๋Š๋ฆฌ๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค. ๋”ฐ๋ผ์„œ Redis ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. ์บ์‹œ ๊ฐฑ์‹  ์‹œ์ ์—๋งŒ ์กฐํšŒํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ ์„ฑ๋Šฅ ๋ถ€๋‹ด์ด ๋œํ•  ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ๋‹ค. ๋˜ํ•œ, ์ „๋‚ ์˜ ๊ธฐ๋ก์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ ์‚ฌ์šฉ์ด ์˜๋ฏธ๊ฐ€ ์žˆ์œผ๋ฆฌ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

์ •์ง„ํฌ

๐Ÿ’ญ ์‚ฌ์šฉ์ž ์œ„์น˜์™€ ๋ง›์ง‘ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์–ด๋–ค ๊ฒƒ์ด ๊ฐ€์žฅ ์ ํ•ฉํ• ๊นŒ?

๊ณ ๋ฏผ

์ฒ˜์Œ ์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์กฐํšŒ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•  ๋•Œ, ๋‘ ์ง€๋ฆฌ์  ์ขŒํ‘œ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ์ง‘์ค‘ํ–ˆ๋‹ค.

๊ฒ€์ƒ‰์„ ํ†ตํ•ด ๋‘ ์ง€์  ๊ฐ„์˜ ๊ตฌ๋ฉด ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ์ˆ˜ํ•™ ๊ณต์‹์ธ โ€œํ•˜๋ฒ„์‚ฌ์ธ ๊ณต์‹โ€์„ ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ , ์ด๋ฅผ Querydsl๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์œ„์น˜์—์„œ ์ฃผ์–ด์ง„ ๋ฒ”์œ„ ๋‚ด์˜ ๋ง›์ง‘์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ฟผ๋ฆฌ๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ , ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์šธ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ํŒ๋‹จ์ด ๋“ค์–ด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ธฐ๋กœ ํ–ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ํƒ์ƒ‰

๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ ํƒ€์ž…๊ณผ ๊ณต๊ฐ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.

๊ณต๊ฐ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ •ํ™•ํ•œ ์ง€๋ฆฌ์  ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๊ณต๊ฐ„ ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ๋„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

์ฟผ๋ฆฌ์— ์–ด๋–ค ๊ณต๊ฐ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ง€ ๊ณ ๋ฏผํ–ˆ๋‹ค.

  1. ST_DISTANCE : SRID 4326์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ํ•˜๋ฒ„์‚ฌ์ธ ๊ณต์‹๊ณผ ์œ ์‚ฌํ•œ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ ํ•ฉํ•ด ๋ณด์˜€์ง€๋งŒ, ๊ณต๊ฐ„ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด ์„ ํƒํ•˜์ง€ ์•Š์•˜๋‹ค.
  2. ST_Contains + ST_Buffer : ๊ณต๊ฐ„ ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ด ๋ฐฉ๋ฒ•์„ ์„ ํƒํ–ˆ๋‹ค.

์„ ํƒํ•œ ๋ฐฉ๋ฒ•

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ๊ฒฝ๋„์™€ ์œ„๋„๋ฅผ ํ™œ์šฉํ•˜์—ฌ, ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ธ Point๋ฅผ ์‚ฌ์šฉํ•ด ์œ„์น˜(location) ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ์„ฑํ–ˆ๋‹ค.

  • ST_Contains์™€ ST_Buffer ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

    // ์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์กฐํšŒ ๋ชฉ๋ก - ๊ฑฐ๋ฆฌ์ˆœ์œผ๋กœ ์ •๋ ฌ
    @Query("SELECT s FROM Store s " +
        "WHERE ST_Contains(ST_Buffer(:userLocation, :meterRange), s.location) " + // ST_Buffer์™€ ST_Contains๋กœ spatial index ํ™œ์šฉ
        "ORDER BY ST_Distance(s.location, :userLocation) ASC") // ์‚ฌ์šฉ์ž์™€ ๊ฐ€๊นŒ์šด ๋ง›์ง‘๋ถ€ํ„ฐ ์ •๋ ฌ
๐Ÿ’ญ ์‚ฌ์šฉ์ž ์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์ถ”์ฒœ์€ ์–ด๋–ค ๊ธฐ์ค€์œผ๋กœ ์ถ”์ฒœ์„ ์ •ํ• ๊นŒ?

๊ณ ๋ฏผ

๋ง›์ง‘ ์ถ”์ฒœ์„ ์œ„ํ•œ ์ดˆ๊ธฐ ๊ณ„์‚ฐ์‹์€ ํ‰์  * 0.7 + ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ * 0.3 ์ด์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜์˜ ๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ๋„“์–ด ํฌ๊ธฐ ์กฐ์ •์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ํƒ์ƒ‰

์กฐ์ •์„ ์œ„ํ•œ ๊ณ„์‚ฐ์‹์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ๋„ค์ด๋ฒ„ ์ง€๋„ ์•ฑ์—์„œ ๋ง›์ง‘ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๋ฅผ ์กฐ์‚ฌํ–ˆ๋‹ค.

๋Œ€ํ˜• ํ”„๋žœ์ฐจ์ด์ฆˆ ๋งค์žฅ์˜ ๊ฒฝ์šฐ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๊ฐ€ 5,000๊ฐœ๋ฅผ ์‰ฝ๊ฒŒ ๋„˜๊ธฐ๊ณ , 10,000๊ฐœ ์ด์ƒ์ธ ๊ณณ๋„ ์žˆ์—ˆ๋‹ค.

๋ฐ˜๋ฉด, ๊ฐœ์ธ์ด ์šด์˜ํ•˜๋Š” ๋ง›์ง‘์€ ๋ณดํ†ต 1,000๊ฐœ์—์„œ 2,000๊ฐœ ์‚ฌ์ด์ด๋ฉฐ, ๊ฐ€๋” 2,000๊ฐœ๋ฅผ ๋„˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์ง€๋งŒ 3,000๊ฐœ ์ด์ƒ์€ ๋“œ๋ฌผ์—ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๋ฅผ 0๊ณผ 1 ์‚ฌ์ด ๊ฐ’์œผ๋กœ ์ •๊ทœํ™”ํ•˜๊ธฐ ์œ„ํ•ด 3,000์„ ๊ธฐ์ค€์œผ๋กœ ์‚ผ๊ธฐ๋กœ ํ–ˆ๋‹ค.

์„ ํƒํ•œ ๋ฐฉ๋ฒ•

  • ๊ณ„์‚ฐ์‹ =ย ํ‰์  * 0.7 + (๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ / 3000) * 0.3
  • ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๊ฐ€ 3,000๊ฐœ ์ดˆ๊ณผํ•  ๊ฒฝ์šฐ,ย (๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ / 3000)์€ 1๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ๊ณ„์‚ฐ์‹ ๊ฒฐ๊ณผ๊ฐ€ 3.0 ์ด์ƒ์ด๋ฉด ์ถ”์ฒœํ•˜๋Š” ๋ง›์ง‘์œผ๋กœ ์ •ํ–ˆ๋‹ค.
double rating = 4.2; // ํ‰์ 
int reviewCount = 1000; // ๋ง›์ง‘์˜ ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜
int maxReviewCount = 3000; // ์ •๊ทœํ™” ํ•  ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜์˜ ์ตœ๋Œ€๊ฐ’

// ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜ ์ •๊ทœํ™” (0~1 ์‚ฌ์ด ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜)
// ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜๊ฐ€ 3000์„ ์ดˆ๊ณผํ•˜๋ฉด normalizedReviewCount๋Š” 1๋กœ ์ฒ˜๋ฆฌ
double normalizedReviewCount = reviewCount > maxReviewCount ? 1.0 : (double) reviewCount / maxReviewCount;

// ์ตœ์ข… ์ ์ˆ˜ ๊ณ„์‚ฐ (ํ‰์ ์— 70%, ๋ฆฌ๋ทฐ ๊ฐœ์ˆ˜์— 30% ๊ฐ€์ค‘์น˜)
// score = 3.04
double score = (rating * 0.7) + (normalizedReviewCount * 0.3);

๐Ÿ™€ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

๊น€์˜์ฃผ

โšก ์นด์นด์˜ค ๋กœ๊ทธ์ธ DB ๊ณ„์ • ์‚ญ์ œ

๋ฌธ์ œ ์ƒํ™ฉ

  • ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์„ฑ๊ณต ์ดํ›„ ๊ณ„์ • ํšŒ์›๊ฐ€์ž… ์žฌ์‹œ๋„ ์ค‘ MySQL์—์„œ ํ•ด๋‹น ๊ณ„์ • ์‚ญ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ

์›์ธ ๋ถ„์„

  • Safe Lock์ด ๊ฑธ๋ ค์ ธ ์žˆ์–ด์„œ ํ…Œ์ŠคํŠธํ•  ๊ณ„์ •์ด ์‚ญ์ œ๊ฐ€ ๋˜์ง€ ์•Š์•˜๋˜ ๊ฒƒ

ํ•ด๊ฒฐ ๊ณผ์ •

  • Safe Mode๋ฅผ ํ•ด๋‹น ์ฟผ๋ฆฌ๋ฌธ์„ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ ๊ป๋‹ค๊ฐ€ ์ผœ์คŒ
-- Safe update mode ๋น„ํ™œ์„ฑํ™”
SET SQL_SAFE_UPDATES = 0;

-- DELETE ์ฟผ๋ฆฌ ์‹คํ–‰
DELETE FROM users WHERE social_type = 'KAKAO';

-- Safe update mode ๋‹ค์‹œ ํ™œ์„ฑํ™”
SET SQL_SAFE_UPDATES = 1;

๊ฒฐ๊ณผ

image image

์ •์€๊ฒฝ

โšก Spring Boot 3.0 ์ด์ƒ Spring Batch ์˜ค๋ฅ˜

๋ฌธ์ œ ์ƒํ™ฉ

  1. ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ” ์ƒ์„ฑ ์˜ค๋ฅ˜ ๋ฐœ์ƒ์œผ๋กœ Job์ด ์‹คํ–‰๋˜์ง€ ์•Š์Œ
  2. ์—ฌ๋Ÿฌ ๊ฐœ์˜ Job ์ƒ์„ฑ ์‹œ ์‹คํ–‰ ์˜ค๋ฅ˜

์›์ธ ๋ถ„์„

  • Spring Batch 5.0๊ณผ Spring Boot 3.0์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์œผ๋กœ ์ž๋™ ์„ค์ • ๋น„ํ™œ์„ฑํ™”
  • @EnableBatchProcessing springBoot 3.0 ๊ถŒ์žฅ x โ†’ ์ž๋™ ์„ค์ • ๋ชจ๋‘ ๋น„ํ™œ์„ฑํ™”

ํ•ด๊ฒฐ ๊ณผ์ •

  • ์ƒˆ๋กœ์šด BatchConfig ํด๋ž˜์Šค ์ƒ์„ฑ
@Configuration
@EnableConfigurationProperties(BatchProperties.class)
public class BatchConfig {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true)
    public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, JobExplorer jobExplorer,
                                                                     JobRepository jobRepository, BatchProperties properties) {
        JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
        String jobNames = properties.getJob().getName();
        if (StringUtils.hasText(jobNames)) {
            runner.setJobName(jobNames);
        }
        return runner;
    }
}
  • DataPipeJobConfig์™€ย OpenApiJobConfigย ์ˆ˜์ •:
    • @EnableSchedulingย ์–ด๋…ธํ…Œ์ด์…˜ ์ œ๊ฑฐ (์Šค์ผ€์ค„๋Ÿฌ ํด๋ž˜์Šค๋กœ ์ด๋™)
    • @Configurationย ์œ ์ง€
  • DataPipeJobScheduler ์ˆ˜์ •
@Component
@RequiredArgsConstructor
@EnableScheduling
@Slf4j
public class DataPipeJobScheduler {
    private final JobLauncher jobLauncher;
    private final Job openApiJob;
    private final Job dataPipeJob;

    @Scheduled(cron = "0 0 3 * * 1")  // ๋งค์ฃผ ์›”์š”์ผ ์ƒˆ๋ฒฝ 3์‹œ 1๋ฒˆ
    public void collectRawData(){
        runJob(openApiJob,"๊ณต๊ณต๋ฐ์ดํ„ฐ ์ˆ˜์ง‘");
    }

    @Scheduled(cron = "0 0 5 * * 1") // ๋งค์ฃผ ์›”์š”์ผ ์ƒˆ๋ฒฝ 5์‹œ 1๋ฒˆ
    public void processedDataUpdate(){
        runJob(dataPipeJob,"์šด์˜ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ");
    }

    private void runJob(Job job, String jobDescription) {
        log.info("{} Job์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.",jobDescription);
        try {
            // ๊ฐ ์‹คํ–‰๋งˆ๋‹ค ๊ณ ์œ ํ•œ JobParameters ์ƒ์„ฑ
            JobParameters jobParameters = new JobParametersBuilder()
                    .addLong("time", System.currentTimeMillis())
                    .toJobParameters();
            // ์ž‘์—… ์‹คํ–‰
            JobExecution jobExecution = jobLauncher.run(job, jobParameters);
            // ์ž‘์—… ์‹คํ–‰ ๊ฒฐ๊ณผ
            log.info(" {} Job ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค: {}", jobDescription,jobExecution.getStatus());
        } catch (Exception e) {
            // ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ
            log.error("{} Job์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {}",jobDescription, e.getMessage());
        }
    }
}
  • application-secret.yml ์ˆ˜์ •
 batch:
    job:
      enabled: false #์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ์ž๋™ ์‹œ์ž‘ ๋ฐฉ์ง€
    jdbc:
      initialize-schema: always

๊ฒฐ๊ณผ

  • ๋ฉ”ํƒ€ํ…Œ์ด๋ธ” ์„ฑ๊ณต์ ์œผ๋กœ ์ƒ์„ฑ
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ Job์ด ์Šค์ผ€์ค„๋Ÿฌ ์„ค์ •์— ๋งž๊ฒŒ ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰

์ด์ง€์›

โšก EC2 ํ™˜๊ฒฝ์—์„œ Redis Docker ์ปจํ…Œ์ด๋„ˆ์™€ Spring Boot ์—ฐ๊ฒฐ ์˜ค๋ฅ˜

๋ฌธ์ œ ์ƒํ™ฉ

  • EC2 ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ Redis cache๋ฅผ ์‚ฌ์šฉํ•œ API ์š”์ฒญ ๋‚ ๋ฆด ๊ฒฝ์šฐ 500 ์—๋Ÿฌ ๋ฐœ์ƒ๊ณผ ํ•จ๊ป˜ Connection refused ์˜ค๋ฅ˜ ๋ฐœ์ƒ 2024-10-28_10 10 41

์›์ธ ๋ถ„์„

  1. redis ๋น„๋ฐ€๋ฒˆํ˜ธ ์„ค์ • ๋ฌธ์ œ
  2. redis host ์„ค์ • ๋ฌธ์ œ

ํ•ด๊ฒฐ ๊ณผ์ •

  1. redis ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์•„์„œ application-secret.yml์— redis ๋น„๋ฐ€๋ฒˆํ˜ธ ์„ค์ •์„ ํ•ด์ค€ ํ›„ ๋‹ค์‹œ ๋ฐฐํฌํ•จ

      data:
        redis:
          password: [redis ๋น„๋ฐ€๋ฒˆํ˜ธ]

    โžก๏ธ ๊ทธ๋Ÿฌ๋‚˜ ์„ค์ •ํ•ด์ค€ ํ›„ ๋‹ค์‹œ API ์š”์ฒญ ๋ณด๋‚ด๋„ ๋˜‘๊ฐ™์€ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

  2. ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ๋Š” ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ EC2 ํ™˜๊ฒฝ์—์„œ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋Š” ๊ฒƒ์ด๋ผ๋ฉด host ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•จ โ†’ EC2 ์ธ์Šคํ„ด์Šค ๋‚ด๋ถ€์—์„œ redis ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, redis host๋ฅผ EC2 IP๋กœ ์„ค์ • ํ›„ ๋‹ค์‹œ ๋ฐฐํฌํ•จ

      data:
        redis:
          password: [redis ๋น„๋ฐ€๋ฒˆํ˜ธ]
          host: [EC2 IP]

๊ฒฐ๊ณผ

  • redis cache๋ฅผ ์‚ฌ์šฉํ•œ API ์ •์ƒ ์ž‘๋™

์ •์ง„ํฌ

โšก Point ์ž๋ฃŒํ˜•๊ณผ ๊ณต๊ฐ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ SRID ์„ค์ •

๋ฌธ์ œ ์ƒํ™ฉ

์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€
java.sql.SQLException: Binary geometry function st_contains given two geometries of different srids: 0 and 4326, which should have been identical

์›์ธ ๋ถ„์„

์ฟผ๋ฆฌ์—์„œ๋Š” ๊ณต๊ฐ„ ํ•จ์ˆ˜(ST_Contains, ST_Distance)์™€ location, myLocation์„ ์‚ฌ์šฉํ•ด์„œ ์‚ฌ์šฉ์ž์˜ ์œ„์น˜์™€ ๋ง›์ง‘์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•œ๋‹ค.
ํ•ด๋‹น ์˜ค๋ฅ˜๋Š” ST_Contains ํ•จ์ˆ˜๊ฐ€ SRID๊ฐ€ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ geometry ๊ฐ์ฒด๋ฅผ ๋น„๊ตํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์ด๋‹ค.
ST_Contains ํ•จ์ˆ˜๋Š” ๋‘ geometry๊ฐ€ ๋™์ผํ•œ SRID(Spatial Reference System Identifier)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ์ž‘๋™ํ•œ๋‹ค.
์ด๋Ÿฐ ๊ฒฝ์šฐ ์–ด๋–ค geometry์˜ SRID๋Š” 4326์œผ๋กœ ์„ค์ •๋์ง€๋งŒ, ๋‹ค๋ฅธ ํ•˜๋‚˜์˜ SRID๋Š” 0์œผ๋กœ ๋˜์–ด ์žˆ์–ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

ํ•ด๊ฒฐ ๊ณผ์ •

Store ์—”ํ‹ฐํ‹ฐ ํŒŒ์ผ์—์„œ location ํ•„๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ SRID๋ฅผ 4326์œผ๋กœ ์„ค์ •ํ–ˆ๋‹ค.
ํ•˜์ง€๋งŒ StoreService ํŒŒ์ผ์—์„œ myLocation ์ธ์Šคํ„ด์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ SRID ์„ค์ •์ด ๋ˆ„๋ฝ๋˜์–ด ์žˆ์–ด, ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด SRID๋ฅผ ์„ค์ •ํ•ด ์ฃผ์—ˆ๋‹ค.

๊ฒฐ๊ณผ

Point myLocation = geometryFactory.createPoint(new Coordinate(lon, lat));
// ์•„๋ž˜ ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฌธ์ œ ํ•ด๊ฒฐ
myLocation.setSRID(4326); // SRID 4326 (WGS 84 ์ขŒํ‘œ๊ณ„)๋กœ ์„ค์ •

About

๐Ÿš์œ„์น˜ ๊ธฐ๋ฐ˜ ๋ง›์ง‘ ์ถ”์ฒœ ์›น ์„œ๋น„์Šค

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •