54일차 특이사항
1. proxy 테이블에 대리결재자의 이름이 들어간다.
2. ${proxy}는 쓸 수 있는데... 왜 그 컬럼값들을 쓸 수 없을까?
${proxy}
${proxy.proxyMember}
${proxy.grantMember}
${proxy.grantTime}
${proxy.endGrant}
3. resultMap을 잘못 입력함... proxyRs로 해야되는데 loginRs로 했음.
<select id="proxy" resultMap="proxyRs" parameterType="map">
SELECT
PROXY_MEMBER
,GRANT_MEMBER
,GRANT_TIME
,END_GRANT
FROM JSH_APPROVAL_PROXY
</select>
팀장님의 지도
1. mapper, 쿼리짜는 부분
- 서브쿼리 사용
- 직급 관련 검색 쿼리부터 만들기
- 과장이 결재에 참여한 글. . . history에서 가져와야 한다는데?
- history에서 가져오려면 윈도우함수를 써서 파티션별로 1번, 2번 row_number를 가져오는 방법이 있다.
- 다시 만들어보자.
2. 상세보기 jsp
- read only로 주고 조건에 따라 풀어주는 것이 낫다.
- 수정되지 않는 상황이 더 많다. 그래서 미리 붙여놓고 조건을 주는 것이 효율적이다.
MEMBER의 계급이 BOSS인 경우, 결재 리스트에 보이는 값
- appr_seq를 가져오는 서브쿼리문 : appr_seq는 히스토리 테이블의 각 파티션 번호다. 1번 히스토리에는 여러개의 글이 들어간다. 1-1, 1-2, 1-3 이런식이다. 파티션 번호를 가져오는데 조건이 있다. row_num이 1과 2인 것만 가져온다. 이 말은 상위 1-1, 1-2번 히스토리 글을 가져온다는 것. appr_seq는 히스토리 테이블의 각 파티션 번호로 정의되지만 다르게 표현하면 결재글 번호(SEQ)와 같다. 글쓰기 버튼을 눌러서 글을 하나 쓰면 seq는 1로 등록되고 appr_seq도 1로 등록된다.
SELECT appr_seq
FROM (
SELECT
his_seq,
appr_seq,
his_app_date,
hist_apper,
hist_status,
ROW_NUMBER() OVER (PARTITION BY appr_seq ORDER BY his_seq desc) AS row_num
FROM JSH_APPROVAL_HISTORY
) Rank
WHERE row_num IN (1, 2);
- 이렇게 서브쿼리를 만든 이유는 뭘까? 글쓰기를 누르면 결재게시판 번호와 히스토리 번호가 등록된다. 그 다음에 누군가 임시저장, 결재를 하게 되면 히스토리 번호가 하나씩 늘어나면서 등록된다. 예를 들어 사원이 결재를 올리면 히스토리 게시판에 1번 '결재대기'로 표시된다.
- 과장이 결재글을 확인하고 '결재'를 누르면 2번 '결재중'으로 표시된다. 그 다음 부장이 결재를 누르면 3번 '결재완료'로 표시된다. 자 여기서 히스토리 테이블의 상위 1번과 2번글에는 과장의 아이디가 포함되어 있다.
- 과장 아이디가 결재 과정 상위 1, 2번에 포함되어 있어야 해당 게시물을 볼 수 있다. 이것을 위해 서브쿼리를 쓰는 것이다. 위 서브쿼리문을 실행하면 히스토리 테이블의 각 파티션의 상위 1번 2번 글이 선택된다.
- 여기에 조건을 추가한다. 세션에 저장된 로그인 아이디가 히스토리 결재자에 남아있으면!
- 정리하면 결재글 번호가 히스토리 테이블 1번, 2번 기록에 남아있으면서! 그 결재자 이름이 자신인 경우만! 해당 게시글을 조회할 수 있는 것이다.
- mapper 코드
<select id="apprList" resultMap="apprListRs" parameterType="map">
SELECT
SEQ
,WRITE_ID
,(select
MEM_NAME
from JSH_APPROVAL_MEMBER sam
where sam.mem_id = sal.write_id) WRITE_NAME
,APPR_SUBJECT
,APPR_STATUS
,decode
(APPR_STATUS,
'tmp','임시저장',
'wat','결재대기',
'ing','결재중',
'end','결재완료',
'ret','반려') APPR_STATUS_KOR
,APPR_REG_DATE
,APPR_DATE
,APPR_APPER
,(select MEM_NAME from JSH_APPROVAL_MEMBER sam where sam.mem_id = sal.APPR_APPER) APPER_NAME
FROM JSH_APPROVAL_LIST sal
WHERE 1=1
<if test="memInfo.memRank == 'CLERK' or memInfo.memRank == 'MANAGER'">
and WRITE_ID = #{memInfo.memId} <!-- 세션에서 가져온 아이디와 글쓴사람 아이디가 같은글만 -->
</if>
<if test="memInfo.memRank == 'BOSS'">
and (APPR_STATUS = 'wat' <!-- 결제대기 글 -->
OR (APPR_STATUS = 'end' AND APPR_APPER = #{memInfo.memId}) <!-- 자신이 썼고, 결재완료 글 -->
OR SEQ IN (
SELECT appr_seq
FROM (
SELECT
his_seq,
appr_seq,
his_app_date,
hist_apper,
hist_status,
ROW_NUMBER() OVER (PARTITION BY appr_seq ORDER BY his_seq DESC) AS row_num
FROM JSH_APPROVAL_HISTORY
) Rank
WHERE row_num IN (1, 2)
AND hist_apper = #{memInfo.memId}) <!-- 과장이 결재에 관여한 글 -->
OR (APPR_APPER = #{memInfo.memId} and APPR_STATUS = 'ret') <!-- 결재자가 자신이면서 반려당한 글 -->
OR (WRITE_ID = #{memInfo.memId} and APPR_STATUS = 'ret') <!-- 내가 썼는데 반려당한 글 -->
OR (WRITE_ID = #{memInfo.memId} and APPR_STATUS = 'tmp')) <!-- 내가 썼는데 임시저장인 글 -->
</if>
<if test="memInfo.memRank == 'KING'">
and (APPR_STATUS = 'ing' <!-- 결제중인 글 -->
OR APPR_STATUS = 'end' <!-- 결제완료 -->
OR (APPR_APPER = #{memInfo.memId} and APPR_STATUS = 'ret')<!-- 자신이 반려시킨 글 -->
OR (WRITE_ID = #{memInfo.memId} and APPR_STATUS = 'tmp')) <!-- 자신이 쓴 임시저장글 -->
</if>
느낀 점
서브쿼리문 만드는 거 쉽지 않네. 시간이 엄청 오래걸렸지만 그래도 해냈다.
팀장님 말로는 이런 것들이 머릿속으로 그려져야 프로젝트에 나가서 업무를 수행할 수 있다고 한다. 현재 내 상태는 그 정도가 아닌데 어떻하죠? 라고 물으니 그럼 쫓겨날 수 있다고 했다. 프로젝트에 나가게 되면 쫓겨나는 비율이 50%라고 한다. 이 분야는 실력 없고, 머리 나쁘면 일을 계속하기 힘든 분야 같다. 더 노력해야겠다. 안 되면 될 때까지! 지금까지 했던 것들을 반복해봐야겠다.
'일경험' 카테고리의 다른 글
[국민취업지원제도 일경험프로그램 56일차] 결재시스템 대리결재 완료 (1) | 2023.10.26 |
---|---|
[국민취업지원제도 일경험프로그램 55일차] 결재시스템 대리결재 controller (0) | 2023.10.25 |
[국민취업지원제도 일경험프로그램 53일차] 대리결재 기능 (0) | 2023.10.23 |
[국민취업지원제도 일경험프로그램 52일차] 결재시스템 대리결제 (제이쿼리 팝업창 제어 window.open(), window.close()) (0) | 2023.10.20 |
[국민취업지원제도 일경험프로그램 51일차] 결재시스템 마무리 ⑩ (1) | 2023.10.19 |