안녕하세요 코북입니다. 지난번에 회원가입 화면을 Bootstrap을 이용해 구성해봤었습니다. 오늘은 그 화면에 맞춰 DB에 값을 넣어 회원가입을 할 수 있도록 만들겠습니다. 작업 진행 순서는 다음과 같습니다.
1. sql, jsp, vo 참고
2. mapper.xml
3. mapper
4. controller
5. jsp
1. sql, jsp, vo 참고
DB에 값을 넣을 쿼리를 작성하기에 앞서, 테이블 구조와 회원가입 화면 jsp, 미리 만들어 놓은 vo를 통해 회원가입 sql을 을 어떻게 작성할지 생각해봅니다.
■ sql
DB에 넣을 회원 테이블의 컬럼은 다음과 같습니다. join_date 컬럼을 default now()로 설정하면 가입이 완료됐을 때의 시간이 가입일자가 됩니다.
CREATE TABLE MEMBERS
(
MB_ID VARCHAR(30) NOT NULL COMMENT '회원 아이디',
MB_NAME VARCHAR(30) NULL COMMENT '회원 이름',
MB_PWD VARCHAR(30) NULL COMMENT '회원 비밀번호',
MB_BIRTHDATE DATE NULL COMMENT '생년월일',
JOIN_DATE DATETIME NULL DEFAULT NOW() COMMENT '가입일자',
ADMIN_YN VARCHAR(1) NULL COMMENT '관리자여부',
MB_SEX VARCHAR(30) NULL COMMENT '성별',
MB_EMAIL VARCHAR(30) NULL COMMENT '이메일',
MB_NICK VARCHAR(30) NULL COMMENT '닉네임',
CONSTRAINT PK_MEMBERS PRIMARY KEY (MB_ID)
);
ALTER TABLE MEMBERS COMMENT '회원정보';
■ JSP
작성한 테이블을 기반으로 제가 사용자에게 얻고자 하는 정보를 입력받을 수 있게 회원가입 jsp를 만들어줬습니다. 저는 ID, 닉네임, PW, 이름, 생년월일, 성별, 본인 확인 이메일을 입력받도록 설정했습니다. 관리자 여부는 사용자가 입력하지 않도록 합니다.
+
2021-11-02 추가
셀렉트 박스의 option태그에 selected disabled hidden 속성을 추가하여 셀렉트 박스 초기값을 설정해줬습니다. selected 속성은 페이지가 로드될 때 옵션 중에서 미리 선택되어지는 옵션을 명시합니다. disabled 속성이 명시된 옵션은 사용할 수 없고, 사용자가 클릭할 수도 없습니다. hidden 속성이 명시된 옵션은 사용자가 볼 수 없습니다.
<section class="bg-light">
<div class="container py-4">
<div class="row align-items-center justify-content-between">
<a class="navbar-brand h1 text-center" href="index.do">
<span class="text-dark h4">도시</span> <span class="text-primary h4">거북</span>
</a>
</div>
<form action="insertMembers.do" method="post">
<div class="form-group">
<label for="mb_id" class="form-label mt-4">아이디</label>
<input type="text" class="form-control" name="mb_id" id="mb_id">
<div><font id="id_feedback" size="2"></font></div>
</div>
<div class="form-group">
<label for="mb_nick" class="form-label mt-4">닉네임</label>
<input type="text" class="form-control" name="mb_nick">
</div>
<div class="form-group has-success">
<label class="form-label mt-4" for="inputValid">비밀번호</label>
<input type="password" class="form-control" id="mb_pwd1" name="mb_pwd">
<div class="valid-feedback"></div>
</div>
<div class="form-group has-danger">
<label class="form-label mt-4" for="inputInvalid">비밀번호 재확인</label>
<input type="password" class="form-control" id="mb_pwd2">
<div><font id="pwd_feedback" size="2"></font></div>
</div>
<div class="form-group">
<label for="exampleInputEmail1" class="form-label mt-4">이름</label>
<input type="text" class="form-control" name="mb_name">
</div>
<div class ="bir_wrap">
<label class="form-label mt-4">생년월일</label>
<div class="bir_yy">
<span class="ps_box">
<input type="text" class="form-control" id="yy" placeholder="년(4자)" maxlength="4" name="mb_yy">
</span>
</div>
<div class="bir_mm">
<span class="ps_box focus">
<select class="form-select" id="mm" name ="mb_mm">
<option>월</option>
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
</span>
</div>
<div class="bir_dd">
<span class="ps_box">
<input type ="text" class="form-control" id ="dd" placeholder="일" maxlength="2" name="mb_dd">
</span>
</div>
</div>
<div class="form-group">
<label for="mb_sex" class="form-label mt-4">성별</label>
<select class="form-select" name="mb_sex">
<option value="" selected disabled hidden>성별</option>
<option value="남자">남자</option>
<option value="여자">여자</option>
<option value="거북">거북</option>
</select>
</div>
<div class="form-group">
<label for="mb_email" class="form-label mt-4">본인 확인 이메일</label>
<input type="email" class="form-control" placeholder="선택입력" name="mb_email">
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary btn-lg" type="submit">가입하기</button>
</div>
</form>
</div>
</section>
■ VO
값에 접근할 수 있는 vo를 만들었습니다. 생년월일의 경우 회원가입 페이지에서 연, 월, 일을 따로 입력받도록 설정해뒀기 때문에 각각의 속성 값을 선언해뒀습니다. mb_yy, mb_mm, mb_dd 이런 식으로 각각 설정했습니다. 이 변수들은 후에 concat()을 통해 한 번에 묶어서 생년월일 컬럼(mb_birthdate)에 넣을 계획입니다.
package city.turtle.mapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MembersVO {
private String mb_id;
private String mb_name;
private String mb_pwd;
private String mb_birthdate;
private String join_date;
private String admin_yn;
private String mb_sex;
private String mb_email;
private String mb_nick;
private String mb_yy;
private String mb_mm;
private String mb_dd;
}
2. Mapper.xml
위에서 작성한 것들을 기반으로 쿼리를 작성해줍니다. mb_birthdate의 값은 concat()을 통해 mb_yy, mb_mm, mb_dd를 묶어서 넣어줍니다. vo에서 각각의 속성을 선언해줬기 때문에 사용자가 입력하는 값을 받아올 수 있습니다. 관리자 번호는 회원이 직접 입력하지 않고 입력이 이루어질 때 0(False)이 되도록 설정합니다. 후에 관리자 ID는 회원가입을 통해서 만들지 않고 직접 insert 명령어를 사용하여 만들고 이때 관리자 번호는 1(True)로 합니다.
<?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="city.turtle.mapper.MembersMapper">
<!-- 회원가입 -->
<insert id="insertMembers" parameterType="city.turtle.mapper.MembersVO">
insert into members(mb_id, mb_nick, mb_pwd, mb_name, mb_birthdate, mb_sex, mb_email, admin_yn)
values(#{mb_id},#{mb_nick},#{mb_pwd},#{mb_name},concat(#{mb_yy}, #{mb_mm}, #{mb_dd}),#{mb_sex},#{mb_email}, 0)
</insert>
<!-- 로그인 -->
<select id="signIn" resultType="city.turtle.mapper.MembersVO">
select * from members where mb_id = #{mb_id} and mb_pwd = #{mb_pwd}
</select>
</mapper>
3. Mapper
mapper Interface도 만들어줍니다. 사용자에게 입력받은 vo값을 xml파일에 넘겨줄 것이기 때문에 매개변수를 MembersVO vo로 설정했고, insert문의 결괏값을 따로 받지 않기 때문에 return type은 void로 설정했습니다.
package city.turtle.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MembersMapper {
// 회원가입
public void insertMembers(MembersVO vo);
// 로그인
public MembersVO signIn(MembersVO vo);
4. Controller
Controller에서는 회원가입 페이지를 보여주는 메소드, 회원가입을 처리하는 메소드, 회원가입 성공 페이지를 보여주는 메소드까지 해서 총 3개의 메소드를 만들었습니다. signUp()메소드와 signUpSuccess()메소드는 단순 페이지만을 보여주는 메소드기 때문에 따로 설명하지 않겠습니다. 중요한 것은 회원가입을 처리해주는 insertMembers()메소드입니다. 먼저 mapper.insertMembers(vo)를 통해 사용자가 입력한 vo값을 변수로 하여 위에서 만들었던 작업들을 처리합니다. 바인딩되어있는 mapper를 통해 Interface의 insertMembers()메소드를 실행합니다. 이 메소드로 인해 실행되는 쿼리가 insert 명령문이기 때문에 따로 결괏값은 받지 않습니다. 위 메소드가 실행된 후에 mapper.signIn(vo) 메소드를 실행합니다. 회원가입 후 회원가입 성공 페이지에 사용자의 이름과 ID를 보여주기 위해 로그인때 사용했던 메소드를 가져왔습니다. select한 값을 session에 담아서 signUp이라는 변수에 담아 로그인 성공 페이지로 redirect합니다.
@Controller
public class CityTurtleController {
@Autowired
private MembersMapper mapper;
// 회원가입 페이지
@RequestMapping("/signUp.do")
public String signUp() {
return "signUp";
}
// 회원가입
@RequestMapping("/insertMembers.do")
public String insertMembers(MembersVO vo, HttpServletRequest request) {
mapper.insertMembers(vo);
MembersVO signUp = mapper.signIn(vo);
HttpSession session = request.getSession();
session.setAttribute("signUp", signUp);
return "redirect:/signUpSuccess.do";
}
// 회원가입 성공 페이지
@RequestMapping("/signUpSuccess.do")
public String signUpSuccess() {
return "signUpSuccess";
}
5. jsp
jsp는 회원가입 페이지, 회원가입 성공 페이지 두 개로 구성했습니다. 로그인 페이지에서 회원가입 페이지로 넘어갈 때는 버튼 태그를 이용했습니다. 다음과 같이 onclick 이벤트를 설정했습니다. 회원가입 페이지는 위에서 다뤘기 때문에 따로 여기서 언급하지 않도록 하겠습니다.
<div class="col-lg-6 col-sm-12 text-lg-start text-center">
<button type="button" class="btn text-secondary" onclick="location.href='signUp.do'">회원가입</button>
</div>
■ 회원가입 성공 페이지
회원가입 성공 시 사용자에게 사용자의 이름과 ID를 보여주기 위해 JSTL+EL 라이브러리를 사용했습니다. 라이브러리이기 때문에 사용하기 전에 태그를 추가해줘야 합니다. 저는 core태그를 사용할 것이기 때문에 header에 추가해줬습니다. 사용자가 회원 가입한 ID를 다시 한번 확인할 수 있도록 하기 위해 Controller에서 가져온 session값을 이용했습니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="cpath" value ="${pageContext.request.contextPath}"/>
<section class="bg-light">
<div class="container py-4">
<div class="row align-items-center justify-content-between">
<a class="navbar-brand h1 text-center" href="index.do">
<span class="text-dark h4">도시</span> <span class="text-primary h4">거북</span>
</a>
</div>
<div>
<h1 class ="text-dark text-center">환영합니다!</h1>
<p class="text-center">
${signUp.mb_name}님의 회원가입을 축하드립니다
<br>새로운 아이디는 <strong>${signUp.mb_id}</strong>입니다.
</p>
</div>
<div class="d-grid gap-2">
<button type="button" class="btn btn-primary btn-lg" onclick="location.href='login.do'">시작하기</button>
</div>
</div>
</section>
구현 화면
사용기술
Spring MVC, JAVA, HTML, CSS, Bootstrap, JSP, JSTL, EL, mysql, myBatis
배운 점
회원가입 시 연, 월, 일을 따로 입력받도록 만들어서 sql 명령어를 만들 때 어떻게 처리해야 하는지 헤맸는데 concat() 함수를 통해 여러 문자열을 하나의 문자열로 합칠 수 있었습니다. 그리고 그에 맞춰 vo에 값을 추가해서 xml파일에서 명령어를 완성시킬 수 있었습니다. 회원가입 후 사용자에게 이름과 ID를 보여주고 싶었으나 구현을 어떻게 해야 할지 감이 오지 않았습니다. 우선은 보류해두고 로그인 기능을 구현했는데, 로그인할 때 사용했던 select명령어 메소드가 vo값을 session으로 가져와서 사용하는 것을 보고 로그인 때 사용했던 메소드를 가져와서 session값을 보내주면 될 것이라고 생각했습니다. JSTL과 EL은 수업시간에 다뤘으나 직접 사용해본 횟수가 적어 다루는 것이 미숙했는데, 회원가입 성공 페이지를 만들면서 그 개념과 사용법을 다시 배우고 다뤄볼 수 있었습니다.
본 글은 아래 링크의 내용을 참고하여 학습한 내용을 나름대로 정리한 글임을 밝힙니다.
https://daesuni.github.io/jstl/
https://velog.io/@ye050425/JSP-JSTL-%EC%A0%95%EB%A6%AC
https://extbrain.tistory.com/52
'Spring' 카테고리의 다른 글
[Spring/Ajax] Chart.js로 차트 만들기 (0) | 2021.10.30 |
---|---|
[Spring] 카카오 로그인 Open API (0) | 2021.10.26 |
[Spring] 네이버 로그인 Open API (4) | 2021.10.23 |
[Spring] session으로 로그인 유지하기 (0) | 2021.10.20 |
[Spring] 비동기 ID 중복 체크 기능 (0) | 2021.10.19 |