💻 뚝딱뚝딱/팀내도서대여시스템(OBRS)

[개발일지#002] 회원 가입 / 회원조회(단건) / 회원정보수정 구현

뚜루리 2024. 4. 1. 12:58
728x90
320x100
다른 사이드프로젝트인 '북북클럽'에서도 사용하는 거의 동일한 기능이라 이번에는 도메인 단위로 묶어서 개발일지를 써보기로 했다. 그래서, 이번 개발일지에는 '회원' 도메인에 관련된 기능을 구현할 예정. 

 

[개발목표]

  1. 회원 목록 조회 (#001에서 이미 구현했음)
  2. 회원 단건 조회 
  3. 회원 정보 수정
  4. 회원가입

 

 

UpdateForm.java

package seulgi.bookRentalSystem.domain.member;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.stereotype.Service;

@Setter @Getter
@RequiredArgsConstructor
public class UpdateForm {

    private String memberName;
    private String password;
}
  • 회원 수정용 객체를 따로 만들었다. 회원은 한번 가입하게 되면 멤버이름과 패스워드만 수정가능하기 때문에 두개의 엔티티만 담아주었다. 
  • 회원 수정시에 쓰게될 객체. 

 

 

MemberMapper.java

package seulgi.bookRentalSystem.domain.member;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Optional;

@Mapper
public interface MemberMapper {
	
    //회원 목록 조회
    List<Member> allMemberList();
	
    //로그인 기능을 위한 회원 조회
    Optional<Member> findByLoginId(@Param("loginId") String loginId);
	
    //회원 가입을 위한 조회
    void join(@Param("member") Member member);
	
    //회원Id을 통해 회원 객체 조회
    Member findById(@Param("memberId") String memberId);
	
    //회원 정보 수정 기능
    void update(@Param("memberId") String memberId, @Param("member") Member member);

}

 

 

MemberService.java

package seulgi.bookRentalSystem.domain.member;

import org.apache.ibatis.annotations.Param;
import seulgi.bookRentalSystem.domain.book.Book;
import seulgi.bookRentalSystem.domain.book.BookRental;

import java.util.List;

public interface MemberService {
	
    //회원 목록 조회
    List<Member> allMemberList();
    
	// 회원 가입 기능
    void join(Member member);
	
    //회원Id로 회원 객제 조회
    Member findById(String id);
	
    //회원 정보 수정
    void update(String memberId, UpdateForm updateForm);

}

 

 

MemberServiceImpl.java

package seulgi.bookRentalSystem.domain.member;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import seulgi.bookRentalSystem.domain.book.Book;
import seulgi.bookRentalSystem.domain.book.BookRental;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService{

    private final MemberMapper memberMapper;
	
    //회원 목록 조회
    public List<Member> allMemberList() {
        return memberMapper.allMemberList();
    }
	
    //회원 가입
    @Override
    public void join(Member member) {
        memberMapper.join(member);
    }
	
    //회원 아이디로 회원 객체 조회
    @Override
    public Member findById(String id) {
        return memberMapper.findById(id);
    }
	
    //회원 정보 수정
    @Override
    public void update(String memberId, UpdateForm updateParam) {
        Member findMember = findById(memberId);
        findMember.setMemberName(updateParam.getMemberName());
        findMember.setPassword(updateParam.getPassword());
        memberMapper.update(memberId, findMember);
    }


}
  • 회원수정 서비스에서 아까만든 회원수정용 객체를 사용하였다.

 

 

MemberMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="seulgi.bookRentalSystem.domain.member.MemberMapper">
	
    <!-- 로그인용 회원 객체 조회 -->
    <select id="findByLoginId" parameterType="java.lang.String" resultType="seulgi.bookRentalSystem.domain.member.Member">
        SELECT
               MEMBER_ID AS mermberId
             , MEMBER_NAME AS memberName
             , PASSWORD
             , JOIN_DATE AS joinDate
            FROM MEMBER_TB WHERE MEMBER_ID = #{loginId}
    </select>
	
    <!-- 회원 단건 조회  -->
    <select id="findById" parameterType="java.lang.String"
                         resultType="seulgi.bookRentalSystem.domain.member.Member">
        SELECT
               MEMBER_ID AS memberId
             , MEMBER_NAME AS memberName
             , PASSWORD
             , JOIN_DATE AS joinDate
        FROM MEMBER_TB
        WHERE MEMBER_ID = #{memberId}
    </select>
    
	<!--회원 목록 조회 -->
    <select id="allMemberList" resultType="seulgi.bookRentalSystem.domain.member.Member">
        SELECT
              MEMBER_ID AS memberId
            , MEMBER_NAME AS memberName
            , PASSWORD
            , JOIN_DATE AS joinDate
        FROM MEMBER_TB;
    </select>
	
    <!-- 회원 가입 -->
    <insert id="join" parameterType="seulgi.bookRentalSystem.domain.member.Member">
        INSERT INTO MEMBER_TB
                ( MEMBER_ID
                , MEMBER_NAME
                , PASSWORD
                , JOIN_DATE
        ) VALUES (
                 #{member.memberId}
                ,#{member.memberName}
                ,#{member.password}
                ,now()
       )
    </insert>
	
    <!-- 회원 정보 수정 -->
    <update id="update" parameterType="java.util.Map">
        UPDATE MEMBER_TB
        SET   MEMBER_NAME = #{member.memberName}
            , PASSWORD = #{member.password}
        WHERE MEMBER_ID = #{memberId}
    </update>

</mapper>
  • Mybatis를 본격적으로 쓰는 것은 처음이라 현재 시간을 입력하기 위해 SYSDATE를 썼다가 에러가나서 보니 mybatis는 now()를 쓰더라. 아맞다..그랬지! 급하게 수정함. 
  • 전자정부프레임워크를 사용할 때는 egovMap을 쓰면 resultMap을 자동으로 카멜 형태로 변환해주기 때문에 그 편한 기능을 쓰다가 없으니 너무 불편하다. 일단 컬럼이 많지 않아 하나하나 alias를 적어서 변환해주고 있지만 찾아보니 변환하는 방법이 없는건 아닌거 같아 추후 수정을 해야 할 것 같다. 

 

MemberController.java

package seulgi.bookRentalSystem.web.member;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import seulgi.bookRentalSystem.domain.member.Member;
import seulgi.bookRentalSystem.domain.member.MemberServiceImpl;
import seulgi.bookRentalSystem.domain.member.UpdateForm;

import java.util.List;

@Controller
@RequiredArgsConstructor
@RequestMapping("/member")
public class MemberController {

    private final MemberServiceImpl memberService;

    /**
     * 회원가입 폼
     * @param model
     * @return
     */
    @GetMapping("/join")
    public String joinForm(Model model){
        model.addAttribute("member", new Member());
        return "member/joinForm";
    }

    /**
     * 회원가입
     * @param member
     * @param redirectAttributes
     * @return
     */
    @PostMapping("/join")
    public String join(@ModelAttribute Member member, RedirectAttributes redirectAttributes){
       memberService.join(member);
       redirectAttributes.addAttribute("memberId", member.getMemberId());
       redirectAttributes.addAttribute("status", true);
       return "redirect:/member/{memberId}";
    }

    /**
     * 회원 단건 조회
     * @param memberId
     * @param model
     * @return
     */
    @GetMapping("/{memberId}")
    public String member(@PathVariable String memberId, Model model){
        Member member = memberService.findById(memberId);
        model.addAttribute("member", member);
        return "member/member";
    }

    /**
     * 회원 목록 조회
     * @param model
     * @return
     */
    @GetMapping
    public String allMemberList(Model model){
        List<Member> members = memberService.allMemberList();
        model.addAttribute("members", members);
        return "member/allMemberList";
    }

    /**
     * 회원 정보 수정 폼
     * @param memberId
     * @param model
     * @return
     */
    @GetMapping("/{memberId}/edit")
    public String editForm(@PathVariable String memberId, Model model){
        Member member = memberService.findById(memberId);
        model.addAttribute("member", member);
        return "member/editForm";
    }
    /**
     * 회원 정보 수정
     * @param memberId
     * @param form
     * @return
     */
    @PostMapping("/{memberId}/edit")
    public String edit(@PathVariable String memberId, @ModelAttribute("member") UpdateForm form) {
        memberService.update(memberId, form);
        return "redirect:/member/{memberId}";
    }
}

 


[구현화면]

전에 했던 사이드프로젝트의 디쟌 그대로 가져온건 안비밀~ㅎ

728x90
320x100