이 게시글은 2025년 1월 14일 진행된 DGB금융그룹의 IT's DGB iM Challenger 대한민국 디지털 인재 양성 프로젝트 공모전 발대식 및 본선 대회 후기입니다.

 

 

1. 대회 공고 확인 및 팀 구성

https://dgb-challenger.co.kr/15

 

 

금융 관련 공모전을 기다리던 중 발견한 DGB금융그룹의 IT's DGB iM Challenger 공모전 !

이름이 길어서 복잡해 보이지만 결론은 디지털 기술을 적용한 금융 관련 상품이나 서비스 아이디어를 개발하는 것이다.

 

예선 - 본선 - 파이널 라운드, 사이에 전문 교육 등등 호흡이 긴 공모전이지만 일단 본선 대회 진출을 목표로 준비를 시작했다.

 

 

 

 

 

2. 예선 준비

우리 팀은 나와 내 친구 2명이었고 둘 모두 개발을 전공한 (예비) 개발자이다.

금융 지식 보유자, 디자이너 없이 개발만 아는 팀원 두 명이었지만 본선 대회에 진출할 수 있었다.

 

예선 준비를 하면서 친구와 다양한 아이디어를 논의해보았고 우리는 금융 관련 지식이 별로 없는만큼 어려운 주식 투자, 펀드, 부동산 등 보다는 보다 단순한 (우리들이 말하기로는 보다 말랑말랑한) 주제를 선정하고자 했다.

 

 

 

이렇게 전년도 수상 정보도 조사해보고 노션을 파서 회의를 진행했다.

 

우리 팀이 최종적으로 선정한 아이디어는 "맞춤형 DGB 캐릭터 키우기 서비스" 이다. 

 

아이디어 회의를 진행하면서 주목했던 2가지는

 

1) 요즘 유행하는 서비스가 무엇인가? => 피크민과 같은 캐릭터 서비스

2) DGB금융그룹이 원하는 건 무엇일까? => iM뱅크가 시중은행이 된 만큼 인지도 상승시키기

였고 전년도에도 dgb 캐릭터를 활용한 아이디어가 수상했던 것을 보아 이를 활용해서 주제를 선정했다.

 

(그런데 예선 자료를 만들면서는 전년도 아이디어랑 너무 유사해보일까봐 걱정되었다. 그래도 결론적으로는 본선까지 간 걸 보면 나름 잘 정한 주제인 것 같다)

 

 

우리는 예선 접수할 때 기술 구현은 하지 않았다. (예비)개발자 2명이었지만 둘 모두 공모전이 처음이었기에 주제 정하고 구체화하는데 더 집중했다.

 

예선 제출날 공모전 홈페이지 서버가 이상해서 메일로 제출하고 하는 이슈가 있었지만 그래도 정상적으로 접수 완료가 되었다.

 

3. 본선 진출 팀 발표

본선 진출 팀 발표는 12월 31일에 이루어졌다. 2024년의 마지막 날 발표라니.. 만약 떨어졌다면 꽤 씁쓸했을 것 같다.

 

발표는 공모전 홈페이지 팝업 및 공지사항으로 이루어졌고 나는 오후 5시쯤 들어가봤는데 낮 즈음에 발표가 나 있었다.

가나다 순이라 홈페이지 들어가자마자 금잔디가 있어서 바로 발견하고 흥분 MAX 상태로 친구에게 전화했다 ㅋㅋ

 

후에 뉴스에서 보니까 총 89팀이 예선 접수했고 그 중 20팀이 발대식 및 본선 대회에 진출했다고 한다.

 

 

4. 본선 대회 준비

본선 진출 팀 발표 이후 1주일 정도 본선 발표용 자료 제출 기한이 주어진다. 이때 기존 주제를 벗어나지 않는 선에서 아이디어 디벨롭이 가능하다. 우리 팀은 소비 분석 케이스를 더 구체화하고 추가 캐릭터를 제작해서 포함했다.

 

이때 자료에 동영상, 슬라이드 쇼, 폰트 등 잘 체크해서 제출하라고 공지를 꼼꼼히 해주신다. 우리 팀은 혹시나 폰트가 깨지면 PDF로 발표하려고 슬라이드 쇼 같은것도 안넣었는데 발표 후 생각해보니까 조금이라도 관심을 주목하기 위한 요소로 넣을 걸 그랬나 싶었다. (아무래도 20팀이 10분씩 계속 발표하다보니 본선 대회가 루즈해지는 것 같았다.)

 

 

학교 세미나실에 가서 발표 연습도 하고, 우리 팀은 서울에서 대구까지 가야하므로 왕복 KTX와 호텔도 1박 예약했다. 본선 대회 때는 서울 기준 KTX 편도 43500원, 왕복 87000원을 지원해준다. 본선 대회 후 일주일 정도 후에 바로 입금이 되었다!

 

 

5. 리허설

본선 대회 전날인 1/13일에 간단한 리허설이 있었다. 본선 대회 발표 순서(랜덤)대로 마이크 테스트 및 PPT 오류가 없는 지 확인한다. 마이크는 핸드 마이크와 핀 마이크 중 고를 수 있다. 대부분 팀들이 핸드 마이크를 썼는데 발표 때 한 손에는 포인터를 들어야 하니 이를 고려해서 선택해도 좋을 것 같다. 아무래도 핸드 마이크를 선택하면 손을 사용하는데 제약이 있다.

 

 

KTX 타고 대구로 이동~ 동대구역에서는 택시를 타고 갔다.

 

입구에서 단디와 똑디가 반겨준다. 아주 반가워서 친구한테 여기서 사진 한 장 찍어줄까? 했는데 거절함 ㅋㅋ쿄

iM뱅크 제2본점이라는데 회사 아주 삐까뻔쩍했다.

 

 

그리고 발대식 및 본선대회가 이루어질 5층 홀 ! 

 

리허설 때 나누어주신 안내 종이. 총 20팀이라 7, 7, 6 팀 씩 끊어서 발표했다. 

 

 

 

6. 발대식

본선 대회 날의 오전 동안에 발대식이 이루어졌다. DGB금융그룹 회장님과 임직원 분들, 대구 국회의원, 대구 지역의 대학교 교수님들 등 많은 분들이 참석하셨다.

 

4층 다목적 홀이 참가학생들 대기 공간 및 짐을 두고 점심도 먹는 공간이었다. 본선 대회 당일날 도착하면 단체 티를 나누어주신다. 민트색이라고 미리 공지가 되어있었어서 소화할 수 있을까,, 싶었는데 약간의 청록색? 계열이라 다행이었다 

 

사이즈가 95, 100, 105 로 나뉘어져있고 골라서 가져갈 수 있지만 전체적으로 크기가 매우 컸고 기모가 아주 부드러웠다 잠옷으로 입으면 딱일듯

 

 

 

 

발대식 세레모니와 축하 말씀이 있고 대한 변리사 협회의 변리사님이 1시간동안 강의도 해주셨다. IT's DGB iM Challenger 공모전은 교통비 지원, 단체복 제공 등등 모든게 완벽한데 하나 아쉬운 점이 있다면 바로 발대식 및 본선 대회가 이루어지는 공간의 학생들 자리였다. 

 

DGB금융그룹 제공

 

이렇게 계단처럼 된 공간에 앉는 형식인데 자리가 너무 좁고 학생들이 촘촘히 앉아야해서 등을 기대거나 다리를 펼수도 없다. 본선대회날은 거의 하루 종일 여기 앉아있어야 하는데 우리 팀 뿐만 아니라 다른 학생들도 힘들어하는 것 같았다. 

여기 공간이 이런 행사를 하기에는 매우 예쁘고 좋지만 학생들 앉는 공간을 조금만 더 확장해주셔도 좋을 것 같다..

 

 

 

 

발대식 이후 점심 식사를 하고 본선 대회가 진행된다. 도시락도 매우 맛있어 보이는 걸로 제공해주시는데 난 긴장이 되서 거의 못먹었다ㅠㅠ 너무 아쉽다

 

 

발표 공간 옆에 이렇게 간식과 생수도 아주 빵빵하게 제공된다!

 

 

7. 본선 대회

 

밥을 먹고 올라오면 이렇게 본선 대회를 위한 준비가 마쳐져있다. 심사위원은 6분 정도이고 외부 위원 2분에 DGB금융그룹 내부 인사 4분(iM뱅크 ict 및 디지털 사업부의 부장님들 4분) 정도였다. 

 

발표 후 심사위원 Q&A는 없으며 발표자 앞에 10분 타이머와 PPT를 볼 수 있는 스크린을 준비해 주셨다. 팀 당 제공되는 10분 시간이 끝나면 마이크가 자동으로 OFF될 거라고 하셨는데 10분을 초과한 팀은 없었다.

 

모든 발표가 종료된 후 바로 점수를 집계해서 파이널라운드에 진출할 10팀을 발표한다.

 

무려 20팀의 발표를 들으면서 느낀 점은 아이디어는 한정되어 있지만 이를 어떻게 분석하고 표현하는 지가 중요한 것 같다는 점이다. 다른 팀들의 주제로는 소액 주식 투자 상품, AI를 활용한 부동산 서비스, 자산 관리 서비스 등이 있었는데 금융 공모전을 준비해봤다면 한번쯤은 생각해봤을 주제들이었다. 조금 더 시선이 가고 퀄리티 있어보이는 발표는 누구나 생각할 수 있는 주제에 대해 기존 서비스와의 차별점을 구체화한 발표들이었다.

 

우리 팀은 아쉽게 파이널라운드에는 진출하지 못했지만 발대식 및 본선 대회에 진출한 것만으로도 너무 좋은 경험이었다!

 

 

파이널 라운드에 진출하지 못한 10팀에게는 10만원 상당의 기념품이 제공된다고 홈페이지에 나와있었는데

10만원 상당의 기념품은 바로 10만원 백화점 상품권이었다 ㅋㅋㅋ

 

쓸데없는 기념품 보다 돈으로 주는 은행 최고다

 

행사 종료 후 동대구역 앞에서 막창도 먹고 KTX를 타고 서울로 왔다

 

 

 

 

8. 느낀점

첫 공모전 도전이었는데 본선에 진출해서 공개PT라는 의미있는 경험을 할 수 있어서 좋았다. 기획한 아이디어에 대해 개발까지 완료한 건 아니지만 주제를 구체화하고 발표 자료를 만들면서 마이데이터 등 금융권의 디지털 서비스에 대한 이해도도 높아졌다. 이 공모전은 예선 제출부터 만약 다음 라운드에 계속 진출한다면 본선 대회, 전문 교육, 파이널 라운드 등 호흡이 긴 공모전이지만 본선 대회에 진출하는 것만으로도 큰 경험이 되니  DGB금융그룹 공모전을 고민 중인 분들이 계시다면 일단 도전해보길 강추한다.

* JPA (Java Persistence API)

* JPQL(Java Persistence Query Language) : SQL과 유사한 구문을 사용하여 데이터베이스에서 엔티티 객체를 조회하는 쿼리 언어

 

1. setFirstResult, setMaxResults 로 offset, limit 처리

setFirstResult(int offset)

: 결과 리스트에서 시작할 첫 번째 행의 위치를 설정, 데이터베이스 쿼리 결과에서 특정 위치부터 데이터를 가져올 수 있다.

 

setMaxResults(int limit)

: 반환할 최대 값을 설정, 이 값을 이용해 페이지 당 데이터를 얼마나 가져올지 제어할 수 있다.

 

public List<Post> findByKeywordIdPaging(int keywordId, int limit, int offset) {
        //keywordId로 Post 조회하여 결과 목록 전달
        String queryStr = "SELECT pk.post FROM PostKeyword pk WHERE pk.keyword.id = :keywordId order by pk.post.createDate DESC";
        TypedQuery<Post> query = em.createQuery(queryStr, Post.class)
                .setParameter("keywordId", keywordId)
                .setFirstResult(offset) 
                .setMaxResults(limit);   

        return query.getResultList();
    }

 

장점 :

1) 쿼리 제어가 가능하여, 복잡한 쿼리나 커스텀 쿼리에 대해 유연하게 페이징 적용 가능

 

단점 :

1) 매번 쿼리를 작성해야 한다

2) ( 전체 페이지 수, 총 데이터 수)와 같은 추가적인 정보를 얻기 어렵다

 

 

 

 

2. Spring Data JPA의 Pageable, Page 인터페이스

Spring Data JPA의 Pageable 인터페이스는 조금 더 높은 수준의 페이징 기능을 제공한다

PageRequest.of(page, size)를 사용해 페이지 번호와 페이지 크기 지정, 내부적으로는 이를 기반으로 offset, limit 값을 계산

 

offset : page*size 로 계산. 예를 들어, 3번째 페이지를 요청하고 페이지 당 size가 10이라면 offset=3*10=30.

limit : size로 설정됨, 페이지 당 가져올 데이터의 수

 

Pageable pageable = PageRequest.of(2, 10); // 3번째 페이지 (0-indexed), 페이지당 10개의 데이터
Page<Post> postsPage = postRepository.findByTitleContaining("example", pageable);

 

장점 :

1) 코드 간소화(쿼리를 직접 작성하지 않고도 메서드 이름 기반으로 페이징 처리 가능

2) 부가적인 페이징 정보를 얻는데 유리하다(전체 페이지 수, 전체 데이터 개수 등)

3) 확장성(페이징, 정렬, 검색 기능을 쉽게 추가할 수 있다)

 

단점 :

1) 내부적으로 동작하는 쿼리 제어가 어려우므로, 복잡한 쿼리를 처리할 때는 한계가 있을 수 있다

 

 

 


추가로 사용할 수 있는 페이징 방법들

3. Native Query 를 사용한 페이징 처리

복잡한 SQL 쿼리를 직접 작성하고 페이징을 적용할 수 있다.

복잡한 데이터베이스 구조나 성능 최적화를 위해 사용될 수 있다.

@Query(value = "SELECT * FROM post WHERE title LIKE %:title% ORDER BY create_date DESC LIMIT :limit OFFSET :offset", nativeQuery = true)
List<Post> findByTitleNative(@Param("title") String title, @Param("limit") int limit, @Param("offset") int offset);

 

장점 : 고도화된 SQL 제어 가능, 복잡한 쿼리에 대해 성능 최적화 가능

단점 : 유지 보수가 어렵고, 데이터베이스에 종속적일 수 있다.

 


 

 

 

그렇다면 각각의 페이징 기법은 어떤 경우에 사용하면 좋을까?

 

단순한 페이징을 사용하는 경우에는 Pageable 과 Page를 사용하는 Spring Data JPA 방식이 효율적이고

복잡한 쿼리 제어가 필요하다면 setFirstResult 혹은 Native Query 방식을 사용하는 것이 좋을 듯하다.

 

그러면 복잡한 쿼리 제어가 필요한 경우의 기준이 어떻게 되는 지 헷갈려서 chat gpt에게 물어보았다.

 

복잡한 쿼리 제어가 필요하다는 것은,

데이터베이스 단순 조회 작업을 넘어 더 많은 조건, 조인, 서브쿼리 등을 포함해 성능 최적화와 같은 고려가 필요한 경우를 말한다고 한다. 수백만개 이상의 데이터를 처리할 때는 페이징, 정렬 등의 최적화가 필수적이고 이런 경우에도 쿼리 제어 방법을 사용한다고 한다. 

 

 


 

이렇게 총 3가지 페이징 기법들에 대해 학습한 후 내 개인 프로젝트인 배달 서비스 '마잇'에 어떤 기법을 적용하면 좋을 지 고민해보았다. 

 

마잇은 내가 개발중인 배달 애플리케이션 서버이다. 개인 프로젝트로 진행 중이라 프론트 영역은 시각적 이해를 위해 보여주기 위한 부분만 타임리프로 개발하고 주로 백엔드 개발 위주로 진행하고 있다.

 

다음과 같은 기능들을 목표로 개발 중이다.

나는 이 프로젝트를 활용해서 Redis 캐싱 기법 혹은 스프링 부트의 비동기 프로세싱을 활용한 성능 최적화에 관하여 졸업 논문을 작성할 예정이라 이 부분을 염두에 두고 확장성에 유리한 Spring Data JPA 의 Pageable을 활용하는 방법으로 정하였다.

 

 

투스데이 서비스를 배포하고 그 이후 자잘자잘한 오류를 해결하고, 추가 개발하고 있다.

그 중에 내가 오늘 해결한 오류에 대해 정리해보려 한다!

사실 그렇게 어려운? 오류는 아니었고 에러 코드를 보자마자 어 익숙한데! 싶었다.

 


 

08-07 03:40:38.274 WARN 15204 --- [nio-8000-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1451, SQLState: 23000 2024-08-07 03:40:38.275 ERROR 15204 --- [nio-8000-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Cannot delete or update a parent row: a foreign key constraint fails (toothday.notification, CONSTRAINT FKn1l10g2mvj4r1qs93k952fshe FOREIGN KEY (post_id) REFERENCES post (post_id))

 


오류 발생 상황

 

서비스 배포 후 이것 저것 기능들이 잘 작동하는지 테스트해봤는데 한가지 이상한 점이 있었다

바로 커뮤니티 게시글 삭제에서 어떤 게시글은 삭제가 잘 되고 어떤 게시글은 삭제 버튼을 눌러도 튕기고 삭제가 이루어지지 않았다. 의심되는 원인으로는 좋아요나 댓글이 달려있는 경우에 삭제가 잘 되지 않는 것 같았다

 

그래서 바로 테스트 돌입

 

게시글(좋아요,댓글X) ---> 삭제 성공

게시글(내가 좋아요,댓글 작성) ---> 삭제 성공

음 여기서 일단 1차 의문 내가 좋아요와 댓글을 작성하였을 때는 무사히 삭제가 된다. 그럼 좋아요, 댓글 연관 문제가 아닌가?

게시글( 타유저의 좋아요 ) ---> 삭제 실패 !!!

찾았다! 타유저의 좋아요나 댓글이 생성된 경우에 에러가 뜬다. 왜일까? 혹시 JWT 관련 문제일까 싶어 에러 코드를 확인해봤더니 위에 있는 익숙한 SQL 에러코드가 있었다.

 

 

원인 파악

 

원인은 내 게시글에 타유저가 좋아요나 댓글을 남기면 알림이 생성되도록 알림 기능을 개발했는데

알림 테이블이 게시글ID를 외래키로 가져서 게시글을 삭제할 때 알림과 관련하여 에러가 떴던 것이다. 

알림을 개발 후반부에 작업하고 알림과 테이블 사이에 CASCADE 설정을 해주지 않아서 에러가 떴던 것이다

 

 

처음 오류를 확인하고 왜 어떨 때는 되고 어떨 때는 안되나 답답했었는데 이렇게 명확한 원인이 있었다

원인을 파악하고 나니까 답답했던 속이 시원해졌다.

게시글 삭제 시에 해당 post id를 가지는 알람도 삭제 후에 게시글을 삭제하도록 코드를 수정하고 오류를 해결하였다.

public void delete(Post post) {
    notificationRepository.deleteByPostId(post.getId());
    postRepository.delete(post);
}

 

지난 번에 cascade 조건에 대해서도 공부해보고 sql 연관관계에 대해서도 공부하였는데 덕분에 이번에 에러 원인 파악을 빠르게 할 수 있었던 것 같다!

나는 현재 치과 기록 및 커뮤니티로 치아 건강을 관리하는 서비스 투스데이 백엔드 개발 중 커뮤니티 기능 대부문을 맡아서 개발하고 있다.

 

그런데, 커뮤니티 기능을 모두 개발하고 전체 api 테스트를 해보던 와중 좋아요 취소 부분에서 에러가 발생했다.

 

"timestamp": "2024-07-14T04:00:10.191+00:00",
    "status": 500,
    "error": "Internal Server Error",
    "trace": "org.springframework.dao.IncorrectResultSizeDataAccessException: query did not return a unique result: 2; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 2\\r\\n\\tat org.springframework.orm.jpa.

 

 

내용을 보니 query did not return a unique result 하나만 정의되어있어야 하는 값이 중복되어 있는 것 같다.

db를 살펴보니 역시나 한 명의 유저가 하나의 게시글에 좋아요를 두번 눌러 버렸다.

직전에 좋아요 등록 테스트를 할 때 같은 정보로 2번 눌렸고 아무런 저항 없이 새로운 좋아요가 생성되어 버린 것이다.

@PostMapping("/api/community/{postId}/like")
    public ResponseEntity<String> like(@PathVariable Long postId, 
																		   HttpServletRequest request) {
        String token = request.getHeader("Authorization").replace("Bearer ", "");
        Long userId = JwtUtil.getUserIdFromToken(token);
        User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));
        
        Post post = postRepository.findById(postId);
        PostLike like = new PostLike();
        like.setUser(user);
        like.setPost(post);
        likeService.save(like);
        return ResponseEntity.ok("Like successful");
    }

    @DeleteMapping("/api/community/{postId}/like")
    public ResponseEntity<String> unlike(@PathVariable Long postId, HttpServletRequest request) {
        String token = request.getHeader("Authorization").replace("Bearer ", "");
        Long userId = JwtUtil.getUserIdFromToken(token);
        
        Post post = postRepository.findById(postId);
        PostLike like = likeService.findByPostIdAndUserId(postId, userId);
        if(like!=null) {
            likeService.delete(like);
            return ResponseEntity.ok("Like Delete successful");
        } else {
            return ResponseEntity.ok("Like not found");
        }
    }

내가 작성한 좋아요 등록, 취소 api이다.

 

public PostLike findByPostIdAndUserId(long postId, long userId) {
        try {
            return em.createQuery("select pl from PostLike pl where pl.post.id=:postId and pl.user.id=:userId", PostLike.class)
                    .setParameter("postId", postId)
                    .setParameter("userId", userId).getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

 

당연하게도 유저 한 명당 게시글 하나에 좋아요를 한번만 누를 수 있다고 생각하였고 postId와 userId를 사용해서 좋아요를 찾아내고 삭제하도록 설계하였다.

 

그리고 위와 같이 좋아요가 2개 이상 생성되어 있으니 삭제할 수 없는 문제가 발생한 것이다.

 

 

생각해보니 좋아요는 등록/취소 api를 따로 설계하지 말고

하나의 api만으로 좋아요가 눌려있다면 → 취소, 좋아요가 눌려있지않다면 → 등록 이렇게 로직을 짜주면 될 것 같았다. 

 

 

@PostMapping("/api/community/{postId}/like")
    public ResponseEntity<String> like(@PathVariable Long postId, HttpServletRequest request) {
        String token = request.getHeader("Authorization").replace("Bearer ", "");
        Long userId = JwtUtil.getUserIdFromToken(token);
        User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));
        Post post = postRepository.findById(postId);
        PostLike isLiked = likeService.findByPostIdAndUserId(postId, userId);
        if (isLiked == null) {
            PostLike postLike = new PostLike();
            postLike.setPost(post);
            postLike.setUser(user);
            likeService.save(postLike);
            return ResponseEntity.ok("Like successful");
        }
        else {
            likeService.delete(isLiked);
            return ResponseEntity.ok("Like Deleted successful");
        }
    }

 

성공하였다!

이번학기 졸업 작품으로 배달 앱의 서버 구현을 진행하기로 하였다. 내가 만들 배달 앱의 차별성은 바로

고객과 라이더의 정액권 체결로 항상 같은 라이더가 내 음식을 가져다 준다는 것이다.

 

다른 배달 서비스 들에선 주목받지 않았던 '라이더'에 주목한다는게 차별점이다.

라이더의 존재를 수면 위로 들어내 인증된 라이더가 항상 내 음식을 안전하게 배달해준다는 컨셉이다.

 

 

고객, 라이더, 음식점의 장점

 

고객

  • 인증된 라이더에게 배달받을 수 있어 안전하다.
  • 고객 - 라이더 간의 계약이 되어있으므로 음식 파손 등의 배달 사고를 줄일 수 있다.
  • 라이더가 지정되어 있으므로 배차 되느라 오랜 시간을 기다리지 않아도 된다.

라이더

  • 인근에 거주하는 고객 여럿과 계약을 맺으면 이동 경로를 최소화하여 배달할 수 있다.
  • 고객이 정액권을 결제하였으므로 최소 급여 보장이 가능하다.

음식점

  • 각각의 배달 주문에 지정된 라이더가 있기 때문에 오랜 시간 배차를 기다리지 않아도 된다.

 

 

주요 기능

회원 기능

  • 고객 회원가입
  • 라이더 회원가입
  • 음식점 회원가입

메뉴 기능

  • 메뉴 등록
  • 메뉴 수정

정액권 기능

  • 라이더 목록
  • 정액권 체결

주문 기능

  • 음식 주문(결제)
  • 주문 내역 조회

배달 기능

  • 라이더 배차
  • 배달 현황

 

 

도메인 모델

도메인 모델을 설계하며 연관 관계 매핑에 대해 많이 고민해보게 되었다. 테이블을 어떻게 구성하는게 최적의 방법일까 혼자 많이 고민해보았다. 

JPA 란 "객체와 관계형 데이터베이스 테이블이 어떻게 매핑되는지를 이해하는 것"

 

 

단방향

JPA 에서는 기본적으로 두 엔티티 사이의 연관 관계를 단방향으로 정의한다.

이 상태에서는 한 쪽 엔티티는 연관 관계인 엔티티 객체를 조회할 수 있으나, 반대쪽 엔티티 객체는 어떤 엔티티 객체와 연관관계를 갖는지 알 수 없다.


양방향 연관 관계의 규칙

  • 연관 관계를 갖는 두 객체 중 하나를 연관 관계의 주인으로 지정
  • 연관 관계의 주인만이 외래키를 관리(삽입, 수정, 삭제)
  • 주인이 아닌 쪽은 읽기만 가능
  • 주인은 mappedBy 속성을 사용하지 않음
  • 주인이 아닌 쪽은 mappedBy 속성을 사용하여 주인 지정

@Entity   

테이블과 매핑할 엔티티

 

@Table 

엔티티와 매핑할 테이블 

 

@Id

데이터베이스 테이블의 기본 키와 객체의 필드를 매핑 ( 직접 할당)

 

@GeneratedValue 

기본키를 자동으로 생성해주는 애노테이션

@GeneratedValue(strategy = GenerationType.IDENTITY : 기본 키 생성을 데이터베이스에 위임

@GeneratedValue(strategy = GenerationType.SEQUENCE : 유일한 값을 순서대로 생성

 

@Column

 

@ManyToOne  @OneToMany

 

@JoinColumn

Entity의 연관관계에서 외래 키를 매핑하기 위해 사용.

name 속성 : 매핑할 외래 키의 이름 지정

+ Recent posts