변수명을 직관적이게 변경하고,
레거시코드를 정리하고자
며칠간 프로젝트를 처음부터 차근차근 살펴봤다.
다양한 변경사항이 있었지만, 대부분 easy 했다.
그러다.. !! 발견한 MyPage화면의 회원정보변경-저장의 Big legacy ~
레거시코드
1. 회원정보변경하고, 저장버튼을 누르면 !! Controller와 ServiceImpl 두곳에서 변경될 데이터들이 null인지 아닌지 확인한다. null이면 session에 저장되어있는 회원정보를 불러와서 TO에 세팅해준다. (일을 굳이 두번함)
2. 그리고 mapper로 가서 "사용자가 회원정보를 변경했든 안 했든" <모든 회원 데이터를 Update> 시킨다. 1번에서 null인지 아닌지 확인하고 Session에서 정보받아오는이유!!
3. 뿐만아니라 변경된 정보는 session에 재입력되지 않고 있었다.
고민
1. 먼저 과거의 내가.. 굳이 왜 Controller와 ServiceImpl 두곳에서 <데이터가 null인지 아닌지>를 확인하는 코드를 짰는지 파악해야했다. 이유가 있을지도 모르잖아..
근데 그때의 내가 왜그랬는지는 아직도 모른다. ㅎㅎ 아무리 봐도 필요없는 코드였다. 왜그랬을까? 똑같은 코드를 왜 굳이 두번씩이나 짰을까?
암튼 이유없는 찐레거시라 판단하고 업무로직과 상관있다고 생각했기 때문에 ServiceImple에만 남겨두기로했다.
2. 변경하지 않은 데이터까지 session에서 받아온 다음, 다~ Update시켜주는건 너무나도 비효율적이었다. My-Batis에서 제공하는 동적쿼리 if문을 사용해서 변경요청된 데이터만 변경하는것이 좋다고생각했다. 그런데 어떤 데이터가 변경될지 모르니 if문을 쓰기가 애매했다. 만약,, id변경 쿼리를 if문에 담아서 제일 위에 올려뒀는데 id는 변경하지 않고 pw만 변경했다면,, ',' 이 콤마가 에러를 일으키기 때문이다.
3. 아무튼 위의 문제들이 다 해결되고 나면 변경된 정보를 조회한 다음, session에 저장해야한다.
결과
1. <데이터가 null인지 아닌지> 확인하고, null일 경우 session에서 회원정보를 가져오는 작업은 전부 삭제하기로했다.
굳이 session에서 회원정보를 가져오는 이유는 mapper에서 쿼리문을 실행할 때 NullPointerException이 발생하기 때문이다.(쿼리문에서는 널익셉션이 아닌 다른 에러지만.. 일맥상통한 개념이니..)
2. 1번문제는 2번이 해결되면 자동으로 해결된다. null인경우, 즉 수정하지 않는 데이터가 있을 경우, if문 동적쿼리를 사용해 해당 데이터가 들어갈 set구문은 실행하지 않도록 하는것이다.
그러기 위해서 테이블에 컬럼을 새로 만들어주기로했다. status컬럼과 status_date컬럼!!!!
변경사항이 있는 경우 무조건 status컬럼과 status_date컬럼에 데이터를 변경시켜주고,
그 다음 if문 조사를 하면, 순서가 어떠하든 에러는 발생하지 않고 update가 된다.
하루종일 이 문제를 해결하고싶었는데, 못하고 내내 삽질만 하다가 ,, 집에가서 누으니까 해결책이 떠올랐다. 이것 저것 해보다가 에러만 잔뜩 만들어내서 '나 뭐하니..' 하며 해결 안 될까봐 걱정하고 있었는데ㅠㅠ 역시 브레인스토밍이 중요해
3. session에 변경된 새로운 데이터를 저장해두기 위해서, 회원조회할 때 사용하는 retrieveMemberInfo(MemberTO to)메서드에 변경된 회원의 id를 담아 보내고, 조회된 회원의 변경된 정보를 돌려받는다.
그다음 login할 때 사용하는 sessionController의 loginSession(session, memberTO) 메서드에 회원정보와 session을 보내주기로했다. session메서드의 이름이 login이라 마음에 걸린다. 바꾸자!!!!!!으아!!!!!!!!
4. 추가로
변경요청이 왔는데, 변경할 데이터가 없다면 ServiceImpl에서 조사한 다음 errorMsg를 바로 return해주었다.
여기서 중요한것! TO에 데이터가 있는지 없는지 if문에서 검사할 때는 TO.getxx() == "" || TO.getxx()==null 얘네들은 통하지 않는다.
TO.getxx().isEmpty() 를 사용해야한다.
변경된 MyPageController
@PutMapping("/changeMemberInfo")
HashMap<String, String> changeMemberInfo(HttpServletRequest request, @RequestParam("changeMemberInfo") String changeMemberInfo){
HttpSession session = request.getSession();
MemberTO memberTO = gson.fromJson(changeMemberInfo, MemberTO.class);
memberTO.setSessionId((String)session.getAttribute("memberId"));
//회원 ID가 변경될 경우도 있기 때문에, session에 저장된 회원Id를 UPDATE쿼리의 조건으로 둔다.
HashMap<String, String> map=myPageService.changeMemberInfo(memberTO,session);
return map;
}
변경이전 MyPageController
@PutMapping("/changeMemberInfo")
HashMap<String, Integer> changeMemberInfo(HttpServletRequest request, @RequestParam("changeMemberInfo") String changeMemberInfo){
HttpSession session = request.getSession();
String sessionMemberId=(String)session.getAttribute("memberId");
String sessionName=(String)session.getAttribute("memberName");
MemberTO memberTO = gson.fromJson(changeMemberInfo, MemberTO.class);
HashMap<String, Integer> map = new HashMap<>();
memberTO.setSessionId(sessionMemberId);
if(memberTO.getId().isEmpty()|| memberTO.getId()==null || memberTO.getId().trim()=="") {
memberTO.setId(sessionMemberId);
}
if(memberTO.getName().isEmpty()|| memberTO.getName()==null || memberTO.getName().trim()==""){
memberTO.setName(sessionName);
}
if(memberTO.getPassword().isEmpty()||memberTO.getPassword()==null){
memberTO.setPassword((String)session.getAttribute("password"));
}
if(memberTO.getBirth()==0){
memberTO.setBirth((int)session.getAttribute("birthday"));
}
map=myPageService.changeMemberInfo(memberTO,session);
session.setAttribute("memberName",memberTO.getName());
session.setAttribute("memberId",memberTO.getId());
session.setAttribute("memberBirth",memberTO.getBirth());
return map;
}
변경된 MyPageServiceImpl
public HashMap<String,String> changeMemberInfo(MemberTO memberTO,HttpSession session){
HashMap<String, String> map = new HashMap<>();
map.put("errorCd", "N");
map.put("errorMsg", "성공");
//변경저장요청은 들어왔지만, 변경사항된 회원정보가 없을경우
if(memberTO.getId().isEmpty()&&memberTO.getBirth()==0&&memberTO.getPassword().isEmpty()&&memberTO.getName().isEmpty()) {
map.put("errorCd", "Y");
map.put("errorMsg", "변경할 데이터가 없습니다.");
return map;
}
try {
//회원 정보변경
myPageMapper.updateMemberInfo(memberTO);
//회원ID가 변경되지 않은 경우 session에 있는 회원 ID를 가져온다.
if(memberTO.getId().isEmpty() || memberTO.getId()==""){
memberTO.setId((String) session.getAttribute("memberId"));
}
memberTO.setId(memberTO.getId());
//회원 ID를담은 TO를 회원정보조회 메서드로 보내 변경된 회원정보를 가져온다.
memberTO=retrieveMemberInfo(memberTO);
//변경된 회원정보를 session에 담아준다.
SessionController.loginSession(session, memberTO);
}catch (Exception e) {
map.put("errorCd", "Y");
map.put("errorMsg", "정보변경 중 데이터 에러발생");
e.printStackTrace();
}
return map;
}
변경이전 ServiceImpl
public HashMap<String,Integer> changeMemberInfo(MemberTO memberTO, HttpSession session){
HashMap<String, Integer> map = new HashMap<>();
String sessionId=(String)session.getAttribute("memberId");
memberTO.setSessionId(sessionId);
if(memberTO.getId()==null) {
memberTO.setId(sessionId);
}
if(memberTO.getName()==null){
memberTO.setName((String)session.getAttribute("memberName"));
}
if(memberTO.getPassword()==null){
memberTO.setPassword((String)session.getAttribute("memberPassword"));
}
if(memberTO.getBirth()==0){
memberTO.setBirth(0);
}
myPageMapper.updateMemberInfo(memberTO);
map.put("errorCode", 1);
return map;
}
변경된 Mapper 쿼리
<update id="updateMemberInfo" parameterType="com.helper.study.stuhel.member.to.MemberTO">
UPDATE MEMBER_SECURITY
SET
UP_STATUS = 'U'
,UP_DATE = SYSDATE
<if test="!id.isEmpty()" >,ID = #{id}</if>
<if test="!name.isEmpty()" >,NAME = #{name}</if>
<if test="!password.isEmpty()" >,PASSWORD = #{password}</if>
<if test="birth>0" >,BIRTH = #{birth}</if>
WHERE ID = #{sessionId}
</update>
변경이전 Mapper 쿼리
<update id="updateMemberInfo" parameterType="com.helper.study.stuhel.member.to.MemberTO">
UPDATE MEMBER_SECURITY
SET
ID = #{id}
,NAME = #{name}
,PASSWORD = #{password}
,BIRTH = #{birth}
WHERE ID = #{sessionId}
</update>