Mybatis
User정보와 Board 정보가 해당 페이지에 모두 필요하기 때문에 join 필요
Mybatis에서 join을 사용하는 방법은 sql과 작성과 동일하게 진행
sql문이 적혀있는 Mapper에 조인 결과를 받을 수 있도록 조정
조인하고 싶은 테이블의 내용도 가져와야 하며 collection 태그도 사용해야함
VO객체에 join의 결과를 받을 수 있는 변수를 생성
<?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="com.spring.myweb.user.mapper.IUserMapper">
<!-- VO클래스의 멤버변수가 컬렉션 타입일 경우에는 collection 태그를 이용 -->
<!-- collection 타입의 변수에 값을 매길 때는 어떤 객체로 포장해서 넣을 지를 새로운 resultMap으로 선언 -->
<resultMap type="UserVO" id="myPageInfo">
<!-- collection 객체를 가져올 때 컬럼명이 같아도 써주는 게 좋음 -->
<id property="userId" column="USERID" />
<result property="userName" column="USERNAME" />
<result property="userPhone1" column="USERPHONE1" />
<result property="userPhone2" column="USERPHONE2" />
<result property="userEmail1" column="USEREMAIL1" />
<result property="userEmail2" column="USEREMAIL2" />
<result property="addrBasic" column="ADDRBASIC" />
<result property="addrDetail" column="ADDRDETAIL" />
<result property="addrZipNum" column="ADDRZIPNUM" />
<collection property="userBoardList" resultMap="list" />
<!-- board의 값을 가져올 property 생성 -->
</resultMap>
<!-- collection에 들어갈 객체가 어떤 식으로 포장 될 지를 명시해주는 resultMap -->
<resultMap type="FreeBoardVO" id="list">
<id property="bno" column="bno" />
<result property="title" column="title" />
<result property="regDate" column="regdate" />
</resultMap>
<select id="getInfo" resultMap="myPageInfo">
<!-- myPageInfo를 참조 -->
SELECT userId,
userName,
userPhone1,
userPhone2,
userEmail,
userEmail2,
addrBasic,
addrDetail,
addrZipNum,
f.bno,
f.title,
f.regDate
from users u LEFT OUTER JOIN freeboard f ON u.userId = f.writer
WHERE
u.userId = #{userId}
ORDER BY f.bno DESC
</select>
<update id="updateUser">
UPDATE users SET
userPw = #{userPw},
userName = #{userName},
userPhone1 = #{userPhone1},
userPhone2 = #{userPhone2},
userEmail = #{userEmail},
userEmail2 = #{userEmail2},
addrBasic = #{addrBasic},
addrDetail = #{addrDetail},
addrZipNum = #{addrZipNum}
WHERE userId = #{userId}
</update>
</mapper>
Mapper에서 쿼리를 수행한 결과 혹은 Client로 부터 들어오는 데이터 흐름을 Controller에서 확인할 수 있음
session에 저장된 데이터를 가지고 와서 user정보를 확인할 수 있음
Client가 보내는 데이터를 받아서 DB에 업데이트 진행하는 것을 확인할 수 있음
// MyPage 이동 요청
@GetMapping("/userMypage")
public String moveMyPage(HttpSession session, Model model) {
// 세션 데이터에서 id를 뽑아야 유저 정보를 가져올 수 있으므로 session을 매개변수로 하고
// 값을 보내야하기 때문에 model도 매개변수로 지정
String id = ((UserVO) session.getAttribute("login")).getUserId();
// session을 가지고 와서 해당 session에서 id를 추출
UserVO user = service.getInfo(id);
System.out.println("join의 결과 : " + user);
model.addAttribute("userInfo", user);
return "/user/userMypage";
}
@PostMapping("/userUpdate")
public String update(UserVO user, RedirectAttributes ra) {
// 커맨드 객체를 활용하여 값을 받아옴
System.out.println("마이페이지에서 데이터 가져오는지 확인 " + user.toString());
service.updateUser(user);
ra.addFlashAttribute("msg", "수정이 완료되었습니다.");
return "redirect:/user/userMypage";
}
Controller에서 해당 페이지로 유저의 정보를 보내줌
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!-- el 태그르 사용하기 위해서 사용 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ include file="../include/header.jsp"%>
<section>
<!--Toggleable / Dynamic Tabs긁어옴-->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-10 col-lg-9 myInfo">
<div class="titlebox">
MEMBER INFO
</div>
<ul class="nav nav-tabs tabs-style">
<li class="active"><a data-toggle="tab" href="#info">내정보</a></li>
<li><a data-toggle="tab" href="#myBoard">내글</a></li>
<li><a data-toggle="tab" href="#menu2">Menu 2</a></li>
</ul>
<div class="tab-content">
<div id="info" class="tab-pane fade in active">
<p>*표시는 필수 입력 표시입니다</p>
<form action="<c:url value='/user/userUpdate'/>" method="post" id = "updateForm">
<table class="table">
<tbody class="m-control">
<tr>
<!-- name 속성은 커맨드 객체를 사용하기 위해 VO객체의 변수와 같도록 작성
value는 controller에서 보내준 값을 뿌려주는 속성 -->
<td class="m-title">*ID</td>
<td><input class="form-control input-sm" name = "userId" value ="${userInfo.userId }" id ="userId" readonly></td>
</tr>
<tr>
<td class="m-title">*이름</td>
<td><input class="form-control input-sm" name="userName" value="${userInfo.userName }" name="userName"></td>
</tr>
<tr>
<td class="m-title">*비밀번호</td>
<td><input type ="password" class="form-control input-sm" name = "userPw" id="userPw"></td>
</tr>
<tr>
<td class="m-title">비밀번호확인</td>
<td><input type ="password" class="form-control input-sm" id="userPwChk"></td>
</tr>
<tr>
<td class="m-title">E-mail</td>
<td>
<input class="form-control input-sm" name ="userEmail" value="${userInfo.userEmail }">@
<select class="form-control input-sm sel" name="userEmail2">
<option ${userInfo.userEmail2 == '@naver.com'? selected : '' }>@naver.com</option>
<option ${userInfo.userEmail2 == '@gmail.com'? selected : '' }>@gmail.com</option>
<option ${userInfo.userEmail2 == '@daum.com'? selected : '' }>@daum.net</option>
<!-- 사용자가 선택한 option을 작성하기 위해 삼항 연산자 사용 -->
</select>
</td>
</tr>
<tr>
<td class="m-title">휴대폰</td>
<td>
<select class="form-control input-sm sel" name="userPhone1">
<option ${userInfo.userPhone1 == '010' ? selected : '' }>010</option>
<option ${userInfo.userPhone1 == '011' ? selected : '' }>011</option>
<option ${userInfo.userPhone1 == '017' ? selected : '' }>017</option>
<option ${userInfo.userPhone1 == '018' ? selected : '' }>018</option>
<!-- controller에서 뿌린 값이 특정 값과 같다면 selected로 지정 -->
</select>
<input class="form-control input-sm" name="userPhone2" value="${userInfo.userPhone2 }">
</td>
</tr>
<tr>
<td class="m-title">우편번호</td>
<td><input class="form-control input-sm" id = "addrZipNum" name="addrZipNum" value = "${userInfo.addrZipNum }" readonly>
<button type="button" class="btn btn-primary" id="addBtn">주소찾기</button>
</td>
</tr>
<tr>
<td class="m-title">주소</td>
<td><input class="form-control input-sm add" name ="addrBasic" id = "addrBasic" value="${userInfo.addrBasic }" readonly></td>
</tr>
<tr>
<td class="m-title">상세주소</td>
<td><input class="form-control input-sm add" name="addrDetail" id="addrDetail" value="${userInfo.addrDetail }"></td>
</tr>
</tbody>
</table>
</form>
<div class="titlefoot">
<button class="btn" id = "updateBtn">수정</button>
</div>
</div>
<!-- 첫번째 토글 끝(내정보) -->
<!-- 두번쨔 토글 시작-->
<div id="myBoard" class="tab-pane fade">
<p>내 게시글 관리</p>
<form>
<table class="table">
<thead>
<tr>
<td>번호</td>
<td>제목</td>
<td>작성일</td>
</tr>
</thead>
<tbody>
<c:forEach var="board" items="${userInfo.userBoardList }">
<!-- VO객체에 boardlist에 대한 변수도 추가했으므로 해당 변수를 통해 반복문을 진행하여 화면에 데이터를 뿌림 -->
<tr>
<td>${board.bno }</td>
<td><a href="<c:url value='/freeBoard/freeDetail/${board.bno }' />">${board.title }</a></td>
<!-- 클릭을 하게 되면 상세페이지로 이동하도록 -->
<td><fmt:formatDate value="${board.regDate }" pattern="yyy년 MM월 DD일 HH:MM"/></td>
</tr>
</c:forEach>
</tbody>
</table>
</form>
</div>
<!-- 두번째 토글 끝 -->
<div id="menu2" class="tab-pane fade">
<h3>Menu 2</h3>
<p>Some content in menu 2.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<%@ include file="../include/footer.jsp"%>
JS를 활용하여 비밀번호 검증 수행
카카오 주소 api 활용
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
const msg = '${msg}';
if (msg !== ''){
alert(msg);
}
$(function() {
/*
비밀번호가 올바른 정규표현식대로 작성이 되었는지를 검증하셔서
만약 정규표현식에 맞지 않는 값이라면 alert()으로 검증 해 주세요.
나머지 입력창 빈칸 여부를 확인해서 필수 항목이 잘 작성 되었다면 submit
처리해 주세요.
주소찾기 버튼을 눌렀다면, 회원가입때 사용했던 다음 주소 api를 사용해서
주소찾기 기능을 제공해 주세요.
*/
// 비밀번호 검증
$('#updateBtn').click(function() {
const regex = /^[A-Za-z0-9+]{8,16}$/;
if ($('#userPw').val() === ''){
alert('비밀번호는 필수 입력입니다.');
}
else if(!regex.test($('#userPw').val())){
alert('비밀번호 형식과 맞지 않습니다.');
}
else if($('#userPw').val() !== $('#userPwChk').val()){
alert('비밀번호가 일치하지 않습니다. 확인란을 다시 작성해주세요.');
$('#userPwChk').focus();
return;
}
else if($('input[name=userName]').val() ===''){
alert('이름은 필수 입력입니다.');
$('input[name=userName]').focus();
}
else {
if (confirm('이대로 수정을 진행하시겠습니까? ')){
$('#updateForm').submit();
}
else {
return;
}
}
}); // 데이터 검증 검증 끝
// 다음 주소 api
$('#addBtn').click(function() {
new daum.Postcode({
oncomplete: function(data) {
console.log('클릭발생');
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 각 주소의 노출 규칙에 따라 주소를 조합한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var addr = '';
// 주소 변수
var extraAddr = '';
// 참고항목 변수
//사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
addr = data.roadAddress;
} else { // 사용자가 지번 주소를 선택했을 경우(J)
addr = data.jibunAddress;
}
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('addrZipNum').value = data.zonecode;
document.getElementById('addrBasic').value = addr;
// 커서를 상세주소 필드로 이동한다.
// 내가 지정한 곳에 값을 넣어줌
document.getElementById('addrDetail').focus();
}
}).open();
})
}); // end jQuery
</script>