해당 프로젝트는 2023/01/25 ~ 2023/03/12 내에 진행되는
아카데미 내 수강생들끼리 팀을 나누어 진행한 모의 프로젝트입니다.
팀원은 5명이었으며, 프로젝트 리더를 맡았습니다.
이전 글 목록
1) 주어진 RFP를 바탕으로 주제 선정 - Spring Project(OTT 서비스)
2) ERD 설계 - Spring Project(OTT 서비스)
3) 회원 가입 기능 구현 - Spring Project (OTT 서비스)
4) 로그인, 로그아웃 기능 구현 - Spring Project (OTT 서비스)
5) 상세 페이지 및 회원 정보 수정 - Spring Project (OTT 서비스)
6) CRUD를 한번에 → 게시판 만들기(QNA게시판) - Spring Project(Mybatis) (OTT 서비스)
7) 게시판 페이징 처리 - Spring Project (OTT 서비스)
8) 카카오 지도 API 사용하기 - Spring Project (OTT 서비스)
9) (네아로) 네이버 로그인 API 활용 사이트 로그인 및 회원가입 - SPRING Project(OTT 서비스)
10) 카카오 로그인 API 사용하기(내 사이트 로그인 및 회원가입) - Spring Project(OTT Service)
11) 아임포트(포트원) API를 이용한 결제처리 - Spring Project(OTT Service)
12) 관리자 페이지 만들기(데이터 통계 및 chart.js, 유저 알고리즘) - Spring Project(OTT Service)
관리자 페이지에서 아래의 이미지는 VIDEO 데이터 입력 시의 화면이다.
개발자 입장이 아닌 보통의 관리자 입장으로 생각 해 보았을 때
영상이 새로 업로드 되면, 위의 이미지처럼 영상 정보 하나에 배우, 카테고리 및 장르 정보까지 다 넣을 것이라고 생각했다.
그렇게 되면 내가 설계했던 ACTOR, CATEGORY, GENRE 및 기타 연결 테이블들에 정보가 입력되지 않게 될 것이다.
때문에 영상 정보가 업로드될 때, 내가 설계한 대로 관련된 모든 테이블에 조회를 한 후, 해당 데이터가 없을 경우 추가시켜줘야 한다고 생각했다.
우선 등록하기를 클릭할 경우, form.submit 형태로 데이터가 전송되게 구성하였다.
Controller
//VIDEO CREATE - 02.19 장재호
@RequestMapping(value="/admin/videoCreate", method=RequestMethod.POST)
public ModelAndView videoCreate(ModelAndView mv, AdminETCDto dto) {
if(adminService.check(dto) != null) {
mv.addObject("error", "중복 된 제목이 존재합니다");
mv.setViewName("redirect:/admin/databases/video/create");
return mv;
}
//1. 카테고리
String category_name = dto.getCategory_name();
adminService.addCategory(category_name);
//2. 장르
String genre_name = dto.getGenre_name();
adminService.addGenre(genre_name);
//3. 배우
String[] actor = dto.getActor_name().split(",");
adminService.addActor(actor);
//4. 비디오
adminService.addVideo(dto);
//5. 비디오카테고리
adminService.addVideoCategory(dto);
//6. 비디오장르
adminService.addVideoGenre(dto);
//7. 비디오액터
List<String> list = new ArrayList<>();
for(String a : actor) {
list.add(a);
}
List<Integer> list2 = new ArrayList<>();
for(int i=0; i<list.size(); i++) {
list2.add(dto.getVideo_id());
}
dto.setActor(list);
dto.setVideoidx(list2);
adminService.addVideoActor(dto);
mv.setViewName("admin/admin_video");
return mv;
}
배우 테이블 접근 시, 이전에 View에서 구분자를 "," 로 설정하였기 때문에, Dao에서 처리할까 하다가 컨트롤러에서 미리 actor배열로 바꿔서 파라미터로 보냈다.
VIDEO_ACTOR의 경우, list에는 배우들을, list2에는 지금 입력하는 영화의 PK값을 담고 dto에 넣어주었다.
VIDEO의 PK를 굳이 컬렉션에 담은 이유는, Mybatis에서 반복문을 편하게 돌리기 위해서였다.
Dao
public void addCategory(String category_name) {
ss.insert("admin.addCategory", category_name);
}
public void addGenre(String genre_name) {
ss.insert("admin.addGenre", genre_name);
}
//배우는 여러명이기 때문에 걸러냇음
public void addActor(String[] actor) {
List<String> delArr = new ArrayList<>();
List<String> actorArr = new ArrayList<>();
delArr = ss.selectList("admin.actorCheck", actor);
for(String a : actor) actorArr.add(a);
for(int i=0; i<delArr.size(); i++) {
for(int j=0; j<actorArr.size(); j++) {
if(delArr.get(i).equals(actorArr.get(j))) {
actorArr.remove(j);
}
}
}
if(actorArr.size() > 0) {
ss.insert("admin.addActor", actorArr);
}
}
public void addVideo(AdminETCDto dto) {
ss.insert("admin.addVideo", dto);
}
public void addVideoCategory(AdminETCDto dto) {
ss.insert("admin.addVideoCategory", dto);
}
public void addVideoGenre(AdminETCDto dto) {
ss.insert("admin.addVideoGenre", dto);
}
public void addVideoActor(AdminETCDto dto) {
ss.insert("admin.addVideoActor", dto);
}
addActor메서드에서, delArr은 들고 들어온 actor 배열과 비교하여 ACTOR 테이블에 중복되어 있는 배우명을 의미한다.
actorArr에서 delArr을 빼 준 값이 기존 ACTOR 테이블에 존재하지 않는 새로운 배우명이 될 것이다.
SQL.xml
<insert id="addCategory">
insert into CATEGORY(CATEGORY_NAME)
select #{category_name} from dual where not exists(select CATEGORY_NAME from CATEGORY where CATEGORY_NAME=#{category_name})
</insert>
<insert id="addGenre">
insert into GENRE(`GENRE_NAME(KOR)`)
select #{genre_name} from dual where not exists(select `GENRE_NAME(KOR)` from GENRE where `GENRE_NAME(KOR)`=#{genre_name})
</insert>
<select id="actorCheck" resultType="String">
select `ACTOR_NAME(KOR)`
from ACTOR
where `ACTOR_NAME(KOR)` IN
<foreach collection="array" item="actor" index="index" open="(" close=")" separator=",">#{actor}</foreach>
</select>
<insert id="addActor">
insert into ACTOR(`ACTOR_NAME(KOR)`)
values
<foreach collection="list" item="actor" index="index" separator=",">(#{actor})</foreach>
</insert>
<delete id="delActor">
delete from ACTOR
where `ACTOR_NAME(KOR)`=#{actor_name}
</delete>
<insert id="addVideo">
insert into VIDEO(TITLE, SUMMARY, VIDEO_URL, IMAGE_URL, CREATE_COUNTRY, CREATE_YEAR, GRADE)
values (#{title}, #{summary}, #{video_url}, #{image_url}, #{create_country}, #{create_year}, #{grade})
</insert>
<insert id="addVideoCategory">
insert into VIDEO_CATEGORY(VIDEO_ID, CATEGORY_ID)
values ((select VIDEO_ID from VIDEO where TITLE=#{title}),
(select CATEGORY_ID from CATEGORY where CATEGORY_NAME=#{category_name}))
</insert>
<insert id="addVideoGenre">
insert into VIDEO_GENRE(VIDEO_ID, GENRE_ID)
values ((select VIDEO_ID from VIDEO where TITLE=#{title}),
(select GENRE_ID from GENRE where `GENRE_NAME(KOR)`=#{genre_name}))
</insert>
<insert id="addVideoActor">
insert into VIDEO_ACTOR(VIDEO_ID, ACTOR_ID)
values
<foreach collection="actor" item="actor" index="index" separator=",">
((select VIDEO_ID from VIDEO where TITLE=#{title}), (select ACTOR_ID from ACTOR where `ACTOR_NAME(KOR)`=#{actor}))
</foreach>
</insert>
쿼리문을 짜는데 크게 어려운 것이 없었기 때문에 딱히 부연설명은 하지 않겠다.
insert시 select from dual이라는 임의의 테이블을 생성하여 갖고 들어온 파라미터 값이 존재하지 않을 경우에만 insert했다.
원하는대로 관리자가 VIDEO 데이터를 입력 시, ACTOR, CATEGORY, GENRE에 중복되지 않는 값들만 추가되었으며
VIDEO테이블에 정보가 insert된 후, VIDEO의 정보에 맞는 VIDEO_ACTOR, VIDEO_CATEGORY, VIDEO_GENRE가 잘 들어왔다.
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!